Gelatin programs will always match the following regex:
i.e. they will only contain
+_DSa0123456789~ characters. The commands in Gelatin are:
- Digits return their value (
1is \$1\$ etc.) Digits are stand alone, so
10represents \$1\$ and \$0\$, not \$10\$
areturns the argument passed to the Gelatin program
Dtakes a left argument and returns it minus one (decremented)
Stakes a left argument and returns it's square
+takes a left and a right argument and returns their sum
_takes a left and a right argument and returns their difference (subtract the right from the left)
~is a special command. It is always preceded by either
_and it indicates that the preceding command uses the same argument for both the left and the right.
Each command - aside from
~ - in Gelatin has a fixed arity, which is the number of arguments it takes. Digits and
a have an arity of \$0\$ (termed nilads),
S have an arity of \$1\$ (termed monads, no relation) and
_ have an arity of \$2\$ (termed dyads)
_ is followed by a
~, however, they become monads. This affects how the program is parsed.
Tacit languages try to avoid referring to their arguments as much as possible. Instead, they compose the functions in their code so that, when run, the correct output is produced. How the functions are composed depends on their arity.
Each program has a "flow-through" value,
v and an argument
v is initially equal to
ω. We match the start of the program against one of the following arity patterns (earliest first), update
v and remove the matched pattern from the start. This continues until the program is empty:
- 2, 1: This is a dyad
d, followed by a monad
M. First, we apply the monad to
M(ω). We then update
vto be equal to
- 2, 0: This is a dyad
d, followed by a nilad
N. We simply update
- 0, 2: The reverse of the previous pattern,
- 2: The first arity is a dyad
d, and it's not followed by either a monad or a nilad as it would've been matched by the first 2. Therefore, we set
- 1: The first arity is a monad
M. We simply set
For example, consider the program
+S+~_2_ with an argument
5. The arities of this are
[2, 1, 1, 2, 0, 2] (note that
+~ is one arity,
1). We start with
v = ω = 5:
- The first 2 arities match pattern 2, 1 (
+S), so we calculate
S(ω) = S(5) = 25, then calculate
v = v + S(ω) = 5 + 25 = 30
- The next arity matches pattern 1 (
+~means we add the argument to itself, so we double it. Therefore, we apply the monad to
v, updating it to
v = v + v = 30 + 30 = 60
- The next arity pattern is 2, 0 (
_2), which just subtracts 2, updating
v = v - 2 = 60 - 2 = 58
- Finally, the last arity pattern is 2 (
_), meaning we update
v = v - ω = 58 - 5 = 53.
- There are now no more arity patterns to match, so we end the program
At the end of the program, Gelatin outputs the value of
v and terminates.
In a more general sense,
+S+~_2_ is a function that, with an argument \$\omega\$, calculates \$2(\omega + \omega^2) - 2 - \omega = 2\omega^2 + \omega - 2\$.
S+~+_2 is one byte shorter, which is our goal in this challenge.
Given an integer \$n\$ and a target integer \$m\$, you should output a valid Gelatin program that takes \$n\$ as input and outputs \$m\$. A valid Gelatin program is one where the arities always follow the five patterns above (so not
123, etc.), and one that matches the described regex above.
However, this is not a code-golf challenge. Instead, your program will be scored on how short the generated Gelatin programs are for a set of 20 randomly generated inputs where \$-9999 \le n \le 9999\$. The shortest combined length wins.
I will be testing the submissions in order to get a final score. If your program times out on TIO for \$|n-m| > 500\$, please provide testing instructions. If, for whatever reason, you program fails to produce a correct output for any of the scoring cases, I cannot score your program and it is disqualified. This includes time and memory limitations, so please make your metagolfers somewhat efficient.
The MD5 hash of the list of inputs, in the form of a list of newline separated lines like
n m, is
You can use the following test cases to test your answer. They have no bearing on your final score. You are under no obligation to golf your generating code.
This is a very naïve attempt, that simply adds or subtracts \$9\$ until it's within \$9\$ of the target, where it adds/subtracts the remaining gap. It scores 292 on the test cases, and 3494 on the scoring cases. You should aim to beat this at the very least.
n m 7 2 -8 7 2 2 1 -7 2 1 0 30 -40 66 5 -15 -29 18 24 -33 187 -3 417 512 -101 -108 329 251 86 670