2024: d23: ex2: add solution

This commit is contained in:
Bruno BELANYI 2024-12-23 00:31:17 -05:00
parent bc3e81ad4b
commit 0f6051d939

57
2024/d23/ex2/ex2.py Executable file
View file

@ -0,0 +1,57 @@
#!/usr/bin/env python
import sys
from collections import defaultdict
from collections.abc import Iterator
def solve(input: str) -> str:
def parse_line(input: str) -> tuple[str, str]:
lhs, rhs = input.split("-")
return lhs, rhs
def parse(input: list[str]) -> list[tuple[str, str]]:
return [parse_line(line) for line in input]
def links_to_graph(topology: list[tuple[str, str]]) -> dict[str, set[str]]:
graph: dict[str, set[str]] = defaultdict(set)
for lhs, rhs in topology:
graph[lhs].add(rhs)
graph[rhs].add(lhs)
return graph
# Maximum clique solution thanks to [1]
# [1]: https://en.wikipedia.org/wiki/Bron%E2%80%93Kerbosch_algorithm
def bron_kerbosch(graph: dict[str, set[str]]) -> Iterator[set[str]]:
def helper(
clique: set[str],
candidates: set[str],
discarded: set[str],
) -> Iterator[set[str]]:
if not candidates and not discarded:
yield clique
while candidates:
v = candidates.pop()
yield from helper(
clique | {v},
candidates & graph[v],
discarded & graph[v],
)
discarded.add(v)
return helper(set(), set(graph.keys()), set())
topology = parse(input.splitlines())
graph = links_to_graph(topology)
cliques = bron_kerbosch(graph)
historian_group = max(cliques, key=len) # MyPy doesn't like it inline in `sorted`
return ",".join(sorted(historian_group))
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()