···11+import "trilogy:debug" use dbg
22+import "trilogy:io" use readall, println
33+import "trilogy:parsec" use parse, apply, per_line, choice, char, string, integer, followed_by, eof
44+import "trilogy:array" use fold
55+66+proc argument!() {
77+ apply <| choice [
88+ char 'w',
99+ char 'x',
1010+ char 'y',
1111+ char 'z',
1212+ integer,
1313+ ]
1414+}
1515+1616+proc instruction!() {
1717+ let op_code = apply <| choice [
1818+ string "inp",
1919+ string "add",
2020+ string "mul",
2121+ string "div",
2222+ string "mod",
2323+ string "eql",
2424+ ]
2525+ apply <| char ' '
2626+ match op_code {
2727+ case "inp" then 'inp(apply argument)
2828+ case "add" then 'add(apply (followed_by (char ' ') argument):apply argument)
2929+ case "mul" then 'mul(apply (followed_by (char ' ') argument):apply argument)
3030+ case "div" then 'div(apply (followed_by (char ' ') argument):apply argument)
3131+ case "mod" then 'mod(apply (followed_by (char ' ') argument):apply argument)
3232+ case "eql" then 'eql(apply (followed_by (char ' ') argument):apply argument)
3333+ }
3434+}
3535+3636+proc countdown!(cb) {
3737+ with cb!() {
3838+ when 'inp then {
3939+ for option in [9, 8, 7, 6, 5, 4, 3, 2, 1] {
4040+ match resume option {
4141+ case 'some(val) then cancel 'some("${option}${val}")
4242+ }
4343+ }
4444+ cancel 'none
4545+ }
4646+ }
4747+}
4848+4949+func set 'w' w [_, x, y, z] = [w, x, y, z]
5050+func set 'x' x [w, _, y, z] = [w, x, y, z]
5151+func set 'y' y [w, x, _, z] = [w, x, y, z]
5252+func set 'z' z [w, x, y, _] = [w, x, y, z]
5353+5454+func get val and typeof 'number _ = val
5555+func get 'w' [w, _, _, _] = w
5656+func get 'x' [_, x, _, _] = x
5757+func get 'y' [_, _, y, _] = y
5858+func get 'z' [_, _, _, z] = z
5959+6060+func apply_instruction _ 'none = 'none
6161+func apply_instruction 'inp(var) 'some(state) = 'some(set var (yield 'inp) state)
6262+func apply_instruction 'add(var:rhs) 'some(state) = 'some(set var (get var state + get rhs state) state)
6363+func apply_instruction 'mul(var:rhs) 'some(state) = 'some(set var (get var state * get rhs state) state)
6464+func apply_instruction 'div(var:rhs) 'some(state) = 'some(set var (get var state // get rhs state) state)
6565+func apply_instruction 'mod(var:rhs) 'some(state) = 'some(set var (get var state % get rhs state) state)
6666+func apply_instruction 'eql(var:rhs) 'some(state) = 'some(set var (if get var state == get rhs state then 1 else 0) state)
6767+6868+func evaluate program state = fold (fn i s. apply_instruction i s) 'some(state) program
6969+7070+func maybe option cb = match option {
7171+ case 'some(val) then cb val
7272+ else 'none
7373+}
7474+7575+proc main!() {
7676+ let program = parse (followed_by eof <| per_line instruction) readall!()
7777+ let 'some(result) = {
7878+ using countdown
7979+ do(state) using maybe (evaluate program [0, 0, 0, 0])
8080+ if get 'z' state == 0 then 'some("") else 'none
8181+ }
8282+ println!(result)
8383+}