Skip to content

Commit

Permalink
Merge pull request #6 from randallreedjr/bug/integer-division
Browse files Browse the repository at this point in the history
Fix bug that would return solutions with float arithmetic
  • Loading branch information
randallreedjr authored Jan 24, 2017
2 parents fd83b86 + 36512b8 commit 674697e
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 13 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@
/spec/reports/
/tmp/
math24-*.gem
.byebug_history
2 changes: 2 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ PATH
GEM
remote: https://rubygems.org/
specs:
byebug (9.0.6)
diff-lcs (1.2.5)
rake (10.5.0)
rspec (3.5.0)
Expand All @@ -27,6 +28,7 @@ PLATFORMS

DEPENDENCIES
bundler (~> 1.13)
byebug
math24!
rake (~> 10.0)
rspec (~> 3.0)
Expand Down
38 changes: 26 additions & 12 deletions lib/math24.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,33 +20,36 @@ def self.solve(problem)
num_permutation.each do |numbers|
op_permutation.each do |operators|
begin
forward_result = instance_eval("((#{numbers[0].to_f} #{operators[0]} #{numbers[1]}.to_f) #{operators[1]} #{numbers[2]}.to_f) #{operators[2]} #{numbers[3].to_f}")
proposed_solution = "((#{numbers[0].to_f} #{operators[0]} #{numbers[1]}.to_f) #{operators[1]} #{numbers[2]}.to_f) #{operators[2]} #{numbers[3].to_f}"
forward_result = instance_eval(proposed_solution)
rescue ZeroDivisionError
forward_result = 0
end

begin
alternate_result = instance_eval("(#{numbers[0].to_f} #{operators[0]} #{numbers[1].to_f}) #{operators[1]} (#{numbers[2].to_f} #{operators[2]} #{numbers[3].to_f})")
proposed_solution = "(#{numbers[0].to_f} #{operators[0]} #{numbers[1].to_f}) #{operators[1]} (#{numbers[2].to_f} #{operators[2]} #{numbers[3].to_f})"
alternate_result = instance_eval(proposed_solution)
rescue ZeroDivisionError
alternate_result = 0
end

begin
reverse_result = instance_eval("#{numbers[0].to_f} #{operators[0]} (#{numbers[1].to_f} #{operators[1]} (#{numbers[2].to_f} #{operators[2]} #{numbers[3].to_f}))")
proposed_solution = "#{numbers[0].to_f} #{operators[0]} (#{numbers[1].to_f} #{operators[1]} (#{numbers[2].to_f} #{operators[2]} #{numbers[3].to_f}))"
reverse_result = instance_eval(proposed_solution)
rescue ZeroDivisionError
reverse_result = 0
end

if forward_result == 24
if forward_result == 24 && integer_division_only?(proposed_solution)
if (operators.include?("+") || operators.include?("-")) && (operators.include?("*") || operators.include?("/"))
#Might need parentheses for order of operations
return "((#{numbers[0]} #{operators[0]} #{numbers[1]}) #{operators[1]} #{numbers[2]}) #{operators[2]} #{numbers[3]}"
else
return "#{numbers[0]} #{operators[0]} #{numbers[1]} #{operators[1]} #{numbers[2]} #{operators[2]} #{numbers[3]}"
end
elsif alternate_result == 24
elsif alternate_result == 24 && integer_division_only?(proposed_solution)
return "(#{numbers[0]} #{operators[0]} #{numbers[1]}) #{operators[1]} (#{numbers[2]} #{operators[2]} #{numbers[3]})"
elsif reverse_result == 24
elsif reverse_result == 24 && integer_division_only?(proposed_solution)
return "#{numbers[0]} #{operators[0]} (#{numbers[1]} #{operators[1]} (#{numbers[2]} #{operators[2]} #{numbers[3]}))"
end
end
Expand All @@ -55,12 +58,23 @@ def self.solve(problem)
return false
end

def self.check(problem, solution)
raise ArgumentError unless /\A\d{4}\z/.match problem.join
raise ArgumentError unless solution.is_a? String
raise ArgumentError unless /\A(\(*(\d{1}[()\s]*[*+-\/]+[()\s]*){3}\d{1}\)*)\z/.match(solution)
def self.check(problem, solution)
raise ArgumentError unless /\A\d{4}\z/.match problem.join
raise ArgumentError unless solution.is_a? String
raise ArgumentError unless /\A(\(*(\d{1}[()\s]*[*+-\/]+[()\s]*){3}\d{1}\)*)\z/.match(solution)

problem.count {|i| solution.include?(i.to_s) } == 4 &&
instance_eval(solution) == 24
end

problem.count {|i| solution.include?(i.to_s) } == 4 &&
instance_eval(solution) == 24
private

def self.integer_division_only? proposed_solution
# float and integer division yield same result
begin
instance_eval(proposed_solution) == instance_eval(proposed_solution.delete('.0'))
rescue ZeroDivisionError
false
end
end
end
2 changes: 1 addition & 1 deletion lib/math24/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Math24
VERSION = "2.0.0"
VERSION = "2.0.1"
end
1 change: 1 addition & 0 deletions math24.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ Gem::Specification.new do |spec|
spec.add_development_dependency "bundler", "~> 1.13"
spec.add_development_dependency "rake", "~> 10.0"
spec.add_development_dependency "rspec", "~> 3.0"
spec.add_development_dependency "byebug"
end
7 changes: 7 additions & 0 deletions spec/math24_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@

expect(solution).to be false
end

it 'returns solution that does not rely on float division' do
solution = Math24.solve [9, 6, 5, 2]
# should never be 9 + (6 * (5 / 2))

expect(solution).to eq "9 + (5 * (6 / 2))"
end
end

describe '#check' do
Expand Down

0 comments on commit 674697e

Please sign in to comment.