Factorise some code into snippets.py

This commit is contained in:
augustin64 2023-12-23 18:59:54 +01:00
parent e5ba1cc940
commit 5c55af6ae0
5 changed files with 67 additions and 70 deletions

View File

@ -3,6 +3,7 @@
Jour 08 du défi Advent Of Code pour l'année 2023 Jour 08 du défi Advent Of Code pour l'année 2023
""" """
import os import os
import math
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"""
@ -12,19 +13,6 @@ def read_sample():
sample = [ i for i in sample if i != '' ] sample = [ i for i in sample if i != '' ]
return sample return sample
def gcd(a, b):
while b:
a, b = b, a % b
return a
def lcm(a, b):
return (a * b) // gcd(a, b)
def lcm_of_list(numbers):
result = 1
for num in numbers:
result = lcm(result, num)
return result
def parse_sample(sample): def parse_sample(sample):
instructions = sample[0] instructions = sample[0]
@ -34,6 +22,7 @@ def parse_sample(sample):
} }
return instructions, mappings return instructions, mappings
def number_steps(instructions, mappings, pos, untilZZZ=True): def number_steps(instructions, mappings, pos, untilZZZ=True):
step = 0 step = 0
instr = { instr = {
@ -44,6 +33,8 @@ def number_steps(instructions, mappings, pos, untilZZZ=True):
step += 1 step += 1
return step return step
def part1(sample): def part1(sample):
"""Partie 1 du défi""" """Partie 1 du défi"""
instructions, mappings = parse_sample(sample) instructions, mappings = parse_sample(sample)
@ -54,7 +45,7 @@ def part2(sample):
instructions, mappings = parse_sample(sample) instructions, mappings = parse_sample(sample)
a_ending = [i for i in mappings.keys() if i[-1] == 'A'] a_ending = [i for i in mappings.keys() if i[-1] == 'A']
steps = [number_steps(instructions, mappings, i, untilZZZ=False) for i in a_ending] steps = [number_steps(instructions, mappings, i, untilZZZ=False) for i in a_ending]
return lcm_of_list(steps) return math.lcm(*steps)
def main(): def main():

View File

@ -3,8 +3,9 @@
Jour 12 du défi Advent Of Code pour l'année 2023 Jour 12 du défi Advent Of Code pour l'année 2023
""" """
import os import os
from functools import cache, wraps from functools import cache
from time import time
from aoc_utils import decorators
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"""
@ -24,18 +25,6 @@ def parse_sample(sample):
return springs, counts return springs, counts
def timing(f):
@wraps(f)
def wrap(*args, **kw):
ts = time()
result = f(*args, **kw)
te = time()
print('> %s: %2.4f sec' % \
(f.__name__, te-ts))
return result
return wrap
def nb_poss(spring, count): def nb_poss(spring, count):
def check_new_elem(elem, size, count): def check_new_elem(elem, size, count):
if size > len(count): if size > len(count):
@ -114,7 +103,7 @@ def unfold(springs, counts):
counts[i] = counts[i]*5 counts[i] = counts[i]*5
@timing @decorators.timeit
def part1(sample): def part1(sample):
"""Partie 1 du défi""" """Partie 1 du défi"""
springs, counts = parse_sample(sample) springs, counts = parse_sample(sample)
@ -125,7 +114,7 @@ def part1(sample):
return sum(possibilities) return sum(possibilities)
@timing @decorators.timeit
def part2(sample): def part2(sample):
"""Partie 2 du défi""" """Partie 2 du défi"""
springs, counts = parse_sample(sample) springs, counts = parse_sample(sample)

View File

@ -4,6 +4,8 @@ Jour 18 du défi Advent Of Code pour l'année 2023
""" """
import os import os
from aoc_utils import snippets
directions = { directions = {
"R": (0, 1), "R": (0, 1),
"L": (0, -1), "L": (0, -1),
@ -107,29 +109,6 @@ def print_terrain(terrain):
print() print()
def border(data):
return(sum((i[1] for i in data)))
# https://www.tutorialspoint.com/program-to-find-area-of-a-polygon-in-python
def getInfo(x1, y1, x2, y2):
return x1*y2 - y1*x2
def solve(data):
points = [t[0] for t in data]
N = len(points)
firstx, firsty = points[0]
prevx, prevy = firstx, firsty
res = 0
for i in range(1, N):
nextx, nexty = points[i]
res = res + getInfo(prevx,prevy,nextx,nexty)
prevx = nextx
prevy = nexty
res = res + getInfo(prevx,prevy,firstx,firsty)
return abs(res)/2.0
def part1(sample): def part1(sample):
"""Partie 1 du défi""" """Partie 1 du défi"""
data = parse_sample(sample, new_method=False) data = parse_sample(sample, new_method=False)
@ -140,7 +119,8 @@ def part2(sample):
"""Partie 2 du défi""" """Partie 2 du défi"""
data = parse_sample(sample, new_method=True) data = parse_sample(sample, new_method=True)
terrain = dig(data, only_edges=True) terrain = dig(data, only_edges=True)
return int(solve(terrain)+border(data)//2 +1) points = [i[0] for i in terrain]
return snippets.area(points)
def main(): def main():

View File

@ -3,7 +3,8 @@
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 aoc_utils.decorators import timeit
from aoc_utils import decorators, snippets
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"""
@ -62,24 +63,12 @@ def do_steps(sample, steps=26501365, ext=False):
return pos_ts return pos_ts
def lagrange_interpolation(points, x0): @decorators.timeit
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 len(do_steps(sample, steps=64, ext=False)) return len(do_steps(sample, steps=64, ext=False))
@timeit @decorators.timeit
def part2(sample): def part2(sample):
"""Partie 2 du défi""" """Partie 2 du défi"""
def challenge(steps): def challenge(steps):
@ -93,7 +82,7 @@ def part2(sample):
(half_size+size, challenge(half_size+size)), (half_size+size, challenge(half_size+size)),
(half_size+2*size, challenge(half_size+2*size)) (half_size+2*size, challenge(half_size+2*size))
] ]
return lagrange_interpolation(points, 26501365) return snippets.lagrange_interpolation(points, 26501365)

48
aoc_utils/snippets.py Normal file
View File

@ -0,0 +1,48 @@
from typing import TypeVar
Nb = TypeVar("Nb", int, float)
def lagrange_interpolation(points: list[tuple[Nb, Nb]], x0: Nb) -> int:
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)
def area(points: list[tuple[Nb, Nb]], count_border: bool=True) -> int:
def distance(p1: tuple[Nb, Nb], p2: tuple[Nb, Nb]) -> float:
return abs(p1[0]-p2[0]) + abs(p1[1]-p2[1])
def get_info(x1: Nb, y1: Nb, x2: Nb, y2: Nb) -> Nb:
return x1*y2 - y1*x2
def inner_area() -> float:
first_x, first_y = points[0]
prev_x, prev_y = first_x, first_y
res = 0
for i in range(len(points)-1):
next_x, next_y = points[i+1]
res = res + get_info(prev_x, prev_y, next_x, next_y)
prev_x = next_x
prev_y = next_y
res = res + get_info(prev_x, prev_y, first_x, first_y)
return abs(res)/2.0
def border() -> float:
distances = [distance(points[i], points[i+1]) for i in range(len(points)-1)]
distances.append(distance(points[-1], points[0]))
return sum(distances)
if count_border:
return int(inner_area()+border()//2 +1)
return int(inner_area())