There's a combinatorics puzzle (as mentioned in Mathematics From the Birth of Numbers by Jan Gullberg) where if you line up fifteen members from two categories each (e.g. fifteen of category 0
and fifteen of category 1
for a total of 30
elements) mixed up in a certain order, then if you continuously go along this line in a circular fashion (i.e. wrapping around back to the start when you reach the end, continuing counting as you go) throwing out every ninth element, you'll eventually have just the elements of the one "favored" (1
) category
line = [1,1,1,1,0,0,0,0,0,1,1,0,1,1,1,...]
line
(see the run-length encoded tuples version below) is the actual ordering, that if you throw out every ninth,
line = [1,1,1,1,0,0,0,0,1,1,0,1,1,1,...] -- 9th thrown out
you'll always be throwing out the "disfavored" 0
. If seen from the RLE tuples standpoint (where (0|1, n)
encodes n
consecutive occurrences of the 0
or the 1
), (decrementing) from the tuple (0,x)
, i.e., decrementing the x
, you'll eventually get down to just the (1,y)
tuples, of course throwing out the fully depleted (0,0)
tuples as well and recompacting the list as you go
line = [(1,4),(0,5),(1,2),(0,1),(1,3),(0,1),(1,1),(0,2),(1,2),(0,3),(1,1),(0,2),(1,2),(0,1)]
I've got this to get started
tally = foldl (\acc elem -> if (snd(elem)+acc) >= 9
then (snd(elem)+acc)-9
else (snd(elem)+acc)) 0
and when I feed it line
tally [(1,4),(0,5),(1,2),(0,1),(1,3),(0,1),(1,1),(0,2),(1,2),(0,3),(1,1),(0,2),(1,2),(0,1)]
it takes the 4
of the first tuple, then adds the 5
of the second, gets 9
and resets the accumulator to start the "counting down the line" again. And so it accurately returns 3
which is, in fact, the leftover of the accumulator after going along for one pass and identifying the tuple with the ninth and resetting the accumulator. My obvious problem is how to go beyond just identifying the ninth elements, and actually start decrementing the 0
tuples' elements, as well as throwing them out when they're down to (0,0)
and re-running. I'm sure it would be easier to just build line
as
line = [1,1,1,1,0,0,0,0,0,1,1,0,1,1,1,...]
and start chucking (i.. removing) the ninth, again, which should always be a 0
element, (e.g., the first ninth has been eliminated from line
line = [1,1,1,1,0,0,0,0,1,1,0,1,1,1,...]
but this is more of a challenge because I essentially need a fold to be combined with a map -- which is what I want to learn, i.e., a purely functional, no counters, etc., style. Hints and help appreciated. Also, if someone in the combinatorics lore could shed some theory light on what's happening here, that would be nice, too.