Skip to content

Commit

Permalink
day12: python
Browse files Browse the repository at this point in the history
Honestly, I was stunned when my part1 worked first time.

Part 2 was harder because I'm an idiot and had a bug that kept causing recursion errors.

Reckon I'll do a refactor to combine the two parts and memoise, since part 2 took rather long
  • Loading branch information
oatzy committed Dec 12, 2021
1 parent 1e7ee42 commit 98bd593
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 0 deletions.
99 changes: 99 additions & 0 deletions day12/day12.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
from collections import Counter, defaultdict


def load_data(path):
graph = defaultdict(list)

with open(path, 'r') as f:
for line in f:

a, b = line.strip().split('-')

if a == 'start':
graph['START'].append(b)
elif b == 'start':
graph['START'].append(a)

elif b == 'end':
graph[a].append('END')
elif a == 'end':
graph[b].append('END')

else:
graph[a].append(b)
graph[b].append(a)

return graph


def count_paths(graph, node, visited):
if node == 'END':
return 1

neighbours = [
n for n in graph[node]
if n.isupper() or n not in visited
]

paths = 0
for n in neighbours:
paths += count_paths(graph, n, {n, *visited})

return paths


def part1(graph):
return count_paths(graph, 'START', set())


def count_paths_with_revisit(graph, node, visited):
if node == 'END':
return 1

can_revisit = not any(v == 2 for v in visited.values())

paths = 0
for n in graph[node]:
if n.isupper():
paths += count_paths_with_revisit(graph, n, visited)
elif visited[n] == 0 or can_revisit:
v = visited.copy()
v[n] += 1
paths += count_paths_with_revisit(graph, n, v)

return paths


def part2(graph):
return count_paths_with_revisit(graph, 'START', Counter())


def main():
data = load_data('input.txt')
print(part1(data))
print(part2(data))


if __name__ == '__main__':
main()


class Test:

def test_part1_small(self):
assert part1(load_data('test.txt')) == 10

def test_part1_medium(self):
assert part1(load_data('test1.txt')) == 19

def test_part1_large(self):
assert part1(load_data('test2.txt')) == 226

def test_part2_small(self):
assert part2(load_data('test.txt')) == 36

def test_part2_medium(self):
assert part2(load_data('test1.txt')) == 103

def test_part2_large(self):
assert part2(load_data('test2.txt')) == 3509
24 changes: 24 additions & 0 deletions day12/input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
by-TW
start-TW
fw-end
QZ-end
JH-by
ka-start
ka-by
end-JH
QZ-cv
vg-TI
by-fw
QZ-by
JH-ka
JH-vg
vg-fw
TW-cv
QZ-vg
ka-TW
ka-QZ
JH-fw
vg-hu
cv-start
by-cv
ka-cv
7 changes: 7 additions & 0 deletions day12/test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
start-A
start-b
A-c
A-b
b-d
A-end
b-end
10 changes: 10 additions & 0 deletions day12/test1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
dc-end
HN-start
start-kj
dc-start
dc-HN
LN-dc
HN-end
kj-sa
kj-HN
kj-dc
18 changes: 18 additions & 0 deletions day12/test2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
fs-end
he-DX
fs-he
start-DX
pj-DX
end-zg
zg-sl
zg-pj
pj-he
RW-he
fs-DX
pj-RW
zg-RW
start-pj
he-WI
zg-he
pj-fs
start-RW

0 comments on commit 98bd593

Please sign in to comment.