Express a number
Back in the 60s, the French invented the TV game show "Des Chiffres et des Lettres" (Digits & Letters). The goal of the Digits-part of the show was to come as close as you can to a certain 3-digit target number, using some semi-randomly selected numbers. The contestants could use the following operators:
- concatenation (1 and 2 is 12)
- addition (1 + 2 is 3)
- subtraction (5 - 3 = 2)
- division (8 / 2 = 4); division is only allowed if the result is a natural number
- multiplication (2 * 3 = 6)
- parentheses, to override the regular precedence of operations: 2 * ( 3 + 4 ) = 14
Each given number can only be used once or not at all.
For example, the target number 728 can be matched exactly with the numbers: 6, 10, 25, 75, 5 and 50 with the following expression:
75 * 10 - ( ( 6 + 5 ) * ( 50 / 25 ) ) = 750 - ( 11 * 2 ) = 750 - 22 = 728
In this code challenge, your are given the task to find an expression as close as possible to a certain target number. Since we're living in the 21st century, we'll introduce bigger target numbers and more numbers to work with than back in the 60s.
Rules
- Allowed operators: concatenation, +, -, /, *, ( and )
- The concatenation operator has no symbol. Just concatenate the numbers.
- There is no "inverse concatenation". 69 is 69 and can't be split in a 6 and a 9.
- The target number is a positive integer and has a maximum of 18 digits.
- There are at least two numbers to work with and a maximum of 99 numbers. These numbers are also positive integers with a maximum of 18 digits.
- It is possible (actually quite probably) that the target number can't be expressed in terms of the numbers and the operators. The goal is to get as close as possible.
- The program should finish in a reasonable time (a few minutes on a modern desktop PC).
- Standard loopholes apply.
- Your program may not be optimized for the test set in the "scoring" section of this puzzle. I reserve the right to change the test set if I suspect anyone violating this rule.
- This is not a codegolf.
Input
The input consists of an array of numbers that can be formatted in any convenient way. The first number is the target number. The rest of the numbers are the numbers you should work with to form the target number.
Output
The requirements for the output are:
- It should be a string that consists of:
- any subset of the input numbers (except the target number)
- any number of operators
- I prefer the output to be single line without spaces, but if you must, you may add spaces and newlines as you see fit. They will be ignored in the controlling program.
- The output should be a valid mathematical expression.
Examples
For readability, all these examples have an exact solution and each input number is used exactly once.
Input: 1515483, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
Output: 111*111*(111+11+1)
Input: 153135, 1, 2, 3, 4, 5, 6, 7, 8, 9
Output: 123*(456+789)
Input: 8888888888, 9, 9, 9, 99, 99, 99, 999, 999, 999, 9999, 9999, 9999, 99999, 99999, 99999, 1
Output: 9*99*999*9999-9999999-999999-99999-99999-99999-9999-999-9-1
Input: 207901, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0
Output: 1+2*(3+4)*(5+6)*(7+8)*90
Input: 34943, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0
Output: 1+2*(3+4*(5+6*(7+8*90)))
But also valid output is: 34957-6-8
Scoring
The penalty score of a program is the sum of the relative errors of the expressions for the testset below.
For example if the target value is 125 and your expression gives 120, your penalty score is abs( 1 - 120/125 ) = 0,04.
The program with the lowest score (lowest total relative error) wins. If two programs finish equally, the first submission wins.
Finally, the testset (8 cases):
14142, 10, 11, 12, 13, 14, 15
48077691, 6, 9, 66, 69, 666, 669, 696, 699, 966, 969, 996, 999
333723173, 3, 3, 3, 33, 333, 3333, 33333, 333333, 3333333, 33333333, 333333333
589637567, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
8067171096, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199
78649377055, 0, 2, 6, 12, 20, 30, 42, 56, 72, 90, 110, 132, 156, 182, 210, 240, 272, 306, 342, 380, 420, 462, 506, 552, 600, 650, 702, 756, 812, 870, 930, 992
792787123866, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169
2423473942768, 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 2000000, 5000000, 10000000, 20000000, 50000000
Previous similar puzzles
After creating this puzzle and posting it on the sandbox, I noticed something similar (but not the same!) in two previous puzzles: here (no solutions) and here. This puzzle is somewhat different, because it introduces the concatenation operator, I don't seek and exact match and I like to see strategies for coming close to the solution without brute force. I think it is challenging.