The sequence in question can be generated with the algorithm described here. I'm not a big fan of this algorithm though, so I came up with my own after looking at the pattern for a bit.
sequence := "r"
FOR i=1 to n:
sequence = sequence + "r" + reverse(mirror(sequence))
Where 'reverse' reverses the string and 'mirror' flips 'r' to 'l' and vice versa.
To generate the sequence in Python, express the sequence as a list of 1s ('r's) and 0s ('l's). The code follows on from that.
def makeSequence(size):
seq = [1]
for i in xrange(size):
seq += [1] + map(lambda x: not x, seq[::-1])
return seq
To create the 'mirror' we map the 'not' function onto the boolean list, then we reverse with [::-1] (I'll explain how that works at some point in the future, probably). I think this function would look nice as a list comprehension. If only Python could do lazy evaluation like Haskell can...
As it stands, we now have a sequence. Now to draw it!
def drawCurve(size):
for instruction in makeSequence(size):
(t.right if instruction else t.left)(90)
t.forward(1)
What we're doing here is using a conditional expression to choose between two different functions (the 'turn right' function and 'turn left' function) depending on what the instruction says. The chosen function is then executed with the argument 90 (turn 90 degrees). Good luck finding a style guide which this code passes!
The full code is as follows:
import turtle
t = turtle.Pen()
t.tracer(5000)
def makeSequence(size):
seq = [1]
for i in xrange(size):
seq += [1] + map(lambda x: not x, seq[::-1])
return seq
def drawCurve(size):
for instruction in makeSequence(size):
(t.right if instruction else t.left)(90)
t.forward(1)
drawCurve(16)
t.tracer(1)
raw_input()
The output image looks something like this:
Success!

No comments:
Post a Comment