Simple or trump(CodeEval)

簡易版大富豪の実装。
Scoreが80%ぐらいで、何かの考慮漏れがありそうなんだけど、よくわからないので一旦諦め。

CHALLENGE DESCRIPTION:

First playing cards were invented in Eastern Asia and then spread all over the world taking different forms and appearance. In India, playing cards were round, and they were called Ganjifa. In medieval Japan, there was a popular Uta-garuta game, in which shell mussels were used instead of playing cards.
In our game, we use playing cards that are more familiar nowadays. The rules are also simple: an ace beats a deuce (2) unless it is a trump deuce.

INPUT SAMPLE:

The first argument is a path to a file. Each line includes a test case which contains two playing cards and a trump suit. Cards and a trump suite are separated by a pipeline (|). The card deck includes thirteen ranks (from a deuce to an ace) of each of the four suits: clubs (♣), diamonds (♦), hearts (♥), and spades (♠). There are no Jokers.

AD 2H | H
KD KH | C
JH 10S | C

OUTPUT SAMPLE:

Your task is to print a card that wins. If there is no trump card, then the higher card wins. If the cards are equal, then print both cards.

2H
KD KH
JH

CONSTRAINTS:

  1. The card deck includes ranks from a deuce (2) to an ace, no Jokers.
  2. If the cards are equal, then print both cards.
  3. The number of test cases is 40.

My Code

#!/usr/bin/env ruby -w
class Card
  TRUMP_DUCE_RANK = 15
  SIGN_CARD_RANK = {
    "J" => 11,
    "Q" => 12,
    "K" => 13,
    "A" => 14
  }
  attr_reader :rank

  def initialize(card, trump)
    @card = card
    @trump = trump
    @rank = card_to_rank(card, trump)
  end

  def to_s
    @card
  end

  private
    def card_to_rank(card, trump)
      number = card[0...-1]
      rank = SIGN_CARD_RANK[number] || number.to_i
      rank = TRUMP_DUCE_RANK if rank == 2 && card[-1] == trump
      rank
    end
end

def game(cards, trump)
  x, y = cards.map { |card| Card.new(card, trump) }
  if x.rank > y.rank
    x.to_s
  elsif x.rank == y.rank
    "#{x} #{y}"
  else
    y.to_s
  end
end

ARGF.each_line do |line|
  cards_str, trump = line.chomp.split(" | ")
  cards = cards_str.split
  puts game(cards, trump)
end

Not so clever(CodeEval)

Bubble Sort のような(よりも効率の悪い)ソートアルゴリズムを実装する問題。

CHALLENGE DESCRIPTION:

Imagine that you have to arrange items in a certain order: pencils from black to white in a color palette, photographs by the date taken, banknotes from the highest to the lowest, etc. To do this, you definitely don’t need to use the Stupid sort algorithm.
 
After each action, you need to come back to the beginning and start all over again. Not so clever, is it? But, you need to know about this algorithm, that’s why it is used in this challenge.

INPUT SAMPLE:

The first argument is a path to a file. Each line includes a test case which contains numbers that you need to sort using the Stupid sort algorithm. There is also a number of iterations for an algorithm to carry out. The numbers themselves and the number of iterations are separated by a pipeline ‘|’.

4 3 2 1 | 1
5 4 3 2 1 | 2

OUTPUT SAMPLE:

Print sorted numbers after they pass the required number of iterations. One iteration of this sort is a pass to the moment of making changes. Once changing the order of the digits, passing starts from the very beginning. Hence, this is another iteration.

3 4 2 1
4 3 5 2 1

CONSTRAINTS:

  1. The number of iterations can be from 1 to 8.
  2. One iteration of this sort is a pass to the moment of making changes.
  3. The number of test cases is 40.

My Code

#!/usr/bin/env ruby -w

def stupid_sort(numbers, iteration_number)
  iteration_number.times { sort_once!(numbers) }
  numbers
end

def sort_once!(numbers)
  numbers.each_with_index do |n, i|
    x = numbers[i]
    y = numbers[i + 1]
    if x > y
      numbers[i] = y
      numbers[i + 1] = x
      return numbers
    end
  end
end

ARGF.each_line do |line|
  _numbers, _iteration_number = line.chomp.split(" | ")
  numbers = _numbers.split.map(&:to_i)
  iteration_number = _iteration_number.to_i
  puts stupid_sort(numbers, iteration_number).join(" ")
end

Football(CodeEval)

「チーム毎のメンバーが所属する国のリスト」を「国別のチーム一覧」に変換する問題。
日本語にすると一見複雑で、途中で何やってるかわからなくなる。
nested な配列生成が少し汚い。injectにしてもあまり変わらない。
メソッド分割をすれば良いのかもしれないが、名前が複雑になりそうなので、とりあえず最初に書いたまま。
 

CHALLENGE DESCRIPTION:

People around the world watch football matches and root for different football teams. Some people are fans of Real Madrid, some like Barcelona, some pull for Atletico Madrid, while others do not miss a single match with FC Bayern Munich. The teams would like to know people in which countries cheer for them. So, let’s help them!

INPUT SAMPLE:

The first argument is a path to a file. Each row includes a test case with lists of countries. Lists are separated by pipelines ‘|’. Each list includes football teams that people in these countries root for.

1 2 3 4 | 3 1 | 4 1
19 11 | 19 21 23 | 31 39 29

OUTPUT SAMPLE:

For each football team, print a list of countries where people root for them. Separate each team by a semicolon ‘;’ and a space. All output should be sorted.

1:1,2,3; 2:1; 3:1,2; 4:1,3;
11:1; 19:1,2; 21:2; 23:2; 29:3; 31:3; 39:3;

CONSTRAINTS:

  1. The number of countries lists can be from 3 to 20.
  2. Each list contains a different number of football teams: from 1 to 7.
  3. The number of test cases is 40.

My Code

#!/usr/bin/env ruby -w

def teams_by_country(teams)
  countries = teams.flatten.sort.uniq
  results = []
  countries.each do |country|
    result = []
    teams.each_with_index do |team, i|
      result << "#{i + 1}" if team.include?(country)
    end
    results << "#{country}:#{result.join(",")};"
  end
  results.join(" ")
end

ARGF.each_line do |line|
  teams = line.chomp.split(" | ").map { |t| t.split.map(&:to_i) }
  puts teams_by_country(teams)
end