50 lines
2.1 KiB
Haskell
50 lines
2.1 KiB
Haskell
module Commons where
|
|
|
|
import GHC.IO.Handle (isEOF)
|
|
import Data.Array (Array, listArray, (!), indices)
|
|
|
|
|
|
data Direction = North | East | West | South deriving (Eq, Show)
|
|
data Tile = Ground | Start | Pipe (Direction, Direction) deriving (Eq, Show)
|
|
type Grid = Array (Int, Int) Tile
|
|
|
|
|
|
parseLine :: String -> [Tile]
|
|
parseLine [] = []
|
|
parseLine ('.': t) = Ground: parseLine t
|
|
parseLine ('S': t) = Start: parseLine t
|
|
parseLine ('|': t) = Pipe (North, South): parseLine t
|
|
parseLine ('-': t) = Pipe (East, West): parseLine t
|
|
parseLine ('L': t) = Pipe (North, East): parseLine t
|
|
parseLine ('J': t) = Pipe (North, West): parseLine t
|
|
parseLine ('7': t) = Pipe (South, West): parseLine t
|
|
parseLine ('F': t) = Pipe (South, East): parseLine t
|
|
|
|
parseGrid :: [[Tile]] -> IO Grid
|
|
parseGrid otherTiles = do done <- isEOF
|
|
if done
|
|
then return $ listArray ((1, 1), (length otherTiles, length (otherTiles !! 1)))
|
|
$ concat otherTiles
|
|
else do line <- getLine
|
|
let tiles = parseLine line
|
|
parseGrid (otherTiles ++ [tiles])
|
|
|
|
parse :: IO Grid
|
|
parse = parseGrid []
|
|
|
|
|
|
findStart :: [(Int, Int)] -> Grid -> (Int, Int)
|
|
findStart (h: t) grid | grid ! h == Start = h
|
|
| otherwise = findStart t grid
|
|
|
|
getStartCoordinates :: Grid -> (Int, Int)
|
|
getStartCoordinates grid = findStart (indices grid) grid
|
|
|
|
getStartDirection :: (Int, Int) -> Grid -> (Direction, (Int, Int))
|
|
getStartDirection (y, x) grid | grid ! (y + 1, x) == Pipe (North, South) = (South, (y + 1, x))
|
|
| grid ! (y + 1, x) == Pipe (North, East) = (South, (y + 1, x))
|
|
| grid ! (y + 1, x) == Pipe (North, West) = (South, (y + 1, x))
|
|
| grid ! (y, x + 1) == Pipe (East, West) = (East, (y, x + 1))
|
|
| grid ! (y, x + 1) == Pipe (North, West) = (East, (y, x + 1))
|
|
| grid ! (y, x + 1) == Pipe (South, West) = (East, (y, x + 1))
|