1
0
Fork 0
adventofcode/src/Day06.hs

42 lines
1.7 KiB
Haskell

module Day06 (main) where
import Data.List (maximumBy, sortBy)
import Data.Ord (comparing)
import Data.Function (on)
import Data.Map (fromListWith, toAscList)
import Data.Set (fromList, toList)
-- given a list of elements, return pairs of the element with its frequency
-- if two elements have the same frequency, the elements are sorted in ascending order
getElemFreqs :: Ord a => [a] -> [(a, Int)]
getElemFreqs = sortBy (flip $ comparing snd) . toAscList . fromListWith (+) . (flip zip) (repeat 1)
part1 :: [(Int, Int)] -> Int
part1 coords =
let maxrow = fst $ maximumBy (comparing fst) coords
maxcol = snd $ maximumBy (comparing snd) coords
grid = map closest [(r, c) | r <- [1..maxrow], c <- [1..maxcol]]
edges = toList . fromList . map closest . concat $ [[(r, 1), (1, c), (r, maxcol), (maxrow, c)] | r <- [1..maxrow], c <- [1..maxcol]]
in snd . head . filter ((`notElem` edges) . fst) . getElemFreqs $ grid
where
closest coord =
let (car:cadr:_) = sortBy (comparing (manhattan coord)) coords
in if ((==) `on` manhattan coord) car cadr
then ((-1), (-1))
else car
manhattan (r1, c1) (r2, c2) = abs (r1 - r2) + abs (c1 - c2)
part2 :: [(Int, Int)] -> Int
part2 coords =
let maxrow = fst $ maximumBy (comparing fst) coords
maxcol = snd $ maximumBy (comparing snd) coords
in length . filter closeBy $ [(r, c) | r <- [1..maxrow], c <- [1..maxcol]]
where
closeBy coord = (sum $ map (manhattan coord) coords) < 10000
manhattan (r1, c1) (r2, c2) = abs (r1 - r2) + abs (c1 - c2)
main :: IO ()
main = do
input <- map (read . ('(':) . (++ [')'])) . lines <$> readFile "input/06.txt"
print $ part1 input
print $ part2 input