RosettaCodeData/Task/24-game-Solve/Ruby/24-game-solve.rb

42 lines
1.1 KiB
Ruby
Raw Permalink Normal View History

2016-12-05 22:15:40 +01:00
class TwentyFourGame
2013-04-10 21:29:02 -07:00
EXPRESSIONS = [
2016-12-05 22:15:40 +01:00
'((%dr %s %dr) %s %dr) %s %dr',
'(%dr %s (%dr %s %dr)) %s %dr',
'(%dr %s %dr) %s (%dr %s %dr)',
'%dr %s ((%dr %s %dr) %s %dr)',
'%dr %s (%dr %s (%dr %s %dr))',
]
2013-04-10 21:29:02 -07:00
2016-12-05 22:15:40 +01:00
OPERATORS = [:+, :-, :*, :/].repeated_permutation(3).to_a
2013-04-10 21:29:02 -07:00
2013-10-27 22:24:23 +00:00
def self.solve(digits)
solutions = []
2016-12-05 22:15:40 +01:00
perms = digits.permutation.to_a.uniq
perms.product(OPERATORS, EXPRESSIONS) do |(a,b,c,d), (op1,op2,op3), expr|
# evaluate using rational arithmetic
text = expr % [a, op1, b, op2, c, op3, d]
value = eval(text) rescue next # catch division by zero
solutions << text.delete("r") if value == 24
2013-04-10 21:29:02 -07:00
end
2013-10-27 22:24:23 +00:00
solutions
2013-04-10 21:29:02 -07:00
end
end
# validate user input
digits = ARGV.map do |arg|
begin
Integer(arg)
rescue ArgumentError
raise "error: not an integer: '#{arg}'"
end
end
digits.size == 4 or raise "error: need 4 digits, only have #{digits.size}"
2016-12-05 22:15:40 +01:00
solutions = TwentyFourGame.solve(digits)
2013-10-27 22:24:23 +00:00
if solutions.empty?
2013-04-10 21:29:02 -07:00
puts "no solutions"
else
2013-10-27 22:24:23 +00:00
puts "found #{solutions.size} solutions, including #{solutions.first}"
puts solutions.sort
2013-04-10 21:29:02 -07:00
end