--- Writeup at https://work.njae.me.uk/2024/12/24/advent-of-code-2024-day-22/
+-- Writeup at https://work.njae.me.uk/2024/12/25/advent-of-code-2024-day-23/
+
import AoC
import Data.Text (Text)
print $ part1 graph
-- print $ getMaximalCliques graph
putStrLn $ part2 graph
-
-
- -- print $ part1 codes
- -- print $ part2 codes
--- part1, part2 :: [Int] -> Int
--- part1 codes = sum $ fmap (followingSecret 2000) codes
-
--- part1 :: Graph -> Int
+part1 :: Graph -> Int
part1 graph = length $ filter couldBeHistorian $ find3Cliques graph
--- part1 graph = find3Cliques graph
+
+part2 :: Graph -> String
part2 graph = intercalate "," $ sort maxClique
where maxClique = maximumBy (compare `on` length) $ getMaximalCliques graph
-
find3Cliques :: Graph -> [[Vertex]]
find3Cliques graph = filter isClique possibles
where possibles = tuples 3 $ M.keys graph
couldBeHistorian :: [Vertex] -> Bool
couldBeHistorian cliques = any ((== 't') . head) cliques
-
-- Implementation from https://www.cs.columbia.edu/~sedwards/classes/2023/4995-fall/reports/MaximalClique-report.pdf
getMaximalCliques :: Graph -> [Clique]
isConnected :: Graph -> Vertex -> Vertex -> Bool
isConnected graph a b = b `S.member` (graph M.! a)
-
mkGraph :: [Edge] -> Graph
mkGraph edges = M.fromListWith S.union $ fmap (\(Edge a b) -> (a, S.singleton b)) biEdges
where biEdges = edges ++ fmap (\(Edge a b) -> Edge b a) edges