Gelatin is a worse version of Jelly. It is a tacit programming language that always takes a single integer argument and that has 7 (or maybe 16) commands. You are to take in a Gelatin program and its argument and output the result.
Gelatin
Gelatin programs will always match the following regex:
^[+_DSa\d~]*$
i.e. they will only contain +_DSa0123456789~
characters. The commands in Gelatin are:
- Digits return their value (
0
is \$0\$,1
is \$1\$ etc.) Digits are stand alone, so10
represents \$1\$ and \$0\$, not \$10\$ a
returns the argument passed to the Gelatin programD
takes a left argument and returns it minus one (decremented)S
takes a left argument and returns its 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+
or_
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), D
and S
have an arity of \$1\$ (termed monads, no relation) and +
and _
have an arity of \$2\$ (termed dyads)
If +
or _
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 monadM
. First, we apply the monad toω
, yieldingM(ω)
. We then updatev
to be equal tod(v, M(ω))
. - 2, 0: This is a dyad
d
, followed by a niladN
. We simply updatev
to bed(v, N)
- 0, 2: The reverse of the previous pattern,
v
becomesd(N, v)
- 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 matches by the first 2. Therefore, we setv
to bed(v, ω)
- 1: The first arity is a monad
M
. We simply setv
to beM(v)
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 calculateS(ω) = S(5) = 25
, then calculatev = 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 tov
, updating it tov = v + v = 30 + 30 = 60
- The next arity pattern is 2, 0 (
_2
), which just subtracts 2, updatingv
tov = v - 2 = 60 - 2 = 58
- Finally, the last arity pattern is 2 (
_
), meaning we updatev
to bev = 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\$.
You are to take a string representing a Gelatin program, using the characters specified above, and a positive integer \$\omega\$ and output the result of running the Gelatin program with an argument of \$\omega\$
You may assume that the arities of the program will always fit one of the 5 patterns (so nothing like S1S
(1, 0, 1) will appear), and that the flow-through value will never exceed your language's integer bounds. The output may be negative.
This is code-golf so the shortest code in bytes wins
Test cases
Program ω out
+S 7 56
_aSS+ 20 20
++DDDS+1_ 15 1750
_S 13 -156
D0+ 12 11
_+~SSS++__S++a 6 1679598
_++a 17 34
a+_6D 20 33
D+_+_aD 17 15
5 5
DD 8 6
+_aa+S+SS+_+ 4 6404
+9+S_ 19 370
_DDD+_a+_3_4D_ 13 -9
SS_SD+ 15 50414
+~D_~_ 7 -7
D_a+S 10 99
_S+aD+4 1 4
+_a+ 3 6
_aD+60+ 13 5
+1++~ 3 10
This is a program that randomly generates \$n\$ Gelatin programs, along with random inputs and the intended outputs