Created
December 22, 2016 19:16
-
-
Save esehara/f5515d46e3ddc62fd68dd774306e7d5a to your computer and use it in GitHub Desktop.
99ソルバー
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 99というダイスゲームとは | |
# | |
# ルールとしては、まず目標値を決める。この目標値は33から99となる。 | |
# そして、各プレイヤーはサイコロを5個振る。このサイコロの5個の出目を | |
# 足し算・引き算・掛け算・割り算を使って、目標値まで近づける。 | |
# 最も目標値に近いプレイヤーが勝つ、というルールのゲーム。 | |
# | |
# 詳しくは『ダイスゲーム百科』024pを参考にすること。 | |
class Game | |
attr_accessor :dices_perm, :goal, :temp_answer | |
OPLIST = ["+", "-", "--", "*", "/", "//"].repeated_permutation(4) | |
def initialize | |
@goal = Random.rand(66) + 33 | |
set_dices | |
end | |
def set_dices | |
@dices = Array.new(5) { Random.rand(6) + 1 } | |
@dices_perm = @dices.permutation(5) | |
end | |
def goal_check(result, ops, dices, pattern) | |
return if result < 0 | |
@temp_answer = [ops, dices, result] if @temp_answer.nil? | |
if (@goal - @temp_answer[2]).abs > (@goal - result).abs | |
@temp_answer = [ops, dices, result, pattern] | |
end | |
end | |
def solve | |
@dices_perm.each do |d| | |
OPLIST.each do |op| | |
begin | |
# 7割は解ける | |
goal_check( | |
solve_ops( | |
solve_op(d[0], d[1], op[0]), | |
d[2..4].zip(op[1..3])), | |
d, op, "((((a o1 b) o2 c) o3 d) o4 e)") | |
break if goal == @temp_answer[2] | |
# 言うてもそんなに改善はしない | |
goal_check( | |
solve_op( | |
solve_op( | |
solve_op(d[0], d[1], op[0]), | |
solve_op(d[2], d[3], op[2]), | |
op[1] | |
), d[4], op[3] | |
), | |
d, op, "((a o1 b) o2 (c o3 b)) o4 e" | |
) | |
rescue ZeroDivisionError | |
next | |
end | |
end | |
end | |
end | |
def to_ans_s | |
n = @temp_answer[0] | |
o = @temp_answer[1] | |
n[0], n[1] = n[1], n[0] if o[0] == "--" || o[0] == "//" | |
o[0] = '-' if o[0] == "--" | |
o[0] = '/' if o[0] == "//" | |
case @temp_answer[3] | |
when "((((a o1 b) o2 c) o3 d) o4 e)" | |
a = "(#{n[0]} #{o[0]} #{n[1]})" | |
n[2..4].zip(o[1..3]).each do |x| | |
a = create_paren(a, x[0], x[1]) | |
end | |
when "((a o1 b) o2 (c o3 b)) o4 e" | |
a = "(#{n[0]} #{o[0]} #{n[1]})" | |
n[3], n[2] = n[2], n[3] if o[2] == "--" || o[2] == "//" | |
o[2] = '-' if o[2] == "--" | |
o[2] = '/' if o[2] == "//" | |
c = "(#{n[2]} #{o[2]} #{n[3]})" | |
if o[1] == "--" || o[1] == "//" | |
o[1] = '-' if o[1] == "--" | |
o[1] = '/' if o[1] == "//" | |
b = "(#{c} #{o[1]} #{a})" | |
else | |
b = "(#{a} #{o[1]} #{c})" | |
end | |
a = create_paren(b, n[4], o[3]) | |
end | |
"#{a} = #{@temp_answer[2]}" | |
end | |
def create_paren(s, n, o) | |
if o == '--' || o == '//' | |
o = '-' if o == "--" | |
o = '/' if o == "//" | |
"(#{n} #{o} #{s})" | |
else | |
"(#{s} #{o} #{n})" | |
end | |
end | |
def solve_op(a, b, o) | |
case o | |
when "+" | |
a + b | |
when "-" | |
a - b | |
when "--" | |
b - a | |
when "*" | |
a * b | |
when "/" | |
a / b | |
when "//" | |
b / a | |
end | |
end | |
def solve_ops(result, rest) | |
rest.each do |r| | |
result = solve_op(result, r[0], r[1]) | |
end | |
result | |
end | |
end | |
solves = 0 | |
1000.times do | |
game = Game.new | |
game.solve | |
print "GOAL #{game.goal}:" | |
puts game.to_ans_s | |
solves += 1 if game.goal == game.temp_answer[2] | |
end | |
puts solves |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment