Last active
September 30, 2015 01:02
-
-
Save erantapaa/d7758a8ac5a8e226a45b to your computer and use it in GitHub Desktop.
L-systems in Haskell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
L-systems in Haskell. | |
=== | |
> import Data.List.Split (splitOn) | |
> import Data.List | |
> | |
> type Rules = [(Char, String)] | |
> | |
> -- compute the next generation | |
> next :: Rules -> String -> String | |
> next rules [] = [] | |
> next rules (x:xs) = | |
> case lookup x rules of | |
> Nothing -> [x] ++ (next rules xs) | |
> Just y -> y ++ next rules xs | |
> | |
> -- another version of next | |
> next2 :: Rules -> String -> String | |
> next2 rules xs = concatMap go xs | |
> where go x = case lookup x rules of | |
> Nothing -> [x] | |
> Just y -> y | |
simplify | |
=== | |
In this case function `splitOn` and `intercalate` are inverses of each | |
other. `splitOn` splits a list at the specified delimiter character, | |
and `intercalate` joins a list of Strings together with a chosen separator | |
string. | |
> simplify :: String -> String | |
> simplify xs = intercalate "F" (map go (splitOn "F" xs)) | |
> where go xs = let count = mod (foldl accumulate 0 xs) 4 | |
> accumulate s '+' = s+1 | |
> accumulate s '-' = s-1 | |
> accumulate s _ = s | |
> result | count == 0 = "" | |
> | count == 1 = "+" | |
> | count == 3 = "-" | |
> | count == 2 = "++" -- or "--" | |
> in result | |
> | |
> lsystem = [ ('X', "X+YF+"), ('Y', "-FX-Y") ] | |
> | |
> test1 = take 4 $ iterate (next lsystem) "FX" | |
> -- test1 returns: ["FX","FX+YF+","FX+YF++-FX-YF+","FX+YF++-FX-YF++-FX+YF+--FX-YF+"] | |
> | |
> test2 = map simplify test1 | |
> -- test2 returns: ["F","F+F+","F+F+F-F+","F+F+F-F+F+F-F-F+"] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment