<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Advent of Code 2017
December 6th
[0 2 7 0] dup max
Step1:  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...
Step2:  Recalling "Generator Programs"
[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
Step3:  A function to drive a generator and count how many states before a repeat.
First draft
<ASSISTANT_TASK:>
Python Code:
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')
Explanation: Advent of Code 2017
December 6th
[0 2 7 0] dup max
End of explanation
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')
Explanation: 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...
End of explanation
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')
Explanation: Recalling "Generator Programs"
[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
End of explanation
define('count_states == [] swap x [pop index_of 0 >=] [popop size] [[swons] dip x] primrec')
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')
Explanation: A function to drive a generator and count how many states before a repeat.
First draft:
[] [GEN] x [pop index_of 0 &gt;=] [pop size --] [[swons] dip x] primrec
(?)
[]       [GEN] x [pop index_of 0 &gt;=] [pop size --] [[swons] dip x] primrec
[] [...] [GEN]   [pop index_of 0 &gt;=] [pop size --] [[swons] dip x] primrec
[] [...] [GEN]    pop index_of 0 &gt;=
[] [...]              index_of 0 &gt;=
                            -1 0 &gt;=
                             False
Base case
[] [...] [GEN] [pop index_of 0 &gt;=] [pop size --] [[swons] dip x] primrec
[] [...] [GEN]                      pop size --
[] [...]                                size --
[] [...]                                size --
A mistake, popop and no need for --
[] [...] [GEN] popop size
[]                   size
n
Recursive case
[] [...] [GEN] [pop index_of 0 &gt;=] [popop size] [[swons] dip x] primrec
[] [...] [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 &gt;=] [popop size] [[swons] dip x] primrec
End of explanation
<END_TASK>