Compare commits

...

3 Commits

Author SHA1 Message Date
12f0be2a50 Update README.md 2023-12-23 15:30:28 +01:00
bef72df794 Create aoc_utils 2023-12-23 15:28:25 +01:00
483788be60 Add 2023 day 21[2] 2023-12-23 15:28:09 +01:00
5 changed files with 79 additions and 25 deletions

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():

View File

@ -7,7 +7,7 @@
2020: ***~..................... 2020: ***~.....................
2021: *******~~~............... 2021: *******~~~...............
2022: ***************~.*..*.... 2022: ***************~.*..*....
2023: **********............... 2023: **********************~..
.: nothing .: nothing
~: 1 star ~: 1 star
@ -20,9 +20,17 @@ Add this to your `.bashrc`:
AOC_PATH=$HOME/path/to/this/repo/ AOC_PATH=$HOME/path/to/this/repo/
alias aoc="$AOC_PATH/utils/cli.py" alias aoc="$AOC_PATH/utils/cli.py"
aoc-new () { aoc-new () {
# To create a new day
cd $AOC_PATH cd $AOC_PATH
PATH="$PATH:$AOC_PATH" PATH="$PATH:$AOC_PATH"
$AOC_PATH/new_day.sh $AOC_PATH/utils/new_day.sh
PS1="$PS1[aoc] " export PYTHONPATH="$PYTHONPATH:$AOC_PATH"
}
aoc-env () {
# To load the AoC environment
cd $AOC_PATH
PATH="$PATH:$AOC_PATH"
export PYTHONPATH="$PYTHONPATH:$AOC_PATH"
} }
``` ```

0
aoc_utils/__init__.py Normal file
View File

13
aoc_utils/constants.py Normal file
View File

@ -0,0 +1,13 @@
arrows_dir ={
'^': (-1, 0),
'v': (1, 0),
'<': (0, -1),
'>': (0, 1)
}
cardinal_dir = [
(1, 0),
(-1,0),
(0, 1),
(0, -1)
]

13
aoc_utils/decorators.py Normal file
View File

@ -0,0 +1,13 @@
from functools import cache, wraps
import time
def timeit(func):
@wraps(func)
def timeit_wrapper(*args, **kwargs):
start_time = time.perf_counter()
result = func(*args, **kwargs)
end_time = time.perf_counter()
total_time = end_time - start_time
print(f'===== {func.__name__}: {total_time:.4f}s =====')
return result
return timeit_wrapper