day 11, 12 + folder refactoring
This commit is contained in:
parent
d9f6c01f2b
commit
06a5771fbf
78 changed files with 1242 additions and 8 deletions
74
12_day/code.py
Normal file
74
12_day/code.py
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
import pprint
|
||||
import itertools
|
||||
import fileinput
|
||||
|
||||
nodes = []
|
||||
edges = []
|
||||
for raw in fileinput.input():
|
||||
line = raw.strip()
|
||||
if line == '': continue
|
||||
[a,b] = line.split('-')
|
||||
nodes += [a, b]
|
||||
edges.append((a, b))
|
||||
|
||||
nodes = list(set(nodes))
|
||||
nodes.sort()
|
||||
|
||||
graph = [[0 for j in range(len(nodes))] for i in range(len(nodes))]
|
||||
|
||||
#pprint.pprint(graph)
|
||||
|
||||
for (a,b) in edges:
|
||||
i, j = nodes.index(a), nodes.index(b)
|
||||
graph[i][j] = 1
|
||||
graph[j][i] = 1
|
||||
|
||||
visit_only_once = [e for e in nodes if e.lower() == e and e != 'start' and e != 'end']
|
||||
|
||||
start_index = nodes.index('start')
|
||||
end_index = nodes.index('end')
|
||||
|
||||
nodes_d = [(i,e) for i,e in enumerate(nodes)]
|
||||
|
||||
print(f'{nodes_d=}')
|
||||
print(f'{visit_only_once=}')
|
||||
|
||||
visit_only_once_index = [nodes.index(e) for e in visit_only_once]+[start_index, end_index]
|
||||
|
||||
def explore_path(stack, level, locked, s, did_visit_twice):
|
||||
edges = [i for i,e in enumerate(graph[s]) if e]
|
||||
|
||||
if s == end_index:
|
||||
return [s] + [stack]
|
||||
|
||||
paths = []
|
||||
for edge in edges:
|
||||
if edge == start_index: continue
|
||||
|
||||
if edge in visit_only_once_index:
|
||||
if edge in locked:
|
||||
if not did_visit_twice and edge != start_index and edge != end_index:
|
||||
did_visit_twice = True
|
||||
else:
|
||||
continue
|
||||
locked.add(edge)
|
||||
|
||||
#print(f'{level=} , {nodes[edge]=}, {new_locked=}, {at_most=} ')
|
||||
paths += explore_path([s]+stack, level+1, locked.copy(), edge, did_visit_twice)
|
||||
return paths
|
||||
|
||||
print('start exploring...')
|
||||
|
||||
paths = explore_path([], 0, set(), start_index, False)
|
||||
|
||||
all_paths = [ ''.join(map(str, p)) for p in paths ]
|
||||
|
||||
res = list(set(all_paths))
|
||||
|
||||
for p in res:
|
||||
new_p = list(map(int, list(p)))
|
||||
#print([ nodes[i] for i in list(reversed(new_p))])
|
||||
|
||||
#print(res)
|
||||
|
||||
print(f'There are {len(res)} paths')
|
||||
61
12_day/code_part_1.py
Normal file
61
12_day/code_part_1.py
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
import pprint
|
||||
import itertools
|
||||
import fileinput
|
||||
|
||||
nodes = []
|
||||
edges = []
|
||||
for raw in fileinput.input():
|
||||
line = raw.strip()
|
||||
if line == '': continue
|
||||
[a,b] = line.split('-')
|
||||
nodes += [a, b]
|
||||
edges.append((a, b))
|
||||
|
||||
nodes = list(set(nodes))
|
||||
nodes.sort()
|
||||
|
||||
graph = [[0 for j in range(len(nodes))] for i in range(len(nodes))]
|
||||
|
||||
#pprint.pprint(graph)
|
||||
|
||||
for (a,b) in edges:
|
||||
i, j = nodes.index(a), nodes.index(b)
|
||||
graph[i][j] = 1
|
||||
graph[j][i] = 1
|
||||
|
||||
visit_only_once = [e for e in nodes if e.lower() == e and e != 'start' and e != 'end']
|
||||
|
||||
start_index = nodes.index('start')
|
||||
end_index = nodes.index('end')
|
||||
|
||||
print(f'{visit_only_once=}')
|
||||
|
||||
visit_only_once_index = [nodes.index(e) for e in visit_only_once]
|
||||
|
||||
possibles = []
|
||||
|
||||
def explore_path(stack, level, locked, s):
|
||||
edges = [i for i,e in enumerate(graph[s]) if e]
|
||||
|
||||
if s == end_index:
|
||||
possibles.append(stack)
|
||||
return
|
||||
|
||||
for edge in edges:
|
||||
new_locked = locked.copy()
|
||||
if edge in locked: continue
|
||||
if edge == start_index: continue
|
||||
if edge in visit_only_once_index:
|
||||
new_locked += [edge]
|
||||
|
||||
#print(f'{level=} , {nodes[edge]=}, {new_locked=}')
|
||||
explore_path([s]+stack, level+1, new_locked, edge)
|
||||
|
||||
print('start exploring...')
|
||||
|
||||
explore_path([], 0, [], start_index)
|
||||
|
||||
for p in possibles:
|
||||
print([ nodes[i] for i in list(reversed(p))])
|
||||
|
||||
print(f'There are {len(possibles)} paths')
|
||||
7
12_day/example1.txt
Normal file
7
12_day/example1.txt
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
start-A
|
||||
start-b
|
||||
A-c
|
||||
A-b
|
||||
b-d
|
||||
A-end
|
||||
b-end
|
||||
10
12_day/example2.txt
Normal file
10
12_day/example2.txt
Normal file
|
|
@ -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
12_day/example3.txt
Normal file
18
12_day/example3.txt
Normal file
|
|
@ -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
|
||||
24
12_day/input.txt
Normal file
24
12_day/input.txt
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
yb-pi
|
||||
jg-ej
|
||||
yb-KN
|
||||
LD-start
|
||||
end-UF
|
||||
UF-yb
|
||||
yb-xd
|
||||
qx-yb
|
||||
xd-end
|
||||
jg-KN
|
||||
start-qx
|
||||
start-ej
|
||||
qx-LD
|
||||
jg-LD
|
||||
xd-LD
|
||||
ej-qx
|
||||
end-KN
|
||||
DM-xd
|
||||
jg-yb
|
||||
ej-LD
|
||||
qx-UF
|
||||
UF-jg
|
||||
qx-jg
|
||||
xd-UF
|
||||
80
12_day/wow1.py
Normal file
80
12_day/wow1.py
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
import fileinput
|
||||
|
||||
def read_file():
|
||||
return [line.strip() for line in fileinput.input()]
|
||||
|
||||
def make_graph(lines):
|
||||
graph = {}
|
||||
small_caves = set()
|
||||
for line in lines:
|
||||
a, b = line.split('-')
|
||||
add_path(graph, a, b)
|
||||
add_path(graph, b, a)
|
||||
if a.islower():
|
||||
small_caves.add(a)
|
||||
if b.islower():
|
||||
small_caves.add(b)
|
||||
return graph, small_caves
|
||||
|
||||
|
||||
def add_path(graph, a, b):
|
||||
nodes = graph.get(a)
|
||||
if nodes == None:
|
||||
graph[a] = [b]
|
||||
else:
|
||||
nodes.append(b)
|
||||
|
||||
|
||||
def find_paths(graph,
|
||||
small_caves,
|
||||
can_visit_twice,
|
||||
current,
|
||||
end,
|
||||
path,
|
||||
small_visited,
|
||||
did_visit_twice=False):
|
||||
|
||||
if current in small_caves:
|
||||
if current in small_visited:
|
||||
if can_visit_twice and not did_visit_twice and current != 'start' and current != 'end':
|
||||
did_visit_twice = True
|
||||
else:
|
||||
return None
|
||||
small_visited.add(current)
|
||||
|
||||
path.append(current)
|
||||
|
||||
if current == end:
|
||||
return [path]
|
||||
|
||||
paths = []
|
||||
connected = graph[current]
|
||||
for cave in connected:
|
||||
subpaths = find_paths(graph, small_caves, can_visit_twice, cave, end,
|
||||
path.copy(), small_visited.copy(), did_visit_twice)
|
||||
if subpaths != None:
|
||||
paths.extend(subpaths)
|
||||
|
||||
return paths
|
||||
|
||||
|
||||
def print_graph(graph):
|
||||
for key, value in graph.items():
|
||||
for cave in value:
|
||||
print(f"{key} -> {cave}")
|
||||
|
||||
|
||||
def print_paths(paths):
|
||||
for path in paths:
|
||||
print(','.join(path))
|
||||
|
||||
|
||||
input = read_file()
|
||||
graph, small_caves = make_graph(input)
|
||||
|
||||
paths = find_paths(graph, small_caves, False, 'start', 'end', [], set())
|
||||
print(f"Part 1: {len(paths)}")
|
||||
|
||||
paths = find_paths(graph, small_caves, True, 'start', 'end', [], set())
|
||||
print(f"Part 2: {len(paths)}")
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue