Last active
May 27, 2018 12:35
-
-
Save seven1m/6a36782b93f10fa15a2fc381fd91bfb1 to your computer and use it in GitHub Desktop.
Classical Conversations Board Slam math game in use at http://seven1m.sdf.org/experiments/boardslam.cgi
This file contains 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
#!/usr/bin/env ruby | |
# pass 3 numbers as arguments: | |
# | |
# ./boardslam.rb 3 5 1 | |
# | |
# 3 - 5^0 - 1 = 1 | |
# 3 - 5^0 * 1 = 2 | |
# 3 + 5^0 - 1 = 3 | |
# 3 + 5^0 * 1 = 4 | |
# 3 + 5^0 + 1 = 5 | |
# 3^0 + 5 * 1 = 6 | |
# 3 + 5 - 1 = 7 | |
# 3 + 5 * 1 = 8 | |
# 3 + 5 + 1 = 9 | |
# 3^2 + 5^0 * 1 = 10 | |
# 3^2 + 5^0 + 1 = 11 | |
# 5 - 1 * 3 = 12 | |
# 3^2 + 5 - 1 = 13 | |
# 3 * 5 - 1 = 14 | |
# 3 * 5 * 1 = 15 | |
# 3 * 5 + 1 = 16 | |
# 5^2 - 3^2 + 1 = 17 | |
# 5 + 1 * 3 = 18 | |
# 3 + 1 * 5 = 20 | |
# 3^3 - 5 - 1 = 21 | |
# 3^3 - 5 * 1 = 22 | |
# 3^3 - 5 + 1 = 23 | |
# 3^0 * 5^2 - 1 = 24 | |
# 3^0 + 5^2 - 1 = 25 | |
# 3^0 + 5^2 * 1 = 26 | |
# 3 + 5^2 - 1 = 27 | |
# 3 + 5^2 * 1 = 28 | |
# 3 + 5^2 + 1 = 29 | |
# 3^3 + 5 - 1 = 31 | |
# 3^3 + 5 * 1 = 32 | |
# 3^2 + 5^2 - 1 = 33 | |
# 3^2 + 5^2 * 1 = 34 | |
# 3^2 + 5^2 + 1 = 35 | |
# 5 - 1 * 3^2 = 36 | |
# | |
# missing answers: 19, 30 | |
class BoardSlam | |
BOARD = 1..36 | |
OPERATIONS = %w(+ - * /) | |
def initialize(x, y, z) | |
@numbers = [x, y, z] | |
@answers = {} | |
end | |
attr_reader :numbers, :answers | |
def variants(num) | |
[num, "#{num}^0", "#{num}^2", "#{num}^3"] | |
end | |
def expand(num) | |
return num if num.is_a?(Fixnum) | |
num, exp = num.split('^').map(&:to_i) | |
num ** exp | |
end | |
def results | |
each_order do |x_base, y_base, z_base| | |
each_variant(x_base, y_base, z_base) do |(x_pretty, x), (y_pretty, y), (z_pretty, z)| | |
each_operation_pair do |op1, op2| | |
result1 = x.send(op1, y) | |
next if op1 == '/' && x % y != 0 | |
result2 = result1.send(op2, z) | |
next if op2 == '/' && result1 % z != 0 | |
if BOARD.include?(result2) and !answers.key?(result2) | |
answers[result2] = "#{x_pretty.to_s.ljust(3)} #{op1} #{y_pretty.to_s.ljust(3)} #{op2} #{z_pretty.to_s.ljust(3)}" | |
end | |
end | |
end | |
end | |
answers | |
end | |
def each_order | |
@numbers.permutation.each do |(x, y, z)| | |
yield x, y, z | |
end | |
end | |
def each_variant(x_base, y_base, z_base) | |
variants(x_base).each do |x| | |
x_expanded = expand(x) | |
variants(y_base).each do |y| | |
y_expanded = expand(y) | |
variants(z_base).each do |z| | |
z_expanded = expand(z) | |
yield([x, x_expanded], [y, y_expanded], [z, z_expanded]) | |
end | |
end | |
end | |
end | |
def each_operation_pair | |
OPERATIONS.each do |op1| | |
OPERATIONS.each do |op2| | |
yield(op1, op2) | |
yield(op2, op1) | |
end | |
end | |
end | |
def missing | |
BOARD.to_a - results.keys | |
end | |
end | |
if $0 == __FILE__ | |
require 'pp' | |
board = BoardSlam.new(*ARGV.map(&:to_i)) | |
board.results.sort.each do |result, equation| | |
puts equation.ljust(15) + ' = ' + result.to_s | |
end | |
puts | |
if board.missing.any? | |
puts "missing answers: #{board.missing.join(', ')}" | |
else | |
puts "all answers possible!" | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment