29 lines
1.1 KiB
Haskell
29 lines
1.1 KiB
Haskell
|
import Data.Char
|
||
|
import Data.List
|
||
|
|
||
|
-- findBegin :: ((Int, Int), Char) -> [((Int, Int), Char)] -> ((Int, Int), Char)
|
||
|
findBegin s@((x,y), c) dict = case filter (\(p,_) -> p == (x,y-1)) dict of
|
||
|
[] -> s
|
||
|
n:xs -> findBegin n dict
|
||
|
|
||
|
main :: IO ()
|
||
|
main = do
|
||
|
inputLines <- lines <$> getContents
|
||
|
|
||
|
let distances = concat (map (\x -> (map (\y -> (x,y)) [-1..1])) [-1..1])
|
||
|
|
||
|
let numInputLines = zip [0..] (map (zip [0..]) inputLines)
|
||
|
let charCoords = concat (map (\(x, l) -> (map (\(y, c) -> ((x,y),c)) l)) numInputLines)
|
||
|
let symbols = map (\(p, c) -> p) (filter (\(_,c) -> not (c == '.' || isDigit c)) charCoords)
|
||
|
let digits = filter (\(_,c) -> isDigit c) charCoords
|
||
|
let serialChars = filter (\((x,y),_) -> any (\x -> elem x symbols) (map (\(x1,y2) -> (x + x1, y + y2)) distances)) digits
|
||
|
let serialBegins = nub $ map (\x -> findBegin x digits) serialChars
|
||
|
let serialNumbers = map (\((x,y), c) -> read (takeWhile isDigit (drop y (inputLines!!x))) :: Integer) serialBegins
|
||
|
-- print charCoords
|
||
|
-- print symbols
|
||
|
print (sum serialNumbers)
|
||
|
-- convert input to [((x,y), Char)]
|
||
|
|
||
|
-- mapM_ putStrLn inputLines
|
||
|
|