-- John Wilson-Kanamori 0458094 import LSystem -- 1. join :: [Command] -> Command join xs | xs == [] = Sit -- or error "Null Command" | otherwise = foldr1 (:#) xs -- 2. split :: Command -> [Command] split (x :# y) = split x ++ split y split z = [z] -- 3. copy :: Int -> Command -> Command copy x y = join (replicate x y) -- 4. hexagon :: Distance -> Command hexagon x = copy 6 (Go x :# Turn 60) -- 5. polygon :: Distance -> Int -> Command polygon x y = copy y (Go x :# Turn (fromIntegral (div 360 (y)))) -- 6. spiral :: Distance -> Int -> Distance -> Angle -> Command spiral a b c d = join (spiral' a b c d) spiral' :: Distance -> Int -> Distance -> Angle -> [Command] spiral' a b c d = [(Go (a - (fromIntegral x * c)) :# Turn d) | x <- [0..b-1]] -- 7. optimise :: Command -> Command optimise x | optimise' (optimise'''' x) == True = join (optimise'''' x) | otherwise = optimise (join (optimise'''' (join (optimise'''' x)))) optimise' :: [Command] -> Bool optimise' xs | elem (Go 0) (optimise'' xs) = False | elem (Turn 0) (optimise'' xs) = False | otherwise = True optimise'' :: [Command] -> [Command] optimise'' (Go a : Go b : x) = optimise'' (Go (a + b) : x) optimise'' (Turn a : Turn b : x) = optimise'' (Turn (a + b) : x) optimise'' (Go a : Turn b : x) = Go a : optimise'' (Turn b : x) optimise'' (Turn a : Go b : x) = Turn a : optimise'' (Go b : x) optimise'' (Go a : []) = Go a : [] optimise'' (Turn a : []) = Turn a : [] optimise'' [] = [] optimise''' :: [Command] -> [Command] optimise''' xs = [x | x <- xs, x /= Sit, x /= Go 0, x /= Turn 0] optimise'''' :: Command -> [Command] optimise'''' x = (optimise''' (optimise'' [x | x <- split x, x /= Sit, x /= Go 0, x /= Turn 0])) -- 8. arrowhead :: Int -> Command arrowhead x = f x where f 0 = Go 10 f (x+1) = g x :# p :# f x :# p :# g x g 0 = Go 10 g (x+1) = f x :# n :# g x :# n :# f x n = Turn 60 p = Turn (-60) -- 9. branch :: Int -> Command branch x = g x where g 0 = Go 10 g (x+1) = f x :# n :# Branch (Branch (g x) :# p :# g x) :# p :# f x :# Branch (p :# f x :# g x) :# n :# g x f 0 = Go 10 f (x+1) = f x :# f x n = Turn 22.5 p = Turn (-22.5) -- 10. hilbert :: Int -> Command hilbert x = l x where l 0 = Go 10 l (x+1) = p :# r x :# f x :# n :# l x :# f x :# l x :# n :# f x :# r x :# p r 0 = Go 10 r (x+1) = n :# l x :# f x :# p :# r x :# f x :# r x :# p :# f x :# l x :# n f x = Go 10 n = Turn 90 p = Turn (-90) -- Programming Competition Entry -- Please type 'display 0.1 johns' to conjure up the image. I'm afraid it may take up to 30 seconds to load, but I hope that you enjoy... johns :: Command johns = pattern 5 :# GrabPen Inkless :# Go 2900 :# Turn 90 :# Go 2950 :# Turn 180 :# pattern 5 :# GrabPen Inkless :# Turn (-90) :# Go 2200 :# Turn (-90) :# Go 2900 :# Turn 135 :# Go 1200 :# Turn (-45) :# pattern' :# Turn 120 :# GrabPen Inkless :# Go 1500 :# Turn (-45) :# Go 4200 :# Turn (-45) :# Go 400 :# Turn 180 :# pattern' pattern :: Int -> Command pattern x = GrabPen blue :# f x :# p :# f x :# p :# f x :# p :# f x where f 0 = Go 12 f (x+1) = f x :# f x :# p :# GrabPen red :# f x :# p :# f x :# p :# f x :# GrabPen blue :# p :# f x :# f x n = Turn 90 p = Turn (-90) snowflake :: Int -> Command snowflake x = GrabPen black :# f x :# n :# n :# f x :# n :# n :# f x :# n :# n where f 0 = Go 10 f (x+1) = f x :# p :# f x :# n :# n :# f x :# p :# f x n = Turn 60 p = Turn (-60) lambda :: Command lambda = GrabPen (mix red green) :# Turn 90 :# Go 100 :# Turn (-60) :# Go 1500 :# Turn 60 :# Go 100 :# Turn 180 :# Go 100 :# Turn (-60) :# Go 500 :# Turn (-60) :# Go 1000 pattern' :: Command pattern' = snowflake 5 :# GrabPen Inkless :# Go 600 :# Turn 90 :# Go 150 :# Turn (-90) :# lambda