-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day06.hs
84 lines (64 loc) · 1.9 KB
/
Day06.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedRecordDot #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ViewPatterns #-}
module Day06 where
import Control.Arrow ((&&&))
import Control.Monad
import Data.Maybe
import Text.ParserCombinators.ReadP
import Harness
import ParseHelper
main :: IO ()
main = getInputAndSolve (parseInputRaw parseRaces) productOfWaysToWin withCorrectPaper
-- SOLVE
productOfWaysToWin :: Races -> Int
productOfWaysToWin =
product . map (length . findWins) . races
-- | This takes like 15seconds to run but I got a headache to good enough
withCorrectPaper :: Races -> Int
withCorrectPaper =
productOfWaysToWin . Races . fixRaces . (.races)
where
fixRaces :: [Race] -> [Race]
fixRaces races =
let (t, d) = unzip $ map ((.time) &&& (.distance)) races
in [Race (joinInts t) (joinInts d)]
joinInts :: [Int] -> Int
joinInts = read . concatMap show
-- HELPERS
findWins :: Race -> [Int]
findWins race =
mapMaybe isWin [0 .. race.time]
where
isWin :: Int -> Maybe Int
isWin holdTime =
let travelLength = holdTime * (race.time - holdTime)
in if travelLength > race.distance
then Just travelLength
else Nothing
-- PARSE
newtype Races = Races
{ races :: [Race]
}
deriving (Show)
data Race = Race
{ time :: Int
, distance :: Int
}
deriving (Show)
parseRaces :: ReadP Races
parseRaces = do
void $ string "Time:" <* many1 (char ' ')
times <- sepBy1 parseInt (many1 $ char ' ')
void newline
void $ string "Distance:" <* many1 (char ' ')
distances <- sepBy1 parseInt (many1 $ char ' ')
void newline
return . Races $ uncurry Race <$> zip times distances