day 11, 12 + folder refactoring

This commit is contained in:
Matthieu Bessat 2021-12-13 10:08:40 +01:00
parent d9f6c01f2b
commit 06a5771fbf
78 changed files with 1242 additions and 8 deletions

74
12_day/code.py Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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)}")