Langton's ant: Difference between revisions

(→‎{{header|Perl 6}}: swap vars in output loop to tradtitional y=vertical, x=horizontal; swap turns in compute loop to maintain chirality.)
Line 1,024:
}
}</lang>
 
=={{header|Haskell}}==
<lang Haskell>
data Color = Black | White
deriving (Read, Show, Enum, Eq, Ord)
 
putCell c = case c of Black -> putStr "#"
White -> putStr "."
 
toggle :: Color -> Color
toggle color = toEnum $ 1 - fromEnum color
 
 
data Dir = East | North | West | South
deriving (Read, Show, Enum, Eq, Ord)
 
turnLeft South = East
turnLeft dir = succ dir
 
turnRight East = South
turnRight dir = pred dir
 
data Pos = Pos { x :: Int, y :: Int }
deriving (Read)
 
instance Show Pos where
show p@(Pos x y) = "(" ++ (show x) ++ "," ++ (show y) ++ ")"
 
-- Return the new position after moving one unit in the given direction
moveOne pos@(Pos x y) dir =
case dir of
East -> Pos (x+1) y
South -> Pos x (y+1)
West -> Pos (x-1) y
North -> Pos x (y-1)
 
-- Grid is just a list of lists
type Grid = [[Color]]
 
colorAt g p@(Pos x y) = (g !! y) !! x
 
replaceNth n newVal (x:xs)
| n == 0 = newVal:xs
| otherwise = x:replaceNth (n-1) newVal xs
 
toggleCell g p@(Pos x y) =
let newVal = toggle $ colorAt g p
in replaceNth y (replaceNth x newVal (g !! y)) g
 
printRow r = do { mapM_ putCell r ; putStrLn "" }
 
printGrid g = mapM_ printRow g
 
 
data State = State { move :: Int, pos :: Pos, dir :: Dir, grid :: Grid }
 
printState s = do {
putStrLn $ show s;
printGrid $ grid s
}
 
instance Show State where
show s@(State m p@(Pos x y) d g) =
"Move: " ++ (show m) ++ " Pos: " ++ (show p) ++ " Dir: " ++ (show d)
 
nextState s@(State m p@(Pos x y) d g) =
let c = colorAt g p
in let new_d = case c of White -> (turnRight d)
Black -> (turnLeft d)
in let new_m = m + 1
new_p = moveOne p new_d
new_g = toggleCell g p
in State new_m new_p new_d new_g
 
inRange size s@(State m p@(Pos x y) d g) =
x >= 0 && x < size && y >= 0 && y < size
 
initialState size = (State 0 (Pos (size`div`2) (size`div`2)) East [ [ White | x <- [1..size] ] | y <- [1..size] ])
 
--- main
size = 100
allStates = initialState size : [nextState s | s <- allStates]
 
main = printState $ last $ takeWhile (inRange size) allStates</lang>
 
=={{header|Icon}} and {{header|Unicon}}==
1,480

edits