Haskell
A nice dynamic programming problem in part 3.
import Control.Monad
import Data.List
import Data.List.Split
import Data.Map.Lazy qualified as Map
import Data.Maybe
readInput s =
let (names : _ : rules) = lines s
in (splitOn "," names, map readRule rules)
where
readRule s =
let [[c], post] = splitOn " > " s
in (c, map head $ splitOn "," post)
validBy rules name = all (`check` name) rules
where
check (c, cs) = all (`elem` cs) . following c
following c s =
do
(a : b : _) <- tails s
guard (a == c)
return b
part1 (names, rules) = fromJust $ find (validBy rules) names
part2 (names, rules) =
sum $ map fst $ filter (validBy rules . snd) $ zip [1 ..] names
part3 (names, rules) =
sum . map go . filter (validBy rules) $ dedup names
where
dedup xs =
filter (\x -> not $ any (\y -> x /= y && y `isPrefixOf` x) xs) xs
go n = count (length n) (last n)
gen 11 _ = 1
gen len c =
(if len >= 7 then (1 +) else id)
. maybe 0 (sum . map (count (len + 1)))
$ lookup c rules
count =
curry . (Map.!) . Map.fromList $
[ ((k, c), gen k c)
| k <- [1 .. 11],
c <- map fst rules ++ concatMap snd rules
]
main = do
readFile "everybody_codes_e2025_q07_p1.txt" >>= putStrLn . part1 . readInput
readFile "everybody_codes_e2025_q07_p2.txt" >>= print . part2 . readInput
readFile "everybody_codes_e2025_q07_p3.txt" >>= print . part3 . readInput