Day 03 - now with IntMap!
This commit is contained in:
parent
e296528b63
commit
6fa7a855ee
|
@ -10,7 +10,7 @@ To arrive at [⟨ortho|normal⟩](https://hilb.ert.space) as December comes.
|
||||||
|-----|-------------|------------|
|
|-----|-------------|------------|
|
||||||
| 01 | < 0.1 |
|
| 01 | < 0.1 |
|
||||||
| 02 | < 0.1 |
|
| 02 | < 0.1 |
|
||||||
| 03 | |
|
| 03 | ~ 2 |
|
||||||
| 04 | |
|
| 04 | |
|
||||||
| 05 | |
|
| 05 | |
|
||||||
| 06 | |
|
| 06 | |
|
||||||
|
|
31
src/Day03.hs
31
src/Day03.hs
|
@ -1,33 +1,24 @@
|
||||||
module Day03 (main) where
|
module Day03 (main) where
|
||||||
|
|
||||||
import Data.Text (split, pack, unpack)
|
import Data.Text (empty, split, pack, unpack)
|
||||||
|
import Data.IntMap (IntMap, fromListWith, size, notMember)
|
||||||
|
import qualified Data.IntMap as M (filter)
|
||||||
|
|
||||||
type Claim = (Int, Int, Int, Int, Int) -- id, left, top, width, height
|
type Claim = (Int, [Int])
|
||||||
(%) = mod
|
|
||||||
(//) = div
|
|
||||||
|
|
||||||
parse :: String -> Claim
|
parse :: String -> Claim
|
||||||
parse str =
|
parse str =
|
||||||
let i:l:t:w:h:[] = map (read . unpack) . tail . split (flip elem $ "#@,:x") . pack . filter (/= ' ') $ str
|
let i:l:t:w:h:[] = map (read . unpack) . filter (/= empty) . split (flip elem $ " #@,:x") . pack $ str
|
||||||
in (i, l, t, w, h)
|
in (i, [r * 1000 + c | r <- [t .. t + h - 1], c <- [l .. l + w - 1]])
|
||||||
|
|
||||||
doesClaim :: Int -> Claim -> Bool
|
overlapMap :: [Claim] -> IntMap Int
|
||||||
doesClaim cell (_, left, top, width, height) =
|
overlapMap = M.filter (> 1) . fromListWith (+) . (flip zip) (repeat 1) . concat . map snd
|
||||||
let row = cell // 1000
|
|
||||||
col = cell % 1000
|
|
||||||
in (row >= top) && (row < top + height) && (col >= left) && (col < left + width)
|
|
||||||
|
|
||||||
claimCount :: [Claim] -> Int -> Int
|
|
||||||
claimCount claims cell = length . filter (doesClaim cell) $ claims
|
|
||||||
|
|
||||||
part1 :: [Claim] -> Int
|
part1 :: [Claim] -> Int
|
||||||
part1 claims = length . filter id . map ((> 1) . claimCount claims) $ [0 .. 1000 * 1000 - 1]
|
part1 = size . overlapMap
|
||||||
|
|
||||||
part2 :: [Claim] -> Claim
|
part2 :: [Claim] -> Int
|
||||||
part2 claims = filterOverlaps 0 claims
|
part2 claims = fst . head . filter (all (flip notMember $ overlapMap claims) . snd) $ claims
|
||||||
where filterOverlaps cell acc =
|
|
||||||
let newAcc = if claimCount claims cell > 1 then filter (not . doesClaim cell) acc else acc
|
|
||||||
in if length newAcc == 1 then head newAcc else filterOverlaps (cell + 1) newAcc
|
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = do
|
main = do
|
||||||
|
|
Loading…
Reference in New Issue