blog.jnito.comやってみました。
カレンダー作成問題
ここで似たようなことをやっているので省略。(ただし、Date クラスは使っていません。)
カラオケマシン問題
class KaraokeMachine Key = %w(C C# D D# E F F# G G# A A# B) def initialize(melody) @scaned = melody.scan(/C#|D#|F#|G#|A#|C|D|E|F|G|A|B| |\|/) end def transpose(n) @scaned.map do |k| idx = Key.index(k) idx ? Key[(idx + n) % Key.size] : k end.join end end
ビンゴカード作成問題
stock = 5.times.map {|i| (i * 15 + 1..(i + 1) * 15).to_a.shuffle} table = 5.times.map do 5.times.map {|i| stock[i].shift} end table[2][2] = "" table = ([%w(B I N G O)] + table).map do |row| row.map {|x| "%2s" % x}.join(" | ") end puts table
出力例。
B | I | N | G | O 15 | 28 | 32 | 58 | 68 8 | 27 | 35 | 49 | 73 12 | 18 | | 47 | 64 1 | 21 | 42 | 56 | 62 3 | 25 | 38 | 52 | 75
ボーナスドリンク問題
class BonusDrink def self.total_count_for(amount) drink = ->(left, drinked) { return drinked if left.zero? i = left / 3 d = i.zero? ? left : i * 3 #今回飲む本数 drink.(left - d + i, drinked + d) } drink.(amount, 0) end end puts BonusDrink.total_count_for(100) #=>149
再帰で解いています。
残りが3本より少なければそのまま飲みます。3本以上なら、3の倍数本だけ飲めるだけ飲んで、(いま飲んだ本数÷3)本だけ追加します。残り0本ならば終了します。
電話帳作成問題
class NameIndex ADan = %w(ア カ サ タ ナ ハ マ ヤ ラ ワ ン) def self.create_index(names) table = Hash.new([]) names.each do |name| ADan.each_cons(2) do |be, ed| table[be] += [name] if (be...ed).include?(name[0]) end end table.each_value {|v| v.sort!} table.map {|k, v| [k, v]}.sort end end NameIndex.create_index(['キシモト', 'イトウ', 'ババ', 'カネダ', 'ワダ', 'ハマダ'])
行単位、列単位で合計値を求めるプログラム
module SumMatix extend self def output(input) result = calc(input) length = result.last.map {|x| x.to_s.size} result.map do |row| row.map.with_index {|x, i| x.to_s.rjust(length[i])}.join("| ") end end def calc(input) tmp = input.map {|row| row + [row.sum]} last = tmp.first.each_index.map do |i| tmp.map {|row| row[i]}.sum end tmp + [last] end end
実行例。
input = [ [ 9, 85, 92, 20], [68, 25, 80, 55], [43, 96, 71, 73], [43, 19, 20, 87], [95, 66, 73, 62] ] puts SumMatix.output(input)
9| 85| 92| 20| 206 68| 25| 80| 55| 228 43| 96| 71| 73| 283 43| 19| 20| 87| 169 95| 66| 73| 62| 296 258| 291| 336| 297| 1182
ガラケー文字入力問題
module KeitaiMessage Allocation = [%W(. , ! ? #{" "}), %W(a b c), %W(d e f), %W(g h i), %W(j k l), %W(m n o), %W(p q r s), %W(t u v), %W(w x y z)] def self.key_in(input) result = "" input.chars.chunk_while {|i, j| i == j}.reject {|x| x[0] == "0"}.each do |line| group = Allocation[line.first.to_i - 1] result += group[(line.size - 1) % group.size] end result = result[0...-1] if input[-1] != "0" result end end puts KeitaiMessage.key_in("440330555055506660") #=>hello
正しく問題のとおりにするなら、入力が例えば "5" の場合、何も出力されてはいけませんが、ここではじつは空文字列が出力されます。ただ元の仕様は美しくないので、まあいいかということにしてしまいました。正しく修正するなら、メソッドの外ですることになります。
Enumerable#chunk_while は見たことがないという人もいるかもしれませんが、意外と有用なメソッドだと思います。