1時間以内に解けなければプログラマ失格となってしまう5つの問題が話題に
を解いてみた。
一応1時間以内にできたけど、あまり綺麗ではない。
問題1〜3は簡単なので省略。
問題4
正の整数のリストを与えられたとき、数を並び替えて可能な最大数を返す関数を記述せよ。 例えば、[50, 2, 1, 9]が与えられた時、95021が答えとなる
#!/usr/bin/env ruby def max_combination(ar) ar.sort { |x, y| "#{y}#{x}" <=> "#{x}#{y}" } end ar = [50, 2, 1, 9] max_combination(ar).join # => "95021"
一瞬戸惑ったけど、配列の要素を文字列比較すればok。
問題5
1,2,…,9の数をこの順序で、”+”、”-“、またはななにもせず結果が100となる あらゆる組合せを出力するプログラムを記述せよ。 例えば、1 + 2 + 34 – 5 + 67 – 8 + 9 = 100となる
#!/usr/bin/env ruby def detect_total(ar_size, total) ope = ['+', '-', ''] comb = (1...ar_size).inject([]) do |res, i| res << [i].product(ope).map(&:join) end first = comb[0] other = comb[1..-1] first.product(*other) .map { |elm| "#{elm.join}#{ar_size}" } .select { |formula| eval(formula) == total } end
pp detect_total(9, 100) ["1+2+3-4+5+6+78+9", "1+2+34-5+67-8+9", "1+23-4+5+6+78-9", "1+23-4+56+7+8+9", "12+3+4+5-6-7+89", "12+3-4+5+67+8+9", "12-3-4+5-6+7+89", "123+4-5+67-89", "123+45-67+8-9", "123-4-5-6-7+8-9", "123-45-67+89"]
しばらく考えても妙案が浮かばず。
総当たりでやってみました。
まずは、1〜8までの数値それぞれに演算子を付けた配列を用意(comb)。
=> [["1+", "1-", "1"], ["2+", "2-", "2"], ["3+", "3-", "3"], ["4+", "4-", "4"], ["5+", "5-", "5"], ["6+", "6-", "6"], ["7+", "7-", "7"], ["8+", "8-", "8"]]
あとは、これの総当たりを作成してevalで評価。
一見よろしくないですが、product って便利だなと再認識。