Factorise some code into snippets.py
This commit is contained in:
parent
e5ba1cc940
commit
5c55af6ae0
@ -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():
|
||||||
|
@ -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)
|
||||||
|
@ -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():
|
||||||
|
@ -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
48
aoc_utils/snippets.py
Normal 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())
|
Loading…
Reference in New Issue
Block a user