#There you go, a ridiculously complicated solution to euler 220
#define the function that gives the instructions outputs an array
def d(n)
if n==0
["F","a"]
else
newarray(d(n-1))
end
end
#gimme a helper function that does the transformation for each iteration
#of the instructions outputs an array
def newarray(array)
$output=[]
array.each do |piece|
if piece=="a"
$output<<["a","R","b","F","R"]
else
if piece=="b"
$output<<["L","F","a","L","b"]
else
$output<<piece
end
end
end
$output.flatten
end
#define what the new direction is after an instruction L - Left
#or R - Right is given at a current direction. outputs direction
def direction(s,current_direction)
case current_direction
when :up
if s=="R"
:right
else
:left
end
when :right
if s=="R"
:down
else
:up
end
when :down
if s=="R"
:left
else
:right
end
when :left
if s=="R"
:up
else
:down
end
end
end
# define what happens to the coördinates [x,y] when a step is taken
# in a certain direction... outputs coördinates
def step(direction)
case direction
when :up
$coord[1]=$coord[1]+1
when :right
$coord[0]=$coord[0]+1
when :down
$coord[1]=$coord[1]-1
when :left
$coord[0]=$coord[0]-1
end
end
#decide a starting point at [x,y] coördinates
$coord=[0,0]
#give the starting direction
$current_direction=:up
def dragon(n,top_step)
instructions=d(n)
step=0
instructions.each do |instruction|
case instruction
when "R"
$current_direction=direction(instruction,$current_direction)
when "L"
$current_direction=direction(instruction,$current_direction)
when "F"
step+=1
step($current_direction)
if step==top_step
puts "["+$coord[0].to_s+","+$coord[1].to_s+"]"+"it da shit"
end
else
$current_direction=$current_direction
end
end
end
ONE WORD: THE FORCED INDENTATION OF CODE. EULER OVER. import operator
def sub(lst):
n = {'a': 'aRbFR', 'b': 'LFaLb'}
return reduce(operator.add, [tuple(n.get(e, e)) for e in lst])
def dragon(steps):
D = ('F', 'a')
for i in range(steps):
D = sub(D)
return D
x = y = 0
r = 0
R = {
0: lambda x,y: (x, y + 1),
1: lambda x,y: (x + 1, y),
2: lambda x,y: (x, y - 1),
3: lambda x,y: (x - 1, y),
}
i = 0
z = 10**12
for n in dragon(50):
if n == 'L': r = (r - 1) % 4
elif n == 'R': r = (r + 1) % 4
elif n == 'F':
x, y = R.get(r, lambda x, y: (x, y))(x, y)
i += 1
if i == z:
break
forward = (1, 0, 0)
left = (0, 0, 1)
right = (0, 0, -1)
(x, y, a) <+> (dx, dy, da) =
case a of
0 -> (x + dx, y + dy, a')
1 -> (x - dy, y + dx, a')
2 -> (x - dx, y - dy, a')
3 -> (x + dy, y - dx, a')
where a' = (a + da) `mod` 4
dragons n = reverse $ take (n + 1) $ iterate f (0, (0, 0, 0), (0, 0, 0))
where f (l, a, b) = (2 * l + 1,
(a <+> right <+> b <+> forward <+> right),
(left <+> forward <+> a <+> left <+> b))
position steps n = loop steps (0, 0, 1) "Fa" n (dragons n)
where loop 0 pos _ _ _ = pos
loop steps pos (x:xs) n ds@((l, a, b):ds') =
case x of
'F' -> loop (steps - 1) (pos <+> forward) xs n ds
'L' -> loop steps (pos <+> left) xs n ds
'R' -> loop steps (pos <+> right) xs n ds
_ | steps < l -> loop steps pos (expand x) (n - 1) ds'
| x == 'a' -> loop (steps - l) (pos <+> a) xs n ds
| x == 'b' -> loop (steps - l) (pos <+> b) xs n ds
expand 'a' = "aRbFR"
expand 'b' = "LFaLb"
answer = let (x, y, a) = position (10^12) 50 in (x, y)
(x, y, a) <+> (dx, dy, da) =
case a of
0 -> (x + dx, y + dy, a')
1 -> (x - dy, y + dx, a')
2 -> (x - dx, y - dy, a')
3 -> (x + dy, y - dx, a')
where a' = (a + da) `mod` 4