42 lines
1.7 KiB
Haskell
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 |