E04 - Intersection⚓︎
Le problème
Proposition 1⚓︎
def calcul(nombre_heure1, nombre_heure2, duree_commune) -> int :
# cas de figure 0 :
if nombre_heure1[0] >= nombre_heure2[1] :
return 0
if nombre_heure2[0] >= nombre_heure1[1] :
return 0
# Premier cas de figure 1 :
if nombre_heure1[0] > nombre_heure2[0] :
#1a
if nombre_heure1[1] > nombre_heure2[1]:
duree_commune = nombre_heure1[0] - nombre_heure2[1]
return duree_commune
#1b
duree_commune = nombre_heure1[1] - nombre_heure2[1]
return duree_commune
# Deuxième cas de figure 2 :
if nombre_heure1[0] < nombre_heure2[0] :
#2a
if nombre_heure1[1] < nombre_heure2[1]:
duree_commune = nombre_heure2[0] - nombre_heure1[1]
return duree_commune
#2b
duree_commune = nombre_heure2[0] - nombre_heure2[1]
return duree_commune
# Troisème cas de figure 3 :
if nombre_heure1[0] == nombre_heure2[0]:
#3a
if nombre_heure1[1] > nombre_heure2[1]:
duree_commune = nombre_heure1[0] - nombre_heure2[1]
return duree_commune
#3b
duree_commune = nombre_heure1[0] - nombre_heure1[1]
return duree_commune
nombre_heure1 = list(map(int, input().split()))
nombre_heure2 = list(map(int, input().split()))
duree_commune = 0
print(abs(calcul(nombre_heure1, nombre_heure2, duree_commune)))
# abs() va renvoyer la valeur absolue
-
Mauvais passage de paramètres.
-
Il y a trop de cas de figures... On peut largement simplifier.
-
On attend des noms de variable bien plus explicites que
calcul
! -
On attend un doctest...
-
abs
aurait du être utilisé dans la fonction, pas ensuite.
Proposition 2⚓︎
def inter(pa,pb):
if pa[0] >= pb[0] and pa[0] < pb[1]:
if pa[1]>pb[1]:
return pb[1]-pa[0]
else:
return pa[1]-pa[0]
elif pb[0]>= pa[0] and pb[0]<pa[1]:
if pb[1]>pa[1]:
return pa[1]-pb[0]
else:
return pb[1]-pb[0]
else:
return 0
pera = list(map(int,input(). strip(). split()))[:2]
perb = list(map(int,input(). strip(). split()))[:2]
per = inter(pera,perb)
print(per)
import doctest
doctest.testmod()
- Noms de variables très mal choisis...
- PEP-8 à mieux respecter !
- On attend un doctest pour chaque problème.
Proposition 3⚓︎
def intervalle(x_min: int, x_max: int, y_min: int, y_max: int) -> int:
"""
Renvoie la durée en commun entre les deux périodes.
>>> intervalle(-47686716, -38491014, -48528973, -42411585)
5275131
>>> intervalle(-47698252, -45630884, -45440315, -37180150)
0
"""
# se touche pas
if x_max <= y_min or y_max <= x_min:
return 0
# englobe tout
elif y_min >= x_min and y_max <= x_max:
return abs(y_max - y_min)
elif x_min >= y_min and x_max <= y_max:
return abs(x_max - x_min)
# intervalle
elif y_min < x_min < y_max:
return abs(y_max - x_min)
elif y_min < x_max < y_max:
return abs(x_max - y_min)
# Test
import doctest
doctest.testmod()
# Entrée
x_min, x_max = input().split()
x_min = int(x_min)
x_max = int(x_max)
y_min, y_max = input().split()
y_min = int(y_min)
y_max = int(y_max)
# Sortie
print(intervalle(x_min, x_max, y_min, y_max))
-
Le nom
intervalle
est mal choisi. -
x
ety
sont mal choisis, cela fait penser à des coordonnées cartésiennes en 2D ; ce n'est pas le cas ici. -
Tu pouvais encore factoriser le code.
Proposition 4⚓︎
def intersection(periode_a, periode_b):
"""
Calcule et Renvoie le nombre d'heure en commun
"""
if periode_a[0] == periode_a[1] or periode_b[0] == periode_b[1] \
or periode_a[1] == periode_b[0] or periode_b[1] == periode_a[0]:
return 1
if periode_a[0] < periode_b[0] and periode_a[1] > periode_b[1]:
return (periode_b[1] - periode_b[0])
if periode_a[0] > periode_b[0] and periode_a[1] < periode_b[1]:
return (periode_a[1] - periode_a[0])
if periode_a[1] < periode_b[0] or periode_b[1] < periode_a[0]:
return 0
if periode_a[1] > periode_b[0] and periode_a[1] < periode_b[1]:
return (periode_a[1]-periode_b[0])
if periode_b[1] > periode_a[0] and periode_b[1] < periode_a[1]:
return (periode_b[1]-periode_a[0])
#Entrée
periode_a = list(map(int, input().split()))
periode_b = list(map(int, input().split()))
if periode_a[1] > 0:
periode_a[1] -= 1
if periode_b[1] > 0:
periode_b[1] -= 1
#Sortie
print(intersection(periode_a, periode_b))
-
Il y a trop de cas, tu pouvais factoriser.
-
Pourquoi ce décalage de - 1 juste après la lecture de l'entrée ???
-
Les
[0]
et[1]
sont peu lisibles ; il vaut mieux extraire et utiliser un nom explicite.
Proposition 5⚓︎
def intersection():
"""Renvoie la durée en commun entre les deux périodes
>>> -47686716 -38491014
>>> -48528973 -42411585
5275131
"""
if (période_2[1] < période_1[0]) or (période_1[1] < période_2[0]) :
return 0
elif période_1[0] < période_2[0] and période_1[1] < période_2[1] :
return abs(période_2[0] - période_1[1])
elif période_1[0] < période_2[0] and période_1[1] > période_2[1] :
return abs(période_2[0] - période_2[1])
elif période_1[0] > période_2[0] and période_1[1] < période_2[1] :
return abs(période_1[0] - période_1[1])
elif période_1[0] > période_2[0] and période_1[1] > période_2[1]:
return abs(période_1[0] - période_2[1])
période_1 = list(map(int, input().split()))
période_2 = list(map(int, input().split()))
print(intersection())
-
Revoir le principe du doctest.
-
Il y a trop de cas.
-
Travailler avec les indices 0 et 1 est pénible, il vaut mieux extraire dans debut_1, ... , fin_2 ; par exemple.
-
Il faut passer les paramètres à la fonction.
Corrigé du professeur⚓︎
"""
author: Franck CHAMBON
problem: https://prologin.org/train/2004/semifinal/carte_au_tresor
"""
def intersection(debut_1: int, fin_1: int, debut_2: int, fin_2: int) -> int:
"""Renvoie la durée de l'intersection de
[debut_1 ; fin_1] avec [debut_2 ; fin_2]
>>> intersection(-47686716, -38491014, -48528973, -42411585)
5275131
>>> intersection(-47698252, -45630884, -45440315, -37180150)
0
"""
debut = max(debut_1, debut_2)
fin = min(fin_1, fin_2)
if debut < fin:
return fin - debut
else:
return 0
# Tests
import doctest
doctest.testmod()
# Entrée
debut_1, fin_1 = map(int, input().split())
debut_2, fin_2 = map(int, input().split())
# Sortie
print(intersection(debut_1, fin_1, debut_2, fin_2))
Code minimal
On peut encore réduire (ce serait mal) le code de la fonction avec
def intersection(debut_1, fin_1, debut_2, fin_2):
debut = max(debut_1, debut_2)
fin = min(fin_1, fin_2)
return max(0, fin - debut)
One-liner
Et en une seule ligne, mais ce serait très peu lisible. INTERDIT !!!
def intersection(debut_1, fin_1, debut_2, fin_2):
return max(0, min(fin_1, fin_2) - max(debut_1, debut_2))