Skip to content

Instantly share code, notes, and snippets.

@dustMason
Last active December 13, 2015 22:39
Show Gist options
  • Save dustMason/4986249 to your computer and use it in GitHub Desktop.
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.
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