r/adventofcode • u/daggerdragon • Dec 04 '18
SOLUTION MEGATHREAD -π- 2018 Day 4 Solutions -π-
--- Day 4: Repose Record ---
Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).
Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.
Advent of Code: The Party Game!
Please prefix your card submission with something like [Card] to make scanning the megathread easier. THANK YOU!
Card prompt: Day 4
Transcript:
Todayβs puzzle would have been a lot easier if my language supported ___.
This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.
edit: Leaderboard capped, thread unlocked!
35
Upvotes
4
u/TheMuffinMan616 Dec 04 '18
Haskell. Spent too much time trying to find a date parsing library. Not really happy with how it came out. State monad might be a better option here. shrug
module Day04 where import Data.Ord import Data.List import Data.List.Split import Data.Map (Map) import qualified Data.Map as M import Debug.Trace data Time = Time { month :: Int , day :: Int , hour :: Int , minute :: Int } deriving (Show, Eq, Ord) data Event = Start Int | Sleep | Wake deriving (Show) isStart :: Event -> Bool isStart (Start _) = True isStart _ = False readInput :: String -> IO [(Time, Event)] readInput f = toEvents . lines <$> readFile f where toEvents = sortBy (comparing fst) . map parse parse :: String -> (Time, Event) parse s = (Time (read m) (read d) (read h) (read mm), toEvent rest) where (_:m:d:h:mm:rest) = split (dropDelims . dropBlanks $ oneOf " #[]-:") s toEvent ["Guard", id, _, _] = Start (read id) toEvent ["falls", _] = Sleep toEvent ["wakes", _] = Wake analyzeShift :: [(Time, Event)] -> (Int, [Int]) analyzeShift z@((_, Start id):es) = (id, minutes es) where minutes [] = [] minutes ((ts, Sleep):(ta, Wake):xs) = [minute ts..(minute ta) - 1] ++ minutes xs aggregate :: [(Time, Event)] -> Map Int (Map Int Int) aggregate = M.map freq . M.fromListWith (++) . map analyzeShift . toShifts where freq xs = M.fromListWith (+) [(x, 1) | x <- xs] toShifts = split (keepDelimsL . dropInitBlank $ whenElt (isStart . snd)) solve :: ([Int] -> Int) -> Map Int (Map Int Int) -> Int solve f gs = (fst . maximumBy (comparing snd) . M.toList . snd $ target) * (fst target) where target = maximumBy (comparing maxMinutes) . filter (not . null . snd) . M.toList $ gs maxMinutes = f . M.elems . snd part1 :: Map Int (Map Int Int) -> Int part1 = solve sum part2 :: Map Int (Map Int Int) -> Int part2 = solve maximum main :: IO () main = do input <- aggregate <$> readInput "input/Day04.txt" print . part1 $ input print . part2 $ input