Add 2023 day 21[2]

This commit is contained in:
augustin64 2023-12-23 15:28:09 +01:00
parent 8ece48dc88
commit 483788be60

View File

@ -3,7 +3,7 @@
Jour 21 du défi Advent Of Code pour l'année 2023 Jour 21 du défi Advent Of Code pour l'année 2023
""" """
import os import os
from tqdm import tqdm from aoc_utils.decorators import timeit
def read_sample(): def read_sample():
"""récupère les entrées depuis le fichier texte correspondant""" """récupère les entrées depuis le fichier texte correspondant"""
@ -23,10 +23,11 @@ def do_steps(sample, steps=26501365, ext=False):
if sample[i][j] == 'S': if sample[i][j] == 'S':
return (i, j) return (i, j)
def valid(pos): def valid(pos, ext=False):
if ext:
return True
return pos[0] >= 0 and pos[1] >= 0 and pos[0] < len_sample and pos[1] < len_sample0 return pos[0] >= 0 and pos[1] >= 0 and pos[0] < len_sample and pos[1] < len_sample0
def is_point(pos, ext=False): def is_point(pos, ext=False):
if not ext and valid(pos): if not ext and valid(pos):
if sample[pos[0]][pos[1]] == '.' or sample[pos[0]][pos[1]] == 'S': if sample[pos[0]][pos[1]] == '.' or sample[pos[0]][pos[1]] == 'S':
@ -39,43 +40,62 @@ def do_steps(sample, steps=26501365, ext=False):
def voisins(pos, ext=False): def voisins(pos, ext=False):
i, j = pos i, j = pos
v = [] v = []
if valid((i, j-1)) and is_point((i, j-1), ext=ext): if valid((i, j-1), ext=ext) and is_point((i, j-1), ext=ext):
v.append((i, j-1)) v.append((i, j-1))
if valid((i-1, j)) and is_point((i-1, j), ext=ext): if valid((i-1, j), ext=ext) and is_point((i-1, j), ext=ext):
v.append((i-1, j)) v.append((i-1, j))
if valid((i, j+1)) and is_point((i, j+1), ext=ext): if valid((i, j+1), ext=ext) and is_point((i, j+1), ext=ext):
v.append((i, j+1)) v.append((i, j+1))
if valid((i+1, j)) and is_point((i+1, j), ext=ext): if valid((i+1, j), ext=ext) and is_point((i+1, j), ext=ext):
v.append((i+1, j)) v.append((i+1, j))
return v return v
i, j = find_S() i, j = find_S()
pos_ts = {(i, j): [(0, 0)]} pos_ts = {(i, j)}
for i in tqdm(range(steps)): for i in range(steps):
new_pos_ts = {} new_pos_ts = set()
for pos in pos_ts.keys(): for pos in pos_ts:
for p in voisins(pos, ext=ext): for p in voisins(pos, ext=ext):
mp = (p[0]%len_sample, p[1]%len_sample0) new_pos_ts.add(p)
tile = (p[0]//len_sample, p[1]//len_sample0)
if mp not in new_pos_ts.keys():
new_pos_ts[mp] = []
for elem in pos_ts[pos]:
t = (tile[0]+elem[0], tile[1]+elem[1])
if t not in new_pos_ts[mp]:
new_pos_ts[mp].append(t)
pos_ts = new_pos_ts pos_ts = new_pos_ts
return pos_ts return pos_ts
def lagrange_interpolation(points, x0):
result = 0
for i in range(len(points)):
temp = points[i][1]
for j in range(len(points)):
if j != i:
temp *= (x0 - points[j][0]) / (points[i][0] - points[j][0])
result += temp
return int(result)
@timeit
def part1(sample): def part1(sample):
"""Partie 1 du défi""" """Partie 1 du défi"""
return sum([len(i) for i in do_steps(sample, steps=64, ext=False).values()]) return len(do_steps(sample, steps=64, ext=False))
@timeit
def part2(sample): def part2(sample):
"""Partie 2 du défi""" """Partie 2 du défi"""
print("WARNING, this will take a lot of time (and could not even work)") def challenge(steps):
return sum([len(i) for i in do_steps(sample, ext=True).values()]) return len(do_steps(sample, steps=steps, ext=True))
half_size = len(sample)//2
size = len(sample)
points = [
(half_size, challenge(half_size)),
(half_size+size, challenge(half_size+size)),
(half_size+2*size, challenge(half_size+2*size))
]
return lagrange_interpolation(points, 26501365)
def main(): def main():