Skip to content

Commit

Permalink
Day 23: Python
Browse files Browse the repository at this point in the history
Quite slow: Time (mean ± σ): 927.7 ms ± 3.8 ms
  • Loading branch information
edoardob90 committed Dec 24, 2024
1 parent 5729a46 commit 83c1323
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 0 deletions.
32 changes: 32 additions & 0 deletions 23/example.txt
Original file line number Diff line number Diff line change
@@ -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
69 changes: 69 additions & 0 deletions 23/python/solution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/usr/bin/env python3
"""AoC day 23, 2024: LAN Party"""

import pathlib
import sys
from collections import defaultdict


def parse_data(puzzle_input: str) -> dict[str, set]:
"""Parse input data"""
graph = defaultdict(set)
edges = [line.strip().split("-") for line in puzzle_input.splitlines()]

for x, y in edges:
graph[x].add(y)
graph[y].add(x)

return graph


def part1(graph: dict[str, set]) -> int:
"""Solve part 1"""
sets = set()

for x in graph:
for y in graph[x]:
for z in graph[y]:
if z != x and x in graph[z]:
sets.add((tuple(sorted([x, y, z]))))

return len([s for s in sets if any(n.startswith("t") for n in s)])


def part2(graph: dict[str, set]) -> str:
"""Solve part 2"""
sets = set()

def search(node: str, required: set):
key = tuple(sorted(required))
if key in sets:
return

sets.add(key)

for neighbor in graph[node]:
if neighbor in required:
continue
if not required <= graph[neighbor]:
continue

search(neighbor, {*required, neighbor})

for node in graph:
search(node, {node})

return ",".join(sorted(max(sets, key=len)))


def solve(puzzle_input: str) -> tuple[int, str]:
"""Solve the puzzle for the given input"""
data = parse_data(puzzle_input)
return part1(data), part2(data)


if __name__ == "__main__":
for path in sys.argv[1:]:
print(f"\n{path}:")
solutions = solve(pathlib.Path(path).read_text().strip())
print("\n".join(str(solution) for solution in solutions))
33 changes: 33 additions & 0 deletions 23/python/test_solution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env python3
"""Tests for AoC day 23, 2024: LAN Party"""

from pathlib import Path

import pytest

from solution import parse_data, part1, part2


@pytest.fixture
def example_data() -> str:
current_dir = Path(__file__).parent
filename = current_dir.parent / "example.txt"
try:
return filename.read_text().strip()
except FileNotFoundError:
raise FileNotFoundError(f"Example input file not found at {filename}")


def test_parse(example_data: str) -> None:
data = parse_data(example_data)
assert len(data) > 0


def test_part1(example_data: str) -> None:
data = parse_data(example_data)
assert part1(data) == 7


def test_part2(example_data: str) -> None:
data = parse_data(example_data)
assert part2(data) == "co,de,ka,ta"

0 comments on commit 83c1323

Please # to comment.