#############################################

# FINAL FANTASY - THE 4 HEROES OF LIGHT

# Ruby script to produce the best solutions to Scholar Bear's Number Puzzles

# Version 1.0(final) - written by Khatharr (Aug 2012)

#############################################

# No rights reserved - enjoy!

#############################################

#global array with all operator set permutations

$operationSets = []

operators = ['+','-','*','/']

for a in operators

for b in operators

for c in operators

$operationSets.push([a,b,c])

end

end

end

#takes an input value array and spits out a 2D array with all combinations

def composeCombinations(ary)

a = ary[0]; b = ary[1]; c = ary[2]; d = ary[3]

set = [

[a,b,c,d], [a,b,d,c], [a,c,b,d], [a,c,d,b], [a,d,b,c], [a,d,c,b],

[b,a,c,d], [b,a,d,c], [b,c,a,d], [b,c,d,a], [b,d,a,c], [b,d,c,a],

[c,b,a,d], [c,b,d,a], [c,a,b,d], [c,a,d,b], [c,d,b,a], [c,d,a,b],

[d,b,c,a], [d,b,a,c], [d,c,b,a], [d,c,a,b], [d,a,b,c], [d,a,c,b]

]

return set

end

#determines the score of the operation ((A [op] B) [op] C) [op] D

def scoreSequential(valAry, opAry)

vals = valAry.clone

ops = opAry.clone

sult = vals.shift

retval = 0

3.times do

return 0 if (ops[0] == '/') and (sult % vals[0] != 0)

eval "retval += (sult = #{sult} #{ops.shift} #{vals.shift})"

end

return retval if sult == 10

return 0

end

#determines the score of the operation (A [op] B) [op] (C [op] D)

def scorePaired(vals, ops)

sult = []

return 0 if (ops[0] == '/') and (vals[0] % vals[1] != 0)

eval "sult[0] = vals[0] #{ops[0]} vals[1]"

return 0 if (ops[2] == '/') and (vals[2] % vals[3] != 0)

eval "sult[1] = vals[2] #{ops[2]} vals[3]"

if (ops[1] == '/')

return 0 if sult[1] == 0

return 0 if (sult[0] % sult[1] != 0)

end

eval "sult[2] = sult[0] #{ops[1]} sult[1]"

return 0 if sult[2] != 10

return (sult[0] + sult[1] + sult[2])

end

# POLAR BEARS ARE GOOD AT MATHS

def findBestSolution(ary)

results = {}

combos = composeCombinations(ary)

for combo in combos

for ops in $operationSets

score = scoreSequential(combo, ops)

results[score] = [combo.clone, ops.clone, false]

score = scorePaired(combo, ops)

results[score] = [combo.clone, ops.clone, true]

end

end

results.delete(0)

return results.max

end