Add 2022
This commit is contained in:
parent
44d067f79c
commit
94d71c9071
91
2022/day13.py
Executable file
91
2022/day13.py
Executable file
@ -0,0 +1,91 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
"""
|
||||||
|
Jour 13 du défi Advent Of Code pour l'année 2022
|
||||||
|
"""
|
||||||
|
import functools
|
||||||
|
|
||||||
|
def read_sample():
|
||||||
|
"""récupère les entrées depuis le fichier texte correspondant"""
|
||||||
|
with open('inputs/day13.txt', 'r') as f:
|
||||||
|
sample = f.read().split('\n\n')
|
||||||
|
sample = [ [eval(j) for j in i.split('\n') if j != ''] for i in sample if i != '' ]
|
||||||
|
return sample
|
||||||
|
|
||||||
|
def is_right_order(elem1, elem2):
|
||||||
|
if type(elem1) == type(0) and type(elem2) == type(0): # two ints
|
||||||
|
if elem1 == elem2:
|
||||||
|
return None
|
||||||
|
return elem1 < elem2
|
||||||
|
|
||||||
|
if type(elem1) == type([]) and type(elem2) == type([]): # two lists
|
||||||
|
if len(elem1) == 0:
|
||||||
|
return True
|
||||||
|
|
||||||
|
for i in range(len(elem1)):
|
||||||
|
if i > len(elem2)-1:
|
||||||
|
return False # Out
|
||||||
|
|
||||||
|
order = is_right_order(elem1[i], elem2[i])
|
||||||
|
if order is not None:
|
||||||
|
return order
|
||||||
|
|
||||||
|
return is_right_order(len(elem1), len(elem2))
|
||||||
|
|
||||||
|
if type(elem1) == type(0) and type(elem2) == type([]):
|
||||||
|
return is_right_order([elem1], elem2)
|
||||||
|
|
||||||
|
if type(elem2) == type(0) and type(elem1) == type([]):
|
||||||
|
return is_right_order(elem1, [elem2])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def part1(sample):
|
||||||
|
"""Partie 1 du défi"""
|
||||||
|
somme = 0
|
||||||
|
for i in range(len(sample)):
|
||||||
|
order = is_right_order(sample[i][0], sample[i][1])
|
||||||
|
if order is None:
|
||||||
|
order = True
|
||||||
|
if order:
|
||||||
|
somme += i+1
|
||||||
|
return somme
|
||||||
|
|
||||||
|
def part2(sample):
|
||||||
|
"""Partie 2 du défi"""
|
||||||
|
n_sample = []
|
||||||
|
for i in sample:
|
||||||
|
for j in i:
|
||||||
|
n_sample.append(j)
|
||||||
|
n_sample.append([[2]])
|
||||||
|
n_sample.append([[6]])
|
||||||
|
def comparaison(x, y):
|
||||||
|
order = is_right_order(x, y)
|
||||||
|
if order is None:
|
||||||
|
return 0
|
||||||
|
if order:
|
||||||
|
return 1
|
||||||
|
return -1
|
||||||
|
|
||||||
|
keys = functools.cmp_to_key(comparaison)
|
||||||
|
n_sample = sorted(n_sample, key=keys)
|
||||||
|
n_sample.reverse()
|
||||||
|
|
||||||
|
tot = 1
|
||||||
|
for ind in range(len(n_sample)):
|
||||||
|
i = n_sample[ind]
|
||||||
|
if len(i)==1 and isinstance(i[0], list) and len(i[0])==1 and i[0][0]==2:
|
||||||
|
tot *= ind+1
|
||||||
|
elif len(i)==1 and isinstance(i[0], list) and len(i[0])==1 and i[0][0]==6:
|
||||||
|
tot *= ind+1
|
||||||
|
return tot
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Fonction principale"""
|
||||||
|
sample = read_sample()
|
||||||
|
print(f"part1: {part1(read_sample())}")
|
||||||
|
print(f"part2: {part2(read_sample())}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
116
2022/day14.py
Executable file
116
2022/day14.py
Executable file
@ -0,0 +1,116 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
"""
|
||||||
|
Jour 14 du défi Advent Of Code pour l'année 2022
|
||||||
|
"""
|
||||||
|
|
||||||
|
def read_sample():
|
||||||
|
"""récupère les entrées depuis le fichier texte correspondant"""
|
||||||
|
with open('inputs/day14.txt', 'r') as f:
|
||||||
|
sample = f.read().split('\n')
|
||||||
|
sample = [ [eval(j) for j in i.split(" -> ")] for i in sample if i != '' ]
|
||||||
|
return [[(j[1], j[0]) for j in i] for i in sample]
|
||||||
|
|
||||||
|
def create_map(sample):
|
||||||
|
maxi_0 = max([max([j[0] for j in i]) for i in sample])+1
|
||||||
|
maxi_1 = max([max([j[1] for j in i]) for i in sample])+120
|
||||||
|
|
||||||
|
map_ = [['.' for _ in range(maxi_1)] for _ in range(maxi_0)]
|
||||||
|
for line in sample:
|
||||||
|
for i in range(len(line)-1):
|
||||||
|
if line[i][0] == line[i+1][0]:
|
||||||
|
for j in range(min(line[i][1], line[i+1][1]), max(line[i][1], line[i+1][1])+1):
|
||||||
|
map_[line[i][0]][j] = '#'
|
||||||
|
else:
|
||||||
|
for j in range(min(line[i][0], line[i+1][0]), max(line[i][0], line[i+1][0])+1):
|
||||||
|
map_[j][line[i][1]] = '#'
|
||||||
|
return map_
|
||||||
|
|
||||||
|
def print_map(map_, sample):
|
||||||
|
mini = min([min([j[1] for j in i]) for i in sample])-15
|
||||||
|
for i in range(len(map_)):
|
||||||
|
print(i, "".join(map_[i][mini:]))
|
||||||
|
|
||||||
|
def make_sand_fall(map_, sand_source):
|
||||||
|
sand_pos = sand_source
|
||||||
|
while(sand_pos[0] >= 0 and sand_pos[0] < len(map_) and sand_pos[1] >= 0 and sand_pos[1] < len(map_[0])):
|
||||||
|
try:
|
||||||
|
if map_[sand_pos[0]+1][sand_pos[1]] == '.':
|
||||||
|
sand_pos = (sand_pos[0]+1, sand_pos[1])
|
||||||
|
elif map_[sand_pos[0]+1][sand_pos[1]-1] == '.':
|
||||||
|
sand_pos = (sand_pos[0]+1, sand_pos[1]-1)
|
||||||
|
elif map_[sand_pos[0]+1][sand_pos[1]+1] == '.':
|
||||||
|
sand_pos = (sand_pos[0]+1, sand_pos[1]+1)
|
||||||
|
else:
|
||||||
|
map_[sand_pos[0]][sand_pos[1]] = 'o'
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def part1(sample):
|
||||||
|
"""Partie 1 du défi"""
|
||||||
|
map_ = create_map(sample)
|
||||||
|
sand_source = (0,500)
|
||||||
|
|
||||||
|
test = True
|
||||||
|
while (test):
|
||||||
|
test = make_sand_fall(map_, sand_source)
|
||||||
|
|
||||||
|
#print_map(map_, sample)
|
||||||
|
|
||||||
|
cpt = 0
|
||||||
|
for k in map_:
|
||||||
|
for j in k:
|
||||||
|
if j == 'o':
|
||||||
|
cpt += 1
|
||||||
|
return cpt
|
||||||
|
|
||||||
|
|
||||||
|
def create_map2(sample):
|
||||||
|
maxi_0 = max([max([j[0] for j in i]) for i in sample])+3
|
||||||
|
maxi_1 = max([max([j[1] for j in i]) for i in sample])+1+maxi_0 # +maxi0 car put tomber sur les bords
|
||||||
|
|
||||||
|
map_ = [['.' for _ in range(maxi_1)] for _ in range(maxi_0)]
|
||||||
|
for line in sample:
|
||||||
|
for i in range(len(line)-1):
|
||||||
|
if line[i][0] == line[i+1][0]:
|
||||||
|
for j in range(min(line[i][1], line[i+1][1]), max(line[i][1], line[i+1][1])+1):
|
||||||
|
map_[line[i][0]][j] = '#'
|
||||||
|
else:
|
||||||
|
for j in range(min(line[i][0], line[i+1][0]), max(line[i][0], line[i+1][0])+1):
|
||||||
|
map_[j][line[i][1]] = '#'
|
||||||
|
|
||||||
|
for i in range(len(map_[0])):
|
||||||
|
map_[-1][i] = '#'
|
||||||
|
return map_
|
||||||
|
|
||||||
|
|
||||||
|
def part2(sample):
|
||||||
|
"""Partie 2 du défi"""
|
||||||
|
map_ = create_map2(sample)
|
||||||
|
|
||||||
|
sand_source = (0,500)
|
||||||
|
test = True
|
||||||
|
while (test and map_[sand_source[0]][sand_source[1]] == '.'):
|
||||||
|
test = make_sand_fall(map_, sand_source)
|
||||||
|
|
||||||
|
print_map(map_, sample)
|
||||||
|
|
||||||
|
cpt = 0
|
||||||
|
for k in map_:
|
||||||
|
for j in k:
|
||||||
|
if j == 'o':
|
||||||
|
cpt += 1
|
||||||
|
return cpt
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Fonction principale"""
|
||||||
|
sample = read_sample()
|
||||||
|
print(f"part1: {part1(sample)}")# 1409 too low # 1515 too high
|
||||||
|
print(f"part2: {part2(sample)}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
159
2022/day15.py
Executable file
159
2022/day15.py
Executable file
@ -0,0 +1,159 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
"""
|
||||||
|
Jour 15 du défi Advent Of Code pour l'année 2022
|
||||||
|
"""
|
||||||
|
from tqdm import tqdm
|
||||||
|
|
||||||
|
def read_sample():
|
||||||
|
"""récupère les entrées depuis le fichier texte correspondant"""
|
||||||
|
with open('inputs/day15.txt', 'r') as f:
|
||||||
|
sample = f.read().split('\n')
|
||||||
|
sample = [ i for i in sample if i != '' ]
|
||||||
|
return sample
|
||||||
|
|
||||||
|
|
||||||
|
def parse_sample(sample):
|
||||||
|
sensors = []
|
||||||
|
for line in sample:
|
||||||
|
spl = line.split(", ")
|
||||||
|
tmp1 = int(spl[0].split("x=")[1])
|
||||||
|
tmp2 = int(spl[1].split("y=")[1].split(":")[0])
|
||||||
|
tmp3 = int(spl[1].split("x=")[1])
|
||||||
|
tmp4 = int(spl[2].split("y=")[1].split(":")[0])
|
||||||
|
sensors.append(((tmp1, tmp2), (tmp3, tmp4)))
|
||||||
|
return sensors
|
||||||
|
|
||||||
|
|
||||||
|
def intersection(seg1, seg2):
|
||||||
|
seg = []
|
||||||
|
for line in seg1:
|
||||||
|
added = False
|
||||||
|
for line2 in seg2:
|
||||||
|
if line[0] >= line2[0] and line[1] <= line2[1]:
|
||||||
|
added = True
|
||||||
|
seg.append(line)
|
||||||
|
break
|
||||||
|
if not added:
|
||||||
|
for line2 in seg2:
|
||||||
|
if line[0] <= line2[1]:
|
||||||
|
seg.append((max(line2[0], line[0]), min(line[1], line2[1])))
|
||||||
|
elif line[1] >= line2[0]:
|
||||||
|
None#yet
|
||||||
|
|
||||||
|
return seg
|
||||||
|
|
||||||
|
def overlapping_segment(a, b):
|
||||||
|
x = max(a[0], b[0])
|
||||||
|
y = min(a[1], b[1])
|
||||||
|
return x,y
|
||||||
|
|
||||||
|
|
||||||
|
def find_overlaps(r, b):
|
||||||
|
retVal = []
|
||||||
|
ri = 0
|
||||||
|
bi = 0
|
||||||
|
while (ri < len(r)) and (bi < len(b)):
|
||||||
|
s = overlapping_segment(r[ri], b[bi])
|
||||||
|
if s[0] < s[1]:
|
||||||
|
retVal.append([ri, bi])
|
||||||
|
if r[ri][1] == s[1]:
|
||||||
|
ri += 1
|
||||||
|
if b[bi][1] == s[1]:
|
||||||
|
bi += bi + 1
|
||||||
|
return retVal
|
||||||
|
|
||||||
|
|
||||||
|
def taille_seg(segment):
|
||||||
|
taille = 0
|
||||||
|
for i in segment:
|
||||||
|
taille += i[1]-i[0]+1
|
||||||
|
return taille
|
||||||
|
|
||||||
|
def manhattan(x, y):
|
||||||
|
return abs(x[0]-y[0]) + abs(x[1]-y[1])
|
||||||
|
|
||||||
|
def create_map(sensors):
|
||||||
|
maxi_x = max([x[0]+manhattan(x, y) for (x, y) in sensors])
|
||||||
|
maxi_y = max([x[1]+manhattan(x, y) for (x, y) in sensors])
|
||||||
|
|
||||||
|
map_ = [['.' for _ in range(maxi_y)] for _ in range(maxi_x)]
|
||||||
|
for i in range(len(map_)):
|
||||||
|
for j in range(len(map_[0])):
|
||||||
|
for sensor in sensors:
|
||||||
|
if manhattan(sensor[0], sensor[1]) > manhattan(sensor[0], (i, j)):
|
||||||
|
map_[i][j] = '#'
|
||||||
|
|
||||||
|
return map_
|
||||||
|
|
||||||
|
|
||||||
|
def part1(sample):
|
||||||
|
"""Partie 1 du défi"""
|
||||||
|
sensors = parse_sample(sample)
|
||||||
|
|
||||||
|
maxi_y = max([x[1]+manhattan(x, y) for (x, y) in sensors])
|
||||||
|
mini_y = min([x[1]-manhattan(x, y) for (x, y) in sensors])
|
||||||
|
cpt = 0
|
||||||
|
j = 10
|
||||||
|
j=2000000
|
||||||
|
seg = [(mini_y, maxi_y)]
|
||||||
|
for sensor in sensors:
|
||||||
|
d = manhattan(sensor[0], sensor[1])
|
||||||
|
if d+sensor[0][0] >= j:
|
||||||
|
a = sensor[0][0] - j + d
|
||||||
|
print(seg)
|
||||||
|
print([(mini_y, sensor[0][1]-a), (sensor[0][1]+a, maxi_y)])
|
||||||
|
seg = find_overlaps(seg, [(mini_y, sensor[0][1]-a), (sensor[0][1]+a, maxi_y)])
|
||||||
|
print("=>",seg)
|
||||||
|
|
||||||
|
if sensor[0][0]-d <= j:
|
||||||
|
a = -sensor[0][0] + j + d
|
||||||
|
#print([(mini_y, sensor[0][1]-a), (sensor[0][1]+a, maxi_y)])
|
||||||
|
seg = find_overlaps(seg, [(mini_y, sensor[0][1]-a), (sensor[0][1]+a, maxi_y)])
|
||||||
|
|
||||||
|
print(seg, taille_seg(seg))
|
||||||
|
taille = taille_seg(seg)
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
for i in range(mini_y, maxi_y):
|
||||||
|
for sensor in sensors:
|
||||||
|
if manhattan(sensor[0], sensor[1]) >= manhattan(sensor[0], (i, j)):
|
||||||
|
if True not in [ a==i and b==j for ((_, _), (a, b)) in sensors ]:
|
||||||
|
cpt += 1
|
||||||
|
break
|
||||||
|
"""
|
||||||
|
return (maxi_y-mini_y)-taille
|
||||||
|
|
||||||
|
def part2(sample):
|
||||||
|
"""Partie 2 du défi"""
|
||||||
|
sensors = parse_sample(sample)
|
||||||
|
|
||||||
|
maxi = 4000000
|
||||||
|
#maxi = 20
|
||||||
|
|
||||||
|
dists = {}
|
||||||
|
for i in range(len(sensors)):
|
||||||
|
dists[i] = manhattan(sensors[i][0], sensors[i][1])
|
||||||
|
|
||||||
|
for i in tqdm(range(maxi)):
|
||||||
|
for j in range(maxi):
|
||||||
|
test = True
|
||||||
|
for k in range(len(sensors)):
|
||||||
|
if test:
|
||||||
|
if dists[k] >= manhattan(sensors[k][0], (i, j)):
|
||||||
|
test = False
|
||||||
|
|
||||||
|
if test:
|
||||||
|
return (i, j)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Fonction principale"""
|
||||||
|
sample = read_sample()
|
||||||
|
print(f"part1: {part1(sample)}")
|
||||||
|
print(f"part2: {part2(read_sample())}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
77
2022/day16.py
Executable file
77
2022/day16.py
Executable file
@ -0,0 +1,77 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
"""
|
||||||
|
Jour 16 du défi Advent Of Code pour l'année 2022
|
||||||
|
"""
|
||||||
|
import copy
|
||||||
|
|
||||||
|
def read_sample():
|
||||||
|
"""récupère les entrées depuis le fichier texte correspondant"""
|
||||||
|
with open('inputs/day16.txt', 'r') as f:
|
||||||
|
sample = f.read().split('\n')
|
||||||
|
sample = [ i for i in sample if i != '' ]
|
||||||
|
data = []
|
||||||
|
for line in sample:
|
||||||
|
split = line.split(" ")
|
||||||
|
"Valve AA has flow rate=0; tunnels lead to valves DD, II, BB"
|
||||||
|
valve_nb = split[1]
|
||||||
|
flow_rate = int(split[4].split("=")[-1].split(";")[0])
|
||||||
|
lead_to = " ".join(split[9:]).split(", ")
|
||||||
|
data.append((valve_nb, flow_rate, lead_to))
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def floyd_warshall(valves):
|
||||||
|
dist = {v: {u: int(1e9) for u in valves} for v in valves}
|
||||||
|
for v in valves:
|
||||||
|
dist[v][v] = 0
|
||||||
|
for u in valves[v]["lead_to"]:
|
||||||
|
dist[v][u] = 1
|
||||||
|
for k in valves:
|
||||||
|
for i in valves:
|
||||||
|
for j in valves:
|
||||||
|
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])
|
||||||
|
return dist
|
||||||
|
|
||||||
|
|
||||||
|
def part1(sample):
|
||||||
|
"""Partie 1 du défi"""
|
||||||
|
data = {}
|
||||||
|
for i in sample:
|
||||||
|
data[i[0]] = {"enabled":False, "flow_rate": i[1], "lead_to": i[2]}
|
||||||
|
|
||||||
|
distances = floyd_warshall(data)
|
||||||
|
non_zero = [v for v in data if data[v]["flow_rate"] > 0]
|
||||||
|
|
||||||
|
def generate_open_options(pos, opened, time_left):
|
||||||
|
for next in non_zero:
|
||||||
|
if next not in opened and distances[pos][next] <= time_left:
|
||||||
|
opened.append(next)
|
||||||
|
yield from generate_open_options(
|
||||||
|
next, opened, time_left - distances[pos][next] - 1
|
||||||
|
)
|
||||||
|
opened.pop()
|
||||||
|
yield copy.copy(opened)
|
||||||
|
|
||||||
|
def get_order_score(open_order, time_left):
|
||||||
|
now, ans = "AA", 0
|
||||||
|
for pos in open_order:
|
||||||
|
time_left -= distances[now][pos] + 1
|
||||||
|
ans += data[pos]["flow_rate"] * time_left
|
||||||
|
now = pos
|
||||||
|
return ans
|
||||||
|
|
||||||
|
return max(get_order_score(ordre, 30) for ordre in generate_open_options("AA", [], 30))
|
||||||
|
|
||||||
|
def part2(sample):
|
||||||
|
"""Partie 2 du défi"""
|
||||||
|
return NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Fonction principale"""
|
||||||
|
sample = read_sample()
|
||||||
|
print(f"part1: {part1(sample)}")
|
||||||
|
print(f"part2: {part2(sample)}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
179
2022/day18.py
Executable file
179
2022/day18.py
Executable file
@ -0,0 +1,179 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
"""
|
||||||
|
Jour 18 du défi Advent Of Code pour l'année 2022
|
||||||
|
"""
|
||||||
|
import copy
|
||||||
|
|
||||||
|
def read_sample():
|
||||||
|
"""récupère les entrées depuis le fichier texte correspondant"""
|
||||||
|
with open('inputs/day18.txt', 'r') as f:
|
||||||
|
#with open('test.txt', 'r') as f:
|
||||||
|
sample = f.read().split('\n')
|
||||||
|
sample = [ (int(i.split(",")[0]), int(i.split(",")[1]), int(i.split(",")[2])) for i in sample if i != '' ]
|
||||||
|
return sample
|
||||||
|
|
||||||
|
def nb_voisins(cube, sample):
|
||||||
|
vois = 0
|
||||||
|
if (cube[0]-1, cube[1], cube[2]) in sample:
|
||||||
|
vois += 1
|
||||||
|
if (cube[0]+1, cube[1], cube[2]) in sample:
|
||||||
|
vois += 1
|
||||||
|
if (cube[0], cube[1]-1, cube[2]) in sample:
|
||||||
|
vois += 1
|
||||||
|
if (cube[0], cube[1]+1, cube[2]) in sample:
|
||||||
|
vois += 1
|
||||||
|
if (cube[0], cube[1], cube[2]-1) in sample:
|
||||||
|
vois += 1
|
||||||
|
if (cube[0], cube[1], cube[2]+1) in sample:
|
||||||
|
vois += 1
|
||||||
|
|
||||||
|
return vois
|
||||||
|
|
||||||
|
|
||||||
|
def nb_voisins2(cube, sample, carte, num):
|
||||||
|
vois = 0
|
||||||
|
x, y, z = cube
|
||||||
|
if (x-1, y, z) in sample and carte[x-1][y][z] == num:
|
||||||
|
vois += 1
|
||||||
|
if (x+1, y, z) in sample and carte[x+1][y][z] == num:
|
||||||
|
vois += 1
|
||||||
|
if (x, y-1, z) in sample and carte[x][y-1][z] == num:
|
||||||
|
vois += 1
|
||||||
|
if (x, y+1, z) in sample and carte[x][y+1][z] == num:
|
||||||
|
vois += 1
|
||||||
|
if (x, y, z-1) in sample and carte[x][y][z-1] == num:
|
||||||
|
vois += 1
|
||||||
|
if (x, y, z+1) in sample and carte[x][y][z+1] == num:
|
||||||
|
vois += 1
|
||||||
|
|
||||||
|
return vois
|
||||||
|
|
||||||
|
|
||||||
|
def part1(sample):
|
||||||
|
"""Partie 1 du défi"""
|
||||||
|
sides = 6*len(sample)
|
||||||
|
for cube in sample:
|
||||||
|
sides -= nb_voisins(cube, sample)
|
||||||
|
return sides
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def print_cubes(sample, carte=None):
|
||||||
|
min_x, max_x = 0, max([i[0] for i in sample])+2
|
||||||
|
min_y, max_y = 0, max([i[1] for i in sample])+2
|
||||||
|
min_z, max_z = 0, max([i[2] for i in sample])+2
|
||||||
|
|
||||||
|
for z in range(min_z, max_z):
|
||||||
|
print(f"\n--- Couche {z} ---\n")
|
||||||
|
for y in range(min_x, max_x):
|
||||||
|
for x in range(min_x, max_x):
|
||||||
|
if carte is not None and carte[x][y][z] == 2:
|
||||||
|
print("%", end="")
|
||||||
|
elif (x, y, z) in sample:
|
||||||
|
print("#", end="")
|
||||||
|
elif carte is not None and carte[x][y][z] == 1:
|
||||||
|
print('.', end="")
|
||||||
|
else:
|
||||||
|
print(" ", end="")
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
def init_propagation(carte):
|
||||||
|
for x in range(len(carte)):
|
||||||
|
for y in range(len(carte[0])):
|
||||||
|
for z in range(len(carte[0][0])):
|
||||||
|
if x == 0 or y == 0 or z == 0 or x == len(carte)-1 or y == len(carte[0])-1 or z == len(carte[0][0])-1:
|
||||||
|
carte[x][y][z] = 1
|
||||||
|
|
||||||
|
|
||||||
|
def propagation(cart, sample):
|
||||||
|
carte = copy.deepcopy(cart)
|
||||||
|
modif = False
|
||||||
|
for x in range(len(carte)):
|
||||||
|
for y in range(len(carte[0])):
|
||||||
|
for z in range(len(carte[0][0])):
|
||||||
|
bon = False
|
||||||
|
if not(x == 0 or y == 0 or z == 0 or x == len(carte)-1 or y == len(carte[0])-1 or z == len(carte[0][0])-1 or cart[x][y][z] != 0):
|
||||||
|
if cart[x-1][y][z]==1:
|
||||||
|
bon = True
|
||||||
|
elif cart[x+1][y][z]==1:
|
||||||
|
bon = True
|
||||||
|
elif cart[x][y+1][z]==1:
|
||||||
|
bon = True
|
||||||
|
elif cart[x][y-1][z]==1:
|
||||||
|
bon = True
|
||||||
|
elif cart[x][y][z+1]==1:
|
||||||
|
bon = True
|
||||||
|
elif cart[x][y][z+1]==1:
|
||||||
|
bon = True
|
||||||
|
if bon:
|
||||||
|
if (x, y, z) in sample:
|
||||||
|
carte[x][y][z] = 2
|
||||||
|
else:
|
||||||
|
carte[x][y][z] = 1
|
||||||
|
modif = True
|
||||||
|
return modif, carte
|
||||||
|
|
||||||
|
|
||||||
|
def part2(sample):
|
||||||
|
"""Partie 2 du défi, simule l'eau qui se propage"""
|
||||||
|
min_x, max_x = 0, max([i[0] for i in sample])+2
|
||||||
|
min_y, max_y = 0, max([i[1] for i in sample])+2
|
||||||
|
min_z, max_z = 0, max([i[2] for i in sample])+2
|
||||||
|
carte = [[[0 for z in range(min_z, max_z)] for y in range(min_y, max_y)] for x in range(min_x, max_x)]
|
||||||
|
|
||||||
|
init_propagation(carte)
|
||||||
|
test, carte = propagation(carte, sample)
|
||||||
|
while(test):
|
||||||
|
test, carte = propagation(carte, sample)
|
||||||
|
None
|
||||||
|
|
||||||
|
sides = part1(sample)
|
||||||
|
for x in range(len(carte)):
|
||||||
|
for y in range(len(carte[0])):
|
||||||
|
for z in range(len(carte[0][0])):
|
||||||
|
if carte[x][y][z] == 0:
|
||||||
|
sides -= nb_voisins2((x, y, z), sample, carte, 2)
|
||||||
|
|
||||||
|
return sides
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def is_exterior(cube, sample):
|
||||||
|
if nb_voisins(cube, sample) == 6:
|
||||||
|
return False
|
||||||
|
if cube[0] == min([i[0] for i in sample if (i[1], i[2])==(cube[1], cube[2])]):
|
||||||
|
return True
|
||||||
|
if cube[0] == max([i[0] for i in sample if (i[1], i[2])==(cube[1], cube[2])]):
|
||||||
|
return True
|
||||||
|
if cube[1] == min([i[1] for i in sample if (i[0], i[2])==(cube[0], cube[2])]):
|
||||||
|
return True
|
||||||
|
if cube[1] == max([i[1] for i in sample if (i[0], i[2])==(cube[0], cube[2])]):
|
||||||
|
return True
|
||||||
|
if cube[2] == min([i[2] for i in sample if (i[0], i[1])==(cube[0], cube[1])]):
|
||||||
|
return True
|
||||||
|
if cube[2] == max([i[2] for i in sample if (i[0], i[1])==(cube[0], cube[1])]):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def part2_old(sample):
|
||||||
|
"""Partie 2 du défi"""
|
||||||
|
"""Ne regarde que les extrema, omet des résultats"""
|
||||||
|
sides = 6*len(sample)
|
||||||
|
for cube in sample:
|
||||||
|
if not is_exterior(cube, sample):
|
||||||
|
sides -= 6
|
||||||
|
else:
|
||||||
|
sides -= nb_voisins(cube, sample)
|
||||||
|
return sides
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Fonction principale"""
|
||||||
|
sample = read_sample()
|
||||||
|
print(f"part1: {part1(sample)}")
|
||||||
|
print(f"part2: {part2(sample)}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
140
2022/day21.py
Executable file
140
2022/day21.py
Executable file
@ -0,0 +1,140 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
"""
|
||||||
|
Jour 21 du défi Advent Of Code pour l'année 2022
|
||||||
|
"""
|
||||||
|
from tqdm import tqdm
|
||||||
|
|
||||||
|
def read_sample():
|
||||||
|
"""récupère les entrées depuis le fichier texte correspondant"""
|
||||||
|
with open('inputs/day21.txt', 'r') as f:
|
||||||
|
#with open('test.txt', 'r') as f:
|
||||||
|
sample = f.read().split('\n')
|
||||||
|
sample = [ Monkey(i) for i in sample if i != '' ]
|
||||||
|
return sample
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Monkey():
|
||||||
|
def __init__(self, data):
|
||||||
|
self.name = data.split(": ")[0]
|
||||||
|
self.has_yelled = False
|
||||||
|
self.value = -1
|
||||||
|
if len(data.split(": ")[1].split(" ")) == 1:
|
||||||
|
self.dependencies = []
|
||||||
|
self.operation = lambda x : int(data.split(": ")[1])
|
||||||
|
|
||||||
|
else:
|
||||||
|
self.dependencies = [data.split(": ")[1].split(" ")[0], data.split(": ")[1].split(" ")[2]]
|
||||||
|
self.operator = data.split(': ')[1].split(' ')[1]
|
||||||
|
self.operation = lambda deps: eval(f"deps[0] {data.split(': ')[1].split(' ')[1]} deps[1]")
|
||||||
|
|
||||||
|
def evaluate(self, data):
|
||||||
|
if len(self.dependencies) == 0:
|
||||||
|
self.has_yelled = True
|
||||||
|
self.value = self.operation(0)
|
||||||
|
return
|
||||||
|
|
||||||
|
for name in self.dependencies:
|
||||||
|
monkey = data[name]
|
||||||
|
if not monkey.has_yelled:
|
||||||
|
monkey.evaluate(data)
|
||||||
|
|
||||||
|
self.has_yelled = True
|
||||||
|
self.value = self.operation((data[self.dependencies[0]].value, data[self.dependencies[1]].value))
|
||||||
|
|
||||||
|
def get_recursive_dependencies(self, data):
|
||||||
|
if len(self.dependencies) == 0:
|
||||||
|
return [self.name]
|
||||||
|
|
||||||
|
return data[self.dependencies[0]].get_recursive_dependencies(data) + data[self.dependencies[1]].get_recursive_dependencies(data) + [self.name]
|
||||||
|
|
||||||
|
def find_value(self, value, name, data):
|
||||||
|
if self.name == name:
|
||||||
|
return int(value)
|
||||||
|
|
||||||
|
if name in data[data[self.name].dependencies[0]].get_recursive_dependencies(data):
|
||||||
|
change_me = data[data[self.name].dependencies[0]]
|
||||||
|
other = data[data[self.name].dependencies[1]]
|
||||||
|
else:
|
||||||
|
change_me = data[data[self.name].dependencies[1]]
|
||||||
|
other = data[data[self.name].dependencies[0]]
|
||||||
|
|
||||||
|
other.evaluate(data)
|
||||||
|
if self.operator == '*':
|
||||||
|
return int(change_me.find_value(value/other.value, name, data))
|
||||||
|
if self.operator == '+':
|
||||||
|
return int(change_me.find_value(value-other.value, name, data))
|
||||||
|
|
||||||
|
if change_me.name == data[data[self.name].dependencies[1]]:
|
||||||
|
if self.operator == '/':
|
||||||
|
return int(change_me.find_value(other.value/value, name, data))
|
||||||
|
if self.operator == '-':
|
||||||
|
return int(change_me.find_value(other.value-value, name, data))
|
||||||
|
|
||||||
|
if self.operator == '/':
|
||||||
|
return int(change_me.find_value(other.value*value, name, data)) # Not really)
|
||||||
|
if self.operator == '-':
|
||||||
|
return int(change_me.find_value(other.value+value, name, data))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def part1(sample):
|
||||||
|
"""Partie 1 du défi"""
|
||||||
|
data = {}
|
||||||
|
for monkey in sample:
|
||||||
|
data[monkey.name] = monkey
|
||||||
|
|
||||||
|
data["root"].evaluate(data)
|
||||||
|
return data["root"].value
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def part2_brute():
|
||||||
|
"""Partie 2 du défi"""
|
||||||
|
"""Relativement lent, mais l'approche par brute force finit par fonctionner"""
|
||||||
|
for i in tqdm(range(3876907167494-5, 3876907167494+5)):
|
||||||
|
sample = read_sample()
|
||||||
|
data = {}
|
||||||
|
for monkey in sample:
|
||||||
|
data[monkey.name] = monkey
|
||||||
|
|
||||||
|
data["humn"].value = i
|
||||||
|
data["humn"].has_yelled = True
|
||||||
|
|
||||||
|
data[data["root"].dependencies[0]].evaluate(data)
|
||||||
|
data[data["root"].dependencies[1]].evaluate(data)
|
||||||
|
if data[data["root"].dependencies[0]].value == data[data["root"].dependencies[1]].value:
|
||||||
|
return i
|
||||||
|
|
||||||
|
return NotImplementedError
|
||||||
|
|
||||||
|
def part2(sample):
|
||||||
|
"""Partie 2 du défi"""
|
||||||
|
"""Ne fonctionne pas"""
|
||||||
|
|
||||||
|
data = {}
|
||||||
|
for monkey in sample:
|
||||||
|
data[monkey.name] = monkey
|
||||||
|
|
||||||
|
|
||||||
|
if "humn" in data[data["root"].dependencies[0]].get_recursive_dependencies(data):
|
||||||
|
humn = data[data["root"].dependencies[0]]
|
||||||
|
other = data[data["root"].dependencies[1]]
|
||||||
|
else:
|
||||||
|
humn = data[data["root"].dependencies[1]]
|
||||||
|
other = data[data["root"].dependencies[0]]
|
||||||
|
|
||||||
|
other.evaluate(data)
|
||||||
|
return humn.find_value(other.value, "humn", data)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Fonction principale"""
|
||||||
|
sample = read_sample()
|
||||||
|
print(f"part1: {part1(sample)}")
|
||||||
|
print(f"part2: {part2(read_sample())}")
|
||||||
|
print(f"part2 bruteforce: {part2_brute()}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
Loading…
x
Reference in New Issue
Block a user