Last active
December 13, 2015 22:39
-
-
Save dustMason/4986249 to your computer and use it in GitHub Desktop.
A ruby version of the Letters and Numbers "Numbers Round" solver. Check my previous gist for a Scala version with more info. REQUIRES RUBY 2.0! due to use of lazy enumerators.
This file contains hidden or 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
class Equation | |
attr_reader :ops | |
def initialize(ops) | |
@ops = ops | |
end | |
def calc | |
calc_rec(@ops) | |
end | |
def calc_rec(equation) | |
chunk = equation.take(3) | |
if chunk.size == 1 | |
chunk.first | |
else | |
calc_rec(equation[3..-1].unshift(calc_chunk(*chunk))) | |
end | |
end | |
def calc_chunk(a, op, b) | |
a = a.to_i | |
b = b.to_i | |
case op | |
when "+" then a + b | |
when "-" then a - b | |
when "*" then a * b | |
when "/" then a / b | |
end | |
end | |
end | |
class Solver | |
def initialize(cards, goal) | |
# cards is an array of ints | |
@cards = cards | |
@goal = goal | |
end | |
def possibilities | |
# should return a lazy enumerator of all possible equations | |
# made from cards and ops | |
hands = @cards.permutation.lazy | |
opMix = %w{+ - * /}.repeated_combination(@cards.size - 1) | |
hands.flat_map do |h| | |
opMix.flat_map do |o| | |
Equation.new(h.zip(o).flatten.compact) | |
end | |
end | |
end | |
def best_equation | |
best = nil | |
best_diff = Float::INFINITY | |
possibilities.each do |p| | |
a = p.calc | |
if (a - @goal).abs < best_diff | |
best = p | |
best_diff = (a - @goal).abs | |
break if best_diff == 0 | |
end | |
end | |
best | |
end | |
end | |
s = Solver.new [25, 10, 50, 7, 2, 4], 900 | |
puts s.best_equation.ops.join " " |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment