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

Real Fake(CodeEval)

Credit Card のcheck tool。
実際のものではなく、架空のもの。グループごとに1, 3 番目の数字を倍にして、足し上げた結果10で割り切れれば本物と判定する。

CHALLENGE DESCRIPTION:

The police caught a swindler with a big pile of credit cards. Some of them are stolen and some are fake. It would take too much time to determine which ones are real and which are fake, so you need to write a program to check credit cards.
To determine which credit cards are real, double every third number starting from the first one, add them together, and then add them to those figures that were not doubled. If the total sum of all numbers is divisible by 10 without remainder, then this credit card is real.

INPUT SAMPLE:

9999 9999 9999 9999
9999 9999 9999 9993

OUTPUT SAMPLE:

Fake
Real

CONSTRAINTS:

  1. The credit card number is 16 digits in length.
  2. The number of test cases is 40.

My Code

#!/usr/bin/env ruby -w

def real_card?(card_number)
  total = card_number.split.inject(0) do |sum, grouped_number|
    numbers = grouped_number.split("").map(&:to_i)
    sum += numbers.inject(&:+) + numbers[0] + numbers[2]
  end
  total % 10 == 0
end

ARGF.each_line do |line|
  puts real_card?(line.chomp) ? "Real" : "Fake"
end