◂ 6 décembre 2023 ▸
Wait For It : Trouver les meilleurs compromis entre durée de charge d'un bateau (le rend rapide) et le temps restant de course
Time: 49 97 …
Distance: 263 1532 …
- code.py
import re, math, timeit
f = open("input.txt", 'r', encoding='utf-8')
lines = [line[:-1] for line in f.readlines()]
times, dists = ([ int(tok) for tok in re.split('[^0-9]+', line) if tok ] for line in lines)
def nb_fois_battu_basique(time, dist):
"""Donne le nombre de façon de battre le record de distance
Façon naïve qui teste chaque possibilité."""
nb_fois_battu = 0
for temps_presse in range(1,time): # 0 et time donnent 0, inutiles !
if (time-temps_presse) * temps_presse > dist:
nb_fois_battu += 1
return nb_fois_battu
def nb_fois_battu_basique_avec_generateur(time, dist):
"""Donne le nombre de façon de battre le record de distance
Façon naïve, mais avec générateur : plus lent de 10%"""
return sum(1 for temps_presse in range(1,time) if (time-temps_presse) * temps_presse > dist)
def nb_fois_battu_rapide(time, dist):
"""Donne le nombre de façon de battre le record de distance
en résolvant l'inéquation (time-x) · x > dist
↔ x² - time·x + dist < 0
O(1) au lieu de O(n), donc résultat immédiat (mille fois plus rapide ici)."""
delta = time**2 - 4*dist
if delta <= 0:
return 0
sqrt_delta = math.sqrt(delta)
x1 = (time - sqrt_delta) / 2
x2 = (time + sqrt_delta) / 2
return math.ceil(x2) - math.floor(x1) - 1
def reponse1(times, dists):
return math.prod( nb_fois_battu(*time_dist) for time_dist in zip(times, dists) )
def reponse2(times, dists):
coller_valeurs = lambda tab: int(''.join(map(str,tab)))
return nb_fois_battu( coller_valeurs(times), coller_valeurs(dists) )
## Exécution et mesure du temps mis :
coller_valeurs = lambda tab: int(''.join(map(str,tab)))
time, dist = map(coller_valeurs, (times, dists))
timer = timeit.Timer('timer.reponse2 = nb_fois_battu(time, dist)', globals=globals())
for nb_fois_battu in (nb_fois_battu_rapide, nb_fois_battu_basique, nb_fois_battu_basique_avec_generateur):
print("**** Utilisation de " + str(nb_fois_battu).split()[1] + " :")
print("Réponse partie 1:", reponse1(times, dists))
temps = float('%.2g' % timer.timeit(10000 if nb_fois_battu == nb_fois_battu_rapide else 1))
print("Réponse partie 2:", timer.reponse2)
print(' Exécution en %s secondes' % temps)