Day 03
This commit is contained in:
62
day03/Commons.hs
Normal file
62
day03/Commons.hs
Normal file
@@ -0,0 +1,62 @@
|
||||
module Commons where
|
||||
|
||||
import GHC.IO.Handle (isEOF)
|
||||
import Data.Char (isDigit)
|
||||
|
||||
|
||||
data Coordinates = Coordinates { x :: Int, y :: Int } deriving (Eq, Show)
|
||||
data NumberPart = NumberPart { value :: Int, numberLength :: Int, neighbors :: [Coordinates] } deriving Show
|
||||
data SymbolPart = SymbolPart { symbol :: Char, coordinates :: Coordinates } deriving Show
|
||||
data Engine = Engine { numbers :: [NumberPart], symbols :: [SymbolPart] } deriving Show
|
||||
|
||||
|
||||
parseNumberPartNeighborsIn :: Int -> Int -> Int -> [Coordinates]
|
||||
parseNumberPartNeighborsIn row column length | length > 0 = Coordinates {x = column + length - 1, y = row - 1}:
|
||||
Coordinates {x = column + length - 1, y = row + 1}:
|
||||
parseNumberPartNeighborsIn row column (length - 1)
|
||||
| length == 0 = []
|
||||
|
||||
parseNumberPartNeighbors :: Int -> Int -> Int -> [Coordinates]
|
||||
parseNumberPartNeighbors row column length = Coordinates {x = column - 1, y = row - 1}:
|
||||
Coordinates {x = column - 1, y = row}:
|
||||
Coordinates {x = column - 1, y = row+1}:
|
||||
Coordinates {x = column + length, y = row - 1}:
|
||||
Coordinates {x = column + length, y = row }:
|
||||
Coordinates {x = column + length, y = row + 1}:
|
||||
parseNumberPartNeighborsIn row column length
|
||||
|
||||
parseNumberPartValue :: String -> String
|
||||
parseNumberPartValue (h: t) | isDigit h = h: parseNumberPartValue t
|
||||
parseNumberPartValue _ = []
|
||||
|
||||
parseNumberPart :: Int -> Int -> String -> NumberPart
|
||||
parseNumberPart row column rawNumber = let value = parseNumberPartValue rawNumber
|
||||
l = length value
|
||||
in NumberPart {value = read value, numberLength = l,
|
||||
neighbors = parseNumberPartNeighbors row column l}
|
||||
|
||||
parseLine :: Int -> Int -> String -> Engine -> Engine
|
||||
parseLine _ _ [] engine = engine
|
||||
parseLine row column (h: t) engine | isDigit h = let newNumberPart = parseNumberPart row column (h: t)
|
||||
newNumberLength = numberLength newNumberPart
|
||||
in parseLine row (column + newNumberLength)
|
||||
(drop (newNumberLength - 1) t)
|
||||
engine {numbers = newNumberPart: numbers engine}
|
||||
| h /= '.' = let newSymbolPart = SymbolPart {
|
||||
symbol = h,
|
||||
coordinates = Coordinates {x = column, y = row}
|
||||
}
|
||||
in parseLine row (column + 1) t
|
||||
engine {symbols = newSymbolPart: symbols engine}
|
||||
| otherwise = parseLine row (column + 1) t engine
|
||||
|
||||
parseEngine :: Int -> Engine -> IO Engine
|
||||
parseEngine row engine = do done <- isEOF
|
||||
if done
|
||||
then return engine
|
||||
else do line <- getLine
|
||||
let newEngine = parseLine row 1 line engine
|
||||
parseEngine (row+1) newEngine
|
||||
|
||||
parse :: IO Engine
|
||||
parse = parseEngine 1 Engine {numbers = [], symbols = []}
|
||||
Reference in New Issue
Block a user