aoc

advent of code
git clone git://source.orangerot.dev:/aoc.git
Log | Files | Refs

Main2.hs (1220B)


      1 import Data.Char
      2 import Data.List (nub, sort)
      3 
      4 findBegin s@((x,y), c) dict = case filter (\(p,_) -> p == (x,y-1)) dict of
      5   [] -> s
      6   n:xs -> findBegin n dict
      7 
      8 uniqueLists :: [[((Int, Int), Char)]] -> [[((Int, Int), Char)]]
      9 uniqueLists = nub . map sort
     10 
     11 getNumber :: ((Int, Int), Char) -> [String] -> Int
     12 getNumber ((x,y),c) dict = read (takeWhile isDigit (drop y (dict!!x))) :: Int
     13 
     14 main :: IO ()
     15 main = do
     16   inputLines <- lines <$> getContents
     17 
     18   let distances = concat (map (\x -> (map (\y -> (x,y)) [-1..1])) [-1..1])
     19 
     20   let numInputLines = zip [0..] (map (zip [0..]) inputLines)
     21   let charCoords = concat (map (\(x, l) -> (map (\(y, c) -> ((x,y),c)) l)) numInputLines)
     22   let gears = map (\(p, c) -> p) (filter (\(_,c) -> c == '*') charCoords)
     23   let digits = filter (\(_,c) -> isDigit c) charCoords
     24   let gearsChars = map (\(x,y) -> (filter (\(p,xd) -> (elem p (map (\(x1,y1) -> (x+x1,y+y1)) distances))) digits)) gears
     25 
     26   let gearsBegins = uniqueLists $ map (\gearChars -> (nub (map (\x -> (findBegin x digits)) gearChars))) gearsChars
     27   let twoGears = filter (\x -> length x == 2) gearsBegins
     28   let serialNumbers = map (\gs -> product $ map (\g -> getNumber g inputLines) gs) twoGears
     29   print (sum serialNumbers)
     30