from notebook_preamble import D, J, V, define
J('[0 2 7 0] dup max')
from joy.library import SimpleFunctionWrapper
from joy.utils.stack import list_to_stack
@SimpleFunctionWrapper
def index_of(stack):
'''Given a sequence and a item, return the index of the item, or -1 if not found.
E.g.:
[a b c] a index_of
------------------------
0
[a b c] d index_of
------------------------
-1
'''
item, (sequence, stack) = stack
i = 0
while sequence:
term, sequence = sequence
if term == item:
break
i += 1
else:
i = -1
return i, stack
D['index_of'] = index_of
J('[0 2 7 0] 7 index_of')
J('[0 2 7 0] 23 index_of')
Starting at index
distribute count
"blocks" to the "banks" in the sequence.
[...] count index distribute
----------------------------
[...]
This seems like it would be a PITA to implement in Joypy...
from joy.utils.stack import iter_stack, list_to_stack
@SimpleFunctionWrapper
def distribute(stack):
'''Starting at index+1 distribute count "blocks" to the "banks" in the sequence.
[...] count index distribute
----------------------------
[...]
'''
index, (count, (sequence, stack)) = stack
assert count >= 0
cheat = list(iter_stack(sequence))
n = len(cheat)
assert index < n
cheat[index] = 0
while count:
index += 1
index %= n
cheat[index] += 1
count -= 1
return list_to_stack(cheat), stack
D['distribute'] = distribute
J('[0 2 7 0] dup max [index_of] nullary distribute')
J('[2 4 1 2] dup max [index_of] nullary distribute')
J('[3 1 2 3] dup max [index_of] nullary distribute')
J('[0 2 3 4] dup max [index_of] nullary distribute')
J('[1 3 4 1] dup max [index_of] nullary distribute')
[a F] x
[a F] a F
[a F] a swap [C] dip rest cons
a [a F] [C] dip rest cons
a C [a F] rest cons
a C [F] cons
w/ C == dup G
a dup G [F] cons
a a G [F] cons
w/ G == dup max [index_of] nullary distribute
define('direco dip rest cons')
define('G [direco] cons [swap] swoncat cons')
define('make_distributor [dup dup max [index_of] nullary distribute] G')
J('[0 2 7 0] make_distributor 6 [x] times pop')
First draft:
[] [GEN] x [pop index_of 0 >=] [pop size --] [[swons] dip x] tailrec
(?)
[] [GEN] x [pop index_of 0 >=] [pop size --] [[swons] dip x] tailrec
[] [...] [GEN] [pop index_of 0 >=] [pop size --] [[swons] dip x] tailrec
[] [...] [GEN] pop index_of 0 >=
[] [...] index_of 0 >=
-1 0 >=
False
Base case
[] [...] [GEN] [pop index_of 0 >=] [pop size --] [[swons] dip x] tailrec
[] [...] [GEN] pop size --
[] [...] size --
[] [...] size --
A mistake, popop
and no need for --
[] [...] [GEN] popop size
[] size
n
Recursive case
[] [...] [GEN] [pop index_of 0 >=] [popop size] [[swons] dip x] tailrec
[] [...] [GEN] [swons] dip x F
[] [...] swons [GEN] x F
[[...]] [GEN] x F
[[...]] [...] [GEN] F
[[...]] [...] [GEN] F
What have we learned?
F == [pop index_of 0 >=] [popop size] [[swons] dip x] tailrec
define('count_states [] swap x [pop index_of 0 >=] [popop size] [[swons] dip x] tailrec')
define('AoC2017.6 make_distributor count_states')
J('[0 2 7 0] AoC2017.6')
J('[1 1 1] AoC2017.6')
J('[8 0 0 0 0 0] AoC2017.6')