The 24 Game tests one's mental arithmetic.



Task
Write a program that randomly chooses and displays four digits, each from 1 ──► 9 (inclusive) with repetitions allowed.

The program should prompt for the player to enter an arithmetic expression using just those, and all of those four digits, used exactly once each. The program should check then evaluate the expression.

The goal is for the player to enter an expression that (numerically) evaluates to 24.

 Only the following operators/functions are allowed: multiplication, division, addition, subtraction
 Division should use floating point or rational arithmetic, etc, to preserve remainders.
 Brackets are allowed, if using an infix expression evaluator.
 Forming multiple digit numbers from the supplied digits is disallowed. (So an answer of 12+12 when given 1, 2, 2, and 1 is wrong).
 The order of the digits when given does not have to be preserved.


Notes
 The type of expression evaluator used is not mandated. An RPN evaluator is equally acceptable for example.
 The task is not for the program to generate the expression, or test whether an expression is even possible.


Related tasks
 24 game/Solve


Reference
 The 24 Game on h2g2.


import Nanoquery.Lang
import Nanoquery.Util
 
// a function to get the digits from an arithmetic expression
def extract_digits(input)
	input = str(input)
	digits = {}
 
	loc = 0
	digit = ""
	while (loc < len(input))
		if input[loc] in "0123456789"
			digit += input[loc]
		else
			if len(digit) > 0
				digits.append(int(digit))
				digit = ""
			end
		end
		loc += 1
	end
	// check if there's a final digit
	if len(digit) > 0
		digits.append(int(digit))
	end
 
	return digits
end
 
// a function to duplicate a digit list
def dup(list)
	nlist = {}
 
	for n in list
		nlist.append(new(Integer, n))
	end
 
	return nlist
end
 
// generate four random digits and output them
random = new(Random)
randDigits = {}
for i in range(1, 4)
	randDigits.append(random.getInt(8) + 1)
end
println "Your digits are: " + randDigits + "\n"
 
// get expressions from the user until a valid one is found
won = false
while !won
	print "> "
	expr = input()
	tempDigits = dup(randDigits)
 
	// check for invalid digits in the expression
	invalid = false
	digits = extract_digits(expr)
	for (i = 0) (!invalid and (i < len(digits))) (i += 1)
		if not digits[i] in tempDigits
			invalid = true
			println "Invalid digit " + digits[i]
		else
			tempDigits.remove(tempDigits)
		end
	end
 
	// if there were no invalid digits, check if the expression
	// evaluates to 24
	if !invalid
		a = null
		try
			exec("a = " + expr)
		catch
			println "Invalid expression " + expr
		end
		println a
 
		if a = 24
			println "Success!"
			won = true
		end
	end
end