-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Quite slow: Time (mean ± σ): 927.7 ms ± 3.8 ms
- Loading branch information
1 parent
5729a46
commit 83c1323
Showing
3 changed files
with
134 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" |