import Control.Monad import Data.List import qualified Data.Map.Strict as Map type Inventory = Map.Map Int [Int] findbridges :: Int -> Inventory -> [[(Int, Int)]] findbridges start inven = case Map.lookup start inven of Nothing -> [[]] Just nexts -> concatMap (\n -> map ((start, n) :) $ findbridges n (delpair start n $ delpair n start inven)) $ nub nexts where delpair :: Int -> Int -> Inventory -> Inventory delpair a b = Map.update (\l -> let l' = l \\ [b] in if null l' then Nothing else Just l') a . Map.update (\l -> let l' = l \\ [a] in if null l' then Nothing else Just l') b strength :: [(Int, Int)] -> Int strength = sum . map (uncurry (+)) parse :: String -> (Int, Int) parse str = let Just idx = findIndex (== '/') str in (read $ take idx str, read $ drop (succ idx) str) main :: IO () main = do input <- liftM (map parse . lines) (readFile "24.in") let mp = foldl (\m (a,b) -> Map.insertWith (++) b [a] $ Map.insertWith (++) a [b] m) Map.empty input br = findbridges 0 mp print $ maximum (map strength br) let maxlen = maximum (map length br) print $ maximum $ map strength $ filter ((== maxlen) . length) br