テンパズル - Wikipedia
1桁の4つの数と四則演算で、10 を作るコードを Ruby で書いてみました。括弧は使ってもよいことにします。
実行例。
$ ruby make_ten.rb [2, 7, 3, 9] で 10 を作る (2 + 3) * (9 - 7) (7 + 9) - (2 * 3) 9 + (7 - (2 * 3)) 9 - ((2 * 3) - 7) 7 + (9 - (2 * 3)) 7 - ((2 * 3) - 9) (7 * 3) - (2 + 9) 2 * (9 - (7 - 3)) 2 * (9 + (3 - 7)) ((7 * 3) - 2) - 9 ((7 * 3) - 9) - 2 2 * (3 - (7 - 9)) (9 - 7) * (2 + 3) 2 * (3 + (9 - 7)) 2 * ((3 + 9) - 7) 7 - ((3 - 9) / 2) 7 + ((9 - 3) / 2) ((3 * 9) - 7) / 2 $ ruby make_ten.rb 1185 [1, 1, 8, 5] で 10 を作る 8 / (1 - (1 / 5))
括弧を使っているので事実上は同じ演算が重複して出力されてしまいますが、そこはお許しを。
4 / (1 - (3 / 5))
のように分数を使ったものも解けます。
コード。
make_ten.rb
class Integer def /(a) Rational(self, a) end end def solve(ary) if ary.size <= 1 @ans << ary[0][1..-2] if eval(ary[0]) == 10 else idxs = [*0...ary.size] idxs.combination(2) do |i, j| a, b = ary[i], ary[j] nxt = (idxs - [i, j]).map{|x| ary[x]} nums = ["(#{a} + #{b})", "(#{a} - #{b})", "(#{b} - #{a})", "(#{a} * #{b})"] nums << "(#{a} / #{b})" if eval(b).nonzero? nums << "(#{b} / #{a})" if eval(a).nonzero? nums.each {|n| solve(nxt + [n])} end end end @ans = [] given = ARGV[0] ? ARGV[0].chars : Array.new(4) {[*0..9].sample.to_s} puts given.map(&:to_i).inspect + " で 10 を作る" solve(given) puts @ans.uniq
メソッド solve() は solve(["2", "7", "3", "9"])
のように各数字を String にして呼ぶのがミソです。eval の活躍しどころなのです。分数を使った場合に対応するため、演算子/
を再定義*1しています(Ruby!)。
例えば 9999 とか 3478 とか、むずかしいのがあるそうですよ。わからなかったら上のプログラムに解かせてみて下さいな。
実際には数字は 1桁でなくともよいですし、4つでなくとも構いません。