Day 6, Part 1
This commit is contained in:
		
							
								
								
									
										74
									
								
								Day6/puzzle1.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								Day6/puzzle1.hs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| import Data.List (elemIndex) | ||||
| import Data.Maybe (isJust, fromMaybe) | ||||
|  | ||||
| type Grid = [String] | ||||
| type Position = (Int, Int) | ||||
| data Direction = U | R | D | L deriving Eq | ||||
|  | ||||
| getDirection :: Char -> Direction | ||||
| getDirection '^' = U | ||||
| getDirection '>' = R | ||||
| getDirection 'v' = D | ||||
| getDirection '<' = L | ||||
|  | ||||
| getStartPositionition :: Char -> Grid -> Position | ||||
| getStartPositionition c grid = (x, y) | ||||
|                             where x = fromMaybe (-1) . elemIndex True . map (isJust . elemIndex c) $ grid | ||||
|                                   y = if x == -1 | ||||
|                                            then -1 | ||||
|                                            else fromMaybe (-1) . elemIndex c $ grid !! x | ||||
|  | ||||
| getGridVal :: Position -> Grid -> Char | ||||
| getGridVal (x, y) grid = (grid !! x) !! y | ||||
|  | ||||
| moveUp :: Position -> Position | ||||
| moveUp (x, y) = (x - 1, y) | ||||
|  | ||||
| moveDown :: Position -> Position | ||||
| moveDown (x, y) = (x + 1, y) | ||||
|  | ||||
| moveLeft :: Position -> Position | ||||
| moveLeft (x, y) = (x, y - 1) | ||||
|  | ||||
| moveRight :: Position -> Position | ||||
| moveRight (x, y) = (x, y + 1) | ||||
|  | ||||
| isInside :: Position -> Grid -> Bool | ||||
| isInside (x, y) grid = x >= 0 && y >= 0 && x < length grid && y < length (head grid) | ||||
|  | ||||
| getNextPosition :: Position -> Direction -> Grid -> (Position, Direction) | ||||
| getNextPosition (x, y) U grid = let newPos = moveUp (x, y) | ||||
|                                 in  if newPos `isInside` grid && getGridVal newPos grid == '#' | ||||
|                                        then (moveRight (x, y), R) | ||||
|                                     else (newPos, U) | ||||
| getNextPosition (x, y) R grid = let newPos = moveRight (x, y) | ||||
|                                 in  if newPos `isInside` grid && getGridVal newPos grid == '#' | ||||
|                                        then (moveDown (x, y), D) | ||||
|                                     else (newPos, R) | ||||
| getNextPosition (x, y) D grid = let newPos = moveDown (x, y) | ||||
|                                 in  if newPos `isInside` grid && getGridVal newPos grid == '#' | ||||
|                                        then (moveLeft (x, y), L) | ||||
|                                     else (newPos, D) | ||||
| getNextPosition (x, y) L grid = let newPos = moveLeft (x, y) | ||||
|                                 in  if newPos `isInside` grid && getGridVal newPos grid == '#' | ||||
|                                        then (moveUp (x, y), U) | ||||
|                                     else (newPos, L) | ||||
|  | ||||
| markVisited :: Position -> Grid -> Grid | ||||
| markVisited (x, y) grid = let row = grid !! x | ||||
|                               newRow = take y row ++ ['X'] ++ drop (y + 1) row | ||||
|                           in  take x grid ++ [newRow] ++ drop (x + 1) grid | ||||
|  | ||||
| visitGrid :: Position -> Direction -> Grid -> Grid | ||||
| visitGrid (x, y) direction grid = let newGrid = markVisited (x, y) grid | ||||
|                                       (newPosition, newDirection) = getNextPosition (x, y) direction grid | ||||
|                                   in  if newPosition `isInside` newGrid | ||||
|                                          then visitGrid newPosition newDirection newGrid | ||||
|                                          else newGrid | ||||
|  | ||||
| main = do | ||||
|     contents <- lines <$> readFile "day6.txt" | ||||
|     let (x, y) = (\w x y z -> head $ filter ((>= 0) . fst) [w, x, y, z]) <$> getStartPositionition 'v' <*> getStartPositionition '^' | ||||
|                                                                              <*> getStartPositionition '<' <*> getStartPositionition '>' $ contents | ||||
|         direction = getDirection $ (contents !! x) !! y | ||||
|     print . length . filter (== 'X') . concat $ visitGrid (x, y) direction contents | ||||
		Reference in New Issue
	
	Block a user