

Haskell
Not particularly optimized but good enough.
import Control.Arrow ((***))
import Data.Array (assocs)
import Data.Function (on)
import Data.Graph
import Data.List
import Data.Map (Map)
import Data.Map qualified as Map
import Data.Maybe
readInput :: String -> Map Int [Char]
readInput = Map.fromList . map ((read *** tail) . break (== ':')) . lines
findRelations :: Map Int [Char] -> Graph
findRelations dna =
buildG (1, Map.size dna)
. concatMap (\(x, (y, z)) -> [(x, y), (x, z)])
. mapMaybe (\x -> (x,) <$> findParents x)
$ Map.keys dna
where
findParents x =
find (isChild x) $
[(y, z) | (y : zs) <- tails $ delete x $ Map.keys dna, z <- zs]
isChild x (y, z) =
all (\(a, b, c) -> a == b || a == c) $
zip3 (dna Map.! x) (dna Map.! y) (dna Map.! z)
scores :: Map Int [Char] -> Graph -> [Int]
scores dna relations =
[similarity x y * similarity x z | (x, [y, z]) <- assocs relations]
where
similarity i j =
length . filter (uncurry (==)) $ zip (dna Map.! i) (dna Map.! j)
part1, part2, part3 :: Map Int [Char] -> Int
part1 = sum . (scores <*> findRelations)
part2 = part1
part3 = sum . maximumBy (compare `on` length) . components . findRelations
main = do
readFile "everybody_codes_e2025_q09_p1.txt" >>= print . part1 . readInput
readFile "everybody_codes_e2025_q09_p2.txt" >>= print . part2 . readInput
readFile "everybody_codes_e2025_q09_p3.txt" >>= print . part3 . readInput




I mean… it can?
It’s pretty awesome, actually.