[haskell] Solve day 6
This commit is contained in:
parent
d6f9b4dae3
commit
a79cc27359
|
@ -25,6 +25,7 @@ library
|
|||
, Day3
|
||||
, Day4
|
||||
, Day5
|
||||
, Day6
|
||||
|
||||
executable aoc2023
|
||||
import: warnings
|
||||
|
|
|
@ -4,10 +4,11 @@ module Main where
|
|||
|
||||
import Day1 qualified
|
||||
import Day2 qualified
|
||||
import Day3 qualified
|
||||
import Day4 qualified
|
||||
import Day5 qualified
|
||||
import Day6 qualified
|
||||
import System.Environment (getArgs)
|
||||
import qualified Day3
|
||||
import qualified Day4
|
||||
import qualified Day5
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
|
@ -17,4 +18,5 @@ main = do
|
|||
["day3"] -> Day3.run
|
||||
["day4"] -> Day4.run
|
||||
["day5"] -> Day5.run
|
||||
["day6"] -> Day6.run
|
||||
args -> error $ "Invlaid args: " <> show args
|
||||
|
|
99
haskell/src/Day6.hs
Normal file
99
haskell/src/Day6.hs
Normal file
|
@ -0,0 +1,99 @@
|
|||
module Day6 where
|
||||
|
||||
import Data.Char
|
||||
import Text.ParserCombinators.ReadP
|
||||
|
||||
run :: IO ()
|
||||
run = do
|
||||
(records, record) <- readInput
|
||||
putStrLn $ "Part 1 Answer: " <> show (part1 records)
|
||||
putStrLn $ "Part 2 Answer: " <> show (part2 record)
|
||||
|
||||
part1 :: [Record] -> Int
|
||||
part1 =
|
||||
product . map (uncurry waysOfWinning)
|
||||
|
||||
part2 :: Record -> Int
|
||||
part2 = uncurry waysOfWinning
|
||||
|
||||
-- | There is definitely a better way for doing this. But this runs in less than
|
||||
-- a second.
|
||||
waysOfWinning :: Time -> Distance -> Int
|
||||
waysOfWinning time recordDistance =
|
||||
length $ filter (> recordDistance) $ productsOfAdders time
|
||||
|
||||
-- | Finds products of all adders
|
||||
--
|
||||
-- >>> productsOfAdders 7
|
||||
-- [0,6,10,12,12,10,6,0]
|
||||
--
|
||||
-- >>> productsOfAdders 30
|
||||
-- [0,29,56,81,104,125,144,161,176,189,200,209,216,221,224,225,224,221,216,209,200,189,176,161,144,125,104,81,56,29,0]
|
||||
productsOfAdders :: Int -> [Int]
|
||||
productsOfAdders = map (uncurry (*)) . adders
|
||||
|
||||
-- | Postitive integers which add up to the given integer
|
||||
--
|
||||
-- >>> adders 7
|
||||
-- [(0,7),(1,6),(2,5),(3,4),(4,3),(5,2),(6,1),(7,0)]
|
||||
--
|
||||
-- >>> adders 8
|
||||
-- [(0,8),(1,7),(2,6),(3,5),(4,4),(5,3),(6,2),(7,1),(8,0)]
|
||||
adders :: Int -> [(Int, Int)]
|
||||
adders n = map (\x -> (x, n - x)) [0 .. n]
|
||||
|
||||
type Time = Int
|
||||
|
||||
type Distance = Int
|
||||
|
||||
type Race = (Time, Distance)
|
||||
|
||||
type Record = (Time, Distance)
|
||||
|
||||
readInput :: IO ([Record], Record)
|
||||
readInput = do
|
||||
input <- getContents
|
||||
let parseWith p = case readP_to_S p input of
|
||||
[] -> error "Parser failed"
|
||||
[(parsed, "")] -> parsed
|
||||
xs -> error $ "Parser failed: " <> show xs
|
||||
pure (parseWith recordsParser, parseWith betterRecordParser)
|
||||
|
||||
numberParser :: ReadP Int
|
||||
numberParser =
|
||||
read <$> munch1 isDigit
|
||||
|
||||
timesParser :: ReadP [Time]
|
||||
timesParser = do
|
||||
_ <- string "Time: "
|
||||
_ <- skipSpaces
|
||||
sepBy1 numberParser skipSpaces
|
||||
|
||||
distancesParser :: ReadP [Distance]
|
||||
distancesParser = do
|
||||
_ <- string "Distance: "
|
||||
_ <- skipSpaces
|
||||
sepBy1 numberParser skipSpaces
|
||||
|
||||
recordsParser :: ReadP [Record]
|
||||
recordsParser = do
|
||||
times <- timesParser
|
||||
_ <- char '\n'
|
||||
distances <- distancesParser
|
||||
eof
|
||||
pure $ zip times distances
|
||||
|
||||
betterNumberParser :: ReadP Int
|
||||
betterNumberParser =
|
||||
read . filter (/= ' ') <$> munch1 (\c -> c == ' ' || isDigit c)
|
||||
|
||||
betterRecordParser :: ReadP (Time, Distance)
|
||||
betterRecordParser = do
|
||||
_ <- string "Time: "
|
||||
skipSpaces
|
||||
t <- betterNumberParser
|
||||
_ <- string "\nDistance: "
|
||||
skipSpaces
|
||||
d <- betterNumberParser
|
||||
eof
|
||||
pure (t, d)
|
2
input/day6
Normal file
2
input/day6
Normal file
|
@ -0,0 +1,2 @@
|
|||
Time: 62 73 75 65
|
||||
Distance: 644 1023 1240 1023
|
2
input/day6-eg
Normal file
2
input/day6-eg
Normal file
|
@ -0,0 +1,2 @@
|
|||
Time: 7 15 30
|
||||
Distance: 9 40 200
|
Loading…
Reference in a new issue