Skip to content

Instantly share code, notes, and snippets.

@galaydaroman
Last active February 21, 2017 23:35
Show Gist options
  • Save galaydaroman/8555d9bff6c8659d37a8444af46b77ef to your computer and use it in GitHub Desktop.
Save galaydaroman/8555d9bff6c8659d37a8444af46b77ef to your computer and use it in GitHub Desktop.
Solution to correct the equations with matches
module Matches
MATCH_BITS = {
' ' => '',
'0' => '123567',
'1' => '36',
'2' => '13457',
'3' => '13467',
'4' => '2346',
'5' => '12467',
'6' => '124567',
'7' => '136',
'8' => '1234567',
'9' => '123467',
'*' => 'xy',
'/' => 'x',
'+' => 'xy',
'-' => 'x',
'=' => 'x'
}
class Equation
attr_reader :input, :strategy, :diff_count
def initialize input, strategy:, diff_count:
@input = input
@strategy = strategy
@diff_count = diff_count
validate!
end
def execute
input_matches = get_matches_count input
expected_matches = expected_count input_matches
[].tap do |solutions|
operation_types_for(input[1]).each do |operation|
digits.each do |a|
digits.each do |b|
next if b == 0 && operation == '/'
result = evaluate a, b, operation
next if Float === result
result = " #{result}" if input[/(\d+|\-\d)$/].size > result.to_s.size
new_input = [a, operation, b, '=', result].join
if expected_matches == get_matches_count(new_input)
# puts '>> ' + new_input
actual_diff = diff_count
actual_diff *= 2 if strategy == :move
solutions << new_input if changes(new_input) == actual_diff
end
end
end
end
raise 'Equation solution was not found!' if solutions.empty?
end
end
def changes new_input
input.chars.zip(new_input.chars).reduce(0) do |result, (a, b)|
bits_a = MATCH_BITS[a].chars
bits_b = MATCH_BITS[b].chars
added = (bits_b - bits_a).count
removed = (bits_a - bits_b).count
result += added + removed
end
end
def validate!
raise 'Input should be an equation string' unless /\d[+-\/\*]\d=(\d{1,2}|\-\d)/ === input
raise 'Stratagy is wrong type' unless %i[add remove move].include? strategy
end
def evaluate a, b, op
if op == '/'
res = a.to_f / b
res % 1 == 0 ? res.to_i : res
else
[a, b].reduce &op.to_sym
end
end
def digits
(0..9).to_a
end
def operation_types_for operation
/[+-]/ === operation ? %w(+ -) : %w(* /)
end
def expected_count count
case strategy
when :add then count + diff_count
when :move then count
when :remove then count - diff_count
end
end
def get_matches_count input
input.chars.reduce(0) do |sum, char|
sum += MATCH_BITS[char].size
end
end
end
end
# equation = Matches::Equation.new '2-7=5', strategy: :add, diff_count: 2
# equation = Matches::Equation.new '7+9=15', strategy: :move, diff_count: 2
# equation = Matches::Equation.new '4*3=85', strategy: :move, diff_count: 2
equation = Matches::Equation.new '7-9=-9',
strategy: :add,
diff_count: 3
puts equation.execute
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment