Advent of Code 2023 day 06

    Day 6 was much easier than the other days, almost to the extent that I initially confused myself. It's also continuting the trend that reading and parsing the input data is almost the hardest part.

    I started by defining a data type for a Race. I think even this was excessive for this problem; a tuple would have done.

    data Race = Race Int Int deriving (Eq, Show)

    Parsing

    One little wrinkle was walking along two lines in parallel to generate the races. But as there were only two lines, they were easy enough to combine with zipWith.

    racesP = zipWith Race <$> (timesP <* endOfLine) <*> distancesP
    timesP = ("Time:" *> skipSpace) *> numbersP
    distancesP = ("Distance:" *> skipSpace) *> numbersP
    numbersP = decimal `sepBy` skipSpace

    Part 1

    This was almost as simple as "write down the problem statement": for each possible hold time, calculate the distance, check if it's over the current record distance, count how many you have. Do that for all the races, multiply them.

    part1 :: [Race] -> Int     
    part1 = product . fmap waysToWin
    
    waysToWin :: Race -> Int
    waysToWin (Race timeLimit record) = 
      length $ filter (> record) [(timeLimit - h) * h | h <- [1..timeLimit]]

    Part 2

    If the problem for part 2 is "read the input but without the spaces", how about I … read the input but without the spaces?

    let races1 = successfulParse text
    let races2 = successfulParse $ T.filter (/= ' ') text

    That works.

    Code

    You can get the code from my locally-hosted Git repo, or from Gitlab.

    Neil Smith

    Read more posts by this author.