2023-12-05 08:35:07 +01:00
|
|
|
#!/usr/bin/python3
|
|
|
|
"""
|
|
|
|
Jour 05 du défi Advent Of Code pour l'année 2023
|
|
|
|
"""
|
2023-12-10 15:29:11 +01:00
|
|
|
import os
|
2023-12-05 08:35:07 +01:00
|
|
|
|
|
|
|
def read_sample():
|
|
|
|
"""récupère les entrées depuis le fichier texte correspondant"""
|
2023-12-10 15:29:11 +01:00
|
|
|
filename = os.path.join(os.path.dirname(__file__ ), "inputs", "day05.txt")
|
|
|
|
with open(filename, 'r') as f:
|
2023-12-05 08:35:07 +01:00
|
|
|
sample = f.read().split('\n\n')
|
|
|
|
sample = [ i for i in sample if i != '' ]
|
|
|
|
return sample
|
|
|
|
|
|
|
|
def parse_sample(sample):
|
|
|
|
data = []
|
|
|
|
data.append(("seeds", [int(i) for i in sample[0].split(" ")[1:] if i != ""]))
|
|
|
|
|
|
|
|
for subsample in sample[1:]:
|
|
|
|
d = subsample.split("\n")
|
|
|
|
name = d[0].split("-")[-1].split(" ")[0]
|
|
|
|
maps = [[int(j) for j in i.split(" ") if i != ""] for i in d[1:] if i != ""]
|
|
|
|
data.append((name, maps))
|
|
|
|
return data
|
|
|
|
|
|
|
|
|
|
|
|
def get_locations(data, new_seed=False):
|
2023-12-05 09:00:11 +01:00
|
|
|
if new_seed:
|
|
|
|
# Nouvelle définition des range
|
2023-12-05 08:35:07 +01:00
|
|
|
pos = []
|
|
|
|
for i in range(int(len(data[0][1])/2)):
|
|
|
|
pos.append((data[0][1][2*i], data[0][1][2*i+1]))
|
|
|
|
# print(pos)
|
2023-12-05 09:00:11 +01:00
|
|
|
else:
|
|
|
|
# On considère des range de 1
|
|
|
|
pos = [(i, 1) for i in data[0][1]]
|
2023-12-05 08:35:07 +01:00
|
|
|
|
|
|
|
for converter in data[1:]:
|
2023-12-05 09:00:11 +01:00
|
|
|
# On itère sur tous les changements de type de données
|
2023-12-05 08:35:07 +01:00
|
|
|
new_pos = []
|
|
|
|
for (source, rg) in pos:
|
2023-12-05 09:00:11 +01:00
|
|
|
found = False # Il existe un converter ?
|
|
|
|
min_dst = rg # Distance min à un converter
|
2023-12-05 08:35:07 +01:00
|
|
|
for possible_dest in converter[1]:
|
|
|
|
cv_dest, cv_source, cv_range = possible_dest
|
|
|
|
|
|
|
|
if source >= cv_source and source <= cv_source+cv_range:
|
2023-12-05 09:00:11 +01:00
|
|
|
# Un converter est disponible
|
2023-12-05 08:35:07 +01:00
|
|
|
treated_range = min(rg, cv_range - (source - cv_source))
|
2023-12-05 09:00:11 +01:00
|
|
|
if treated_range > 0: # Revoir la condition au dessus ? éviter de créer des élems 0 en tous cas
|
2023-12-05 08:35:07 +01:00
|
|
|
new_pos.append((source - (cv_source-cv_dest), treated_range))
|
|
|
|
|
|
|
|
#print(f"{converter[0]}: {source} -> {new_pos[-1]}")
|
2023-12-05 09:00:11 +01:00
|
|
|
if (rg > treated_range): # Partie non convertie
|
2023-12-05 08:35:07 +01:00
|
|
|
#print(f"using tr:", (source+treated_range, rg - treated_range))
|
|
|
|
pos.append((source+treated_range, rg - treated_range))
|
|
|
|
found = True
|
|
|
|
break
|
|
|
|
|
|
|
|
elif cv_source > source:
|
|
|
|
min_dst = min(min_dst, cv_source-source)
|
|
|
|
|
|
|
|
if not found:
|
2023-12-05 09:00:11 +01:00
|
|
|
# On ajoute jusqu'au prochain converter
|
2023-12-05 08:35:07 +01:00
|
|
|
new_pos.append((source, min_dst))
|
|
|
|
if min_dst < rg:
|
|
|
|
pos.append((source+min_dst, rg-min_dst))
|
|
|
|
#print(f"{converter[0]}: {source} -> {new_pos[-1]} (auto)")
|
|
|
|
pos = new_pos
|
|
|
|
return pos
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def part1(sample):
|
|
|
|
"""Partie 1 du défi"""
|
|
|
|
data = parse_sample(sample)
|
|
|
|
return min(get_locations(data))[0]
|
|
|
|
|
|
|
|
def part2(sample):
|
|
|
|
"""Partie 2 du défi"""
|
|
|
|
data = parse_sample(sample)
|
|
|
|
return min(get_locations(data, new_seed=True))[0]
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
"""Fonction principale"""
|
|
|
|
sample = read_sample()
|
|
|
|
print(f"part1: {part1(sample)}")
|
|
|
|
print(f"part2: {part2(sample)}")
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|