from random import choice
from stream import repeatcall, apply, fold, takei, takewhile, drop, item
vectoradd = lambda u, v: zip(u, v) >> apply(operator.add) >> list
Origin = [0, 0]
Directions = [[1,0], [0,1], [-1,0], [0,-1]]
randwalk = lambda: repeatcall(choice, Directions) >> fold(vectoradd, initval=Origin)
"""Generate a random walk and return True if the walker has returned to
the origin after taking `n` steps.
## `takei` yield lazily so we can short-circuit and avoid computing the rest of the walk
for pos in randwalk() >> drop(1) >> takei(xrange(n-1)):
if pos == Origin:
"""Generate a random walk and return its length upto the moment
that the walker first returns to the origin.
It is mathematically provable that the walker will eventually return,
meaning that the function call will halt, although it may take
"""Alternate the sign of numbers of the input stream by multiply it with
the unit alternating series 1, -1, ...
return zip(s, gseq(-1, initval=1)) >> apply(operator.mul)