From 4af72e57b8d6f4244fbb898054d1988752a685ce Mon Sep 17 00:00:00 2001 From: Steve Dunham Date: Mon, 23 Dec 2024 08:57:38 -0800 Subject: [PATCH] day23 --- aoc2024/Day23.newt | 96 +++++++++++++++++++++++++++ aoc2024/day23/eg.txt | 32 +++++++++ playground/samples/aoc2024/Day23.newt | 1 + playground/samples/aoc2024/day23 | 1 + 4 files changed, 130 insertions(+) create mode 100644 aoc2024/Day23.newt create mode 100644 aoc2024/day23/eg.txt create mode 120000 playground/samples/aoc2024/Day23.newt create mode 120000 playground/samples/aoc2024/day23 diff --git a/aoc2024/Day23.newt b/aoc2024/Day23.newt new file mode 100644 index 0000000..4c8dbdb --- /dev/null +++ b/aoc2024/Day23.newt @@ -0,0 +1,96 @@ +module Day23 + +import Prelude +import Node +import Aoc +import SortedMap + +Graph Edge EdgeSet VSet : U +Graph = SortedMap String (List String) +Edge = String × String +EdgeSet = SortedMap Edge Unit +VSet = SortedMap String Unit + +addEdge : Graph -> String × String -> Graph +addEdge g (a,b) = updateMap a (b :: fromMaybe Nil (snd <$> lookupMap a g)) g + +ppair : String → Maybe Edge +ppair s = case split s "-" of + (a :: b :: Nil) => Just (a, b) + _ => Nothing + +pfile : String → Maybe (List Edge) +pfile text = traverse ppair $ split (trim text) "\n" + +startT : String → Bool +startT s = case unpack s of + ('t' :: _) => True + _ => False + +isJust : ∀ a. Maybe a → Bool +isJust (Just x) = True +isJust _ = False + +checkK3 : Graph → EdgeSet → Edge → Int +checkK3 g es (a,b) = + let cand = fromMaybe Nil $ snd <$> lookupMap b g + cand = if startT a || startT b then cand else filter startT cand + in cast $ length $ filter (\c => isJust $ lookupMap (c,a) es) cand + +isect : List String → List String → List String +isect as bs = filter (flip elem bs) as + +remove : String → List String → List String +remove s Nil = Nil +remove s (x :: xs) = if x == s then xs else x :: remove s xs + +bronKerbosch : Graph → List String → List String → List String → Maybe (List String) +bronKerbosch g rs Nil Nil = Just rs +bronKerbosch g rs Nil xs = Nothing +bronKerbosch g rs (p :: ps) xs = + let np = neighbors p + ps' = p :: filter (\x => not (elem x np)) ps in + foldl best Nothing $ map check ps' + where + neighbors : String → List String + neighbors p = fromMaybe Nil $ snd <$> lookupMap p g + + check : String → Maybe (List String) + check p = let nv = neighbors p in + bronKerbosch g (p :: rs) (isect ps nv) (isect xs nv) + + best : Maybe (List String) → Maybe (List String) → Maybe (List String) + best Nothing Nothing = Nothing + best Nothing a = a + best a Nothing = a + best (Just a) (Just b) = if length a < length b then Just b else Just a + +joinBy : String → List String → String +joinBy _ Nil = "" +joinBy _ (x :: Nil) = x +joinBy s (x :: y :: xs) = joinBy s ((x ++ s ++ y) :: xs) + +run : String -> IO Unit +run fn = do + putStrLn fn + text <- readFile fn + let (Just pairs) = pfile text | _ => putStrLn "parse error" + let dpairs = pairs ++ map swap pairs + let g = foldl addEdge EmptyMap dpairs + let es = foldl (\g e => updateMap e MkUnit g) EmptyMap dpairs + putStrLn $ show (length pairs) ++ " pairs" + putStrLn $ show (length dpairs) ++ " dpairs" + + -- one direction, counting each K3 3 times + let p1 = (foldl _+_ 0 $ map (checkK3 g es) pairs) / 3 + putStrLn $ "part1 " ++ show p1 + let verts = map fst $ toList g + let (Just result) = bronKerbosch g Nil verts Nil | _ => putStrLn "fail" + let p2 = joinBy "," $ qsort _<_ result + + putStrLn $ "part2 " ++ p2 + +main : IO Unit +main = do + run "aoc2024/day23/eg.txt" + run "aoc2024/day23/input.txt" diff --git a/aoc2024/day23/eg.txt b/aoc2024/day23/eg.txt new file mode 100644 index 0000000..3d49766 --- /dev/null +++ b/aoc2024/day23/eg.txt @@ -0,0 +1,32 @@ +kh-tc +qp-kh +de-cg +ka-co +yn-aq +qp-ub +cg-tb +vc-aq +tb-ka +wh-tc +yn-cg +kh-ub +ta-co +de-co +tc-td +tb-wq +wh-td +ta-ka +td-qp +aq-cg +wq-ub +ub-vc +de-ta +wq-aq +wq-vc +wh-yn +ka-de +kh-ta +co-tc +wh-qp +tb-vc +td-yn diff --git a/playground/samples/aoc2024/Day23.newt b/playground/samples/aoc2024/Day23.newt new file mode 120000 index 0000000..d234e7f --- /dev/null +++ b/playground/samples/aoc2024/Day23.newt @@ -0,0 +1 @@ +../../../aoc2024/Day23.newt \ No newline at end of file diff --git a/playground/samples/aoc2024/day23 b/playground/samples/aoc2024/day23 new file mode 120000 index 0000000..e777259 --- /dev/null +++ b/playground/samples/aoc2024/day23 @@ -0,0 +1 @@ +../../../aoc2024/day23 \ No newline at end of file