Files
adventofcode/2025/day07/solve.hs
Bert Peters be6c3d37ea Minor cleanup
Avoid repeatedly creating sets that live for almost no time, as well as
some readability fixes
2025-12-07 22:38:39 +01:00

66 lines
1.9 KiB
Haskell

import Data.Array
import Data.List
import Data.Maybe
import System.Environment
import System.Exit
main = getArgs >>= parse >>= run
stringToArray :: [Char] -> Array Int Char
stringToArray s = listArray (0, length s - 1) s
run :: String -> IO ()
run input =
let gridLines = lines input
startingPoint = findStartingPoint $ head gridLines
arrLines = Data.List.map stringToArray $ tail gridLines
in do
print $ part1 arrLines startingPoint
print $ part2 arrLines startingPoint
findStartingPoint :: [Char] -> Int
findStartingPoint line = fromJust $ elemIndex 'S' line
part1 arrLines startingPoint =
let initial = [startingPoint]
in simulate arrLines 0 initial
checkHit :: Array Int Char -> Int -> [Int]
checkHit line idx = case line ! idx of
'^' -> (idx - 1) : [idx + 1]
_ -> [idx]
simulate [] count active = count
simulate lines count active =
let arr = head lines
followUp = nub $ concatMap (checkHit arr) active
hits = length $ Data.List.filter (\i -> arr ! i == '^') active
remainder = tail lines
in simulate remainder (hits + count) followUp
part2 :: [Array Int Char] -> Int -> Int
part2 arrLines startingPosition =
let n = length arrLines
arr = listArray (0, n - 1) arrLines
width = length $ head arrLines
compute i pos
| i >= n = 1
| otherwise =
let line = arr ! i
in case line ! pos of
'^' -> memo ! (i + 1, pos - 1) + memo ! (i + 1, pos + 1)
_ -> memo ! (i + 1, pos)
memo =
array
((0, 0), (n, width - 1))
[((i, pos), compute i pos) | i <- [0 .. n], pos <- [0 .. width - 1]]
in memo ! (0, startingPosition)
parse ["-h"] = usage >> exitSuccess
parse [] = usage >> die usageStr
parse fs = concat `fmap` mapM readFile fs
usageStr = "Usage: solve [-vh] [file ..]"
usage = putStrLn usageStr