Ce petit notebook Jupyter, écrit en Python, a pour but de résoudre la question suivante :
"En 2017, combien de jours ont leur date qui est un nombre premier ?"
Par exemple, en 2017, le 23 février donne 23022017
est premier, mais le 24 février donne 24022017
qui ne l'est pas.
On veut trouver toutes les dates en 2017 qui sont des nombres premiers.
12012017
pour le 12 janvier ou 01122017
.12012017
a une chance d'être premier !sympy
propose une fonction sympy.isprime
.
from sympy import isprime
Elle marche très bien, et est très rapide !
[isprime(i) for i in [2, 3, 5, 7, 10, 11, 13, 17, 2017]]
[True, True, True, True, False, True, True, True, True]
Pour des nombres de 8 chiffres (c'est tout petit), elle est vraiment rapide :
from numpy.random import randint
%timeit sum([isprime(i) for i in randint(1e8, 1e9-1, 10**4)])
10 loops, best of 3: 64.8 ms per loop
$\implies$ $65 ~\text{ms}$ pour 10000 nombres à tester, ça me semble assez rapide pour ce qu'on veut en faire !
from datetime import datetime
today = datetime.today()
YEAR = today.year
print("On va travailler avec l'année", YEAR, "!")
On va travailler avec l'année 2017 !
C'est ensuite facile de transformer une date en nombre, selon les deux formats.
On utilise le formatage avec .format()
(en Python 3) :
def date_vers_nombre(date):
return int("{:%d%m%Y}".format(date))
def date_vers_nombre_2(date):
return int("{:%m%d%Y}".format(date))
date = datetime(YEAR, 1, 12)
print(date_vers_nombre(date))
print(date_vers_nombre_2(date)) # Le 0 initial est ignoré
12012017 1122017
On peut partir du 1er janvier de cette année, et ajouter des jours un par un.
On utilise un itérateur (avec le mot clé yield
), pour pouvoir facilement boucler sur tous les jours de l'année en cours :
from datetime import timedelta
def tous_les_jours(year=YEAR):
date = datetime(year, 1, 1)
un_jour = timedelta(days=1)
for i in range(0, 366):
yield date
date += un_jour
if date.year > year: # On est allé trop loin
raise StopIteration
On peut vérifier que ça donne ce qu'on voulait :
for date in tous_les_jours():
print("Le jour {:%d/%m/%Y} donne l'entier {:>8} au format jour-mois-année et {:>8} au format mois-jour-année.".format(date, date_vers_nombre(date), date_vers_nombre_2(date)))
Le jour 01/01/2017 donne l'entier 1012017 au format jour-mois-année et 1012017 au format mois-jour-année. Le jour 02/01/2017 donne l'entier 2012017 au format jour-mois-année et 1022017 au format mois-jour-année. Le jour 03/01/2017 donne l'entier 3012017 au format jour-mois-année et 1032017 au format mois-jour-année. Le jour 04/01/2017 donne l'entier 4012017 au format jour-mois-année et 1042017 au format mois-jour-année. Le jour 05/01/2017 donne l'entier 5012017 au format jour-mois-année et 1052017 au format mois-jour-année. Le jour 06/01/2017 donne l'entier 6012017 au format jour-mois-année et 1062017 au format mois-jour-année. Le jour 07/01/2017 donne l'entier 7012017 au format jour-mois-année et 1072017 au format mois-jour-année. Le jour 08/01/2017 donne l'entier 8012017 au format jour-mois-année et 1082017 au format mois-jour-année. Le jour 09/01/2017 donne l'entier 9012017 au format jour-mois-année et 1092017 au format mois-jour-année. Le jour 10/01/2017 donne l'entier 10012017 au format jour-mois-année et 1102017 au format mois-jour-année. Le jour 11/01/2017 donne l'entier 11012017 au format jour-mois-année et 1112017 au format mois-jour-année. Le jour 12/01/2017 donne l'entier 12012017 au format jour-mois-année et 1122017 au format mois-jour-année. Le jour 13/01/2017 donne l'entier 13012017 au format jour-mois-année et 1132017 au format mois-jour-année. Le jour 14/01/2017 donne l'entier 14012017 au format jour-mois-année et 1142017 au format mois-jour-année. Le jour 15/01/2017 donne l'entier 15012017 au format jour-mois-année et 1152017 au format mois-jour-année. Le jour 16/01/2017 donne l'entier 16012017 au format jour-mois-année et 1162017 au format mois-jour-année. Le jour 17/01/2017 donne l'entier 17012017 au format jour-mois-année et 1172017 au format mois-jour-année. Le jour 18/01/2017 donne l'entier 18012017 au format jour-mois-année et 1182017 au format mois-jour-année. Le jour 19/01/2017 donne l'entier 19012017 au format jour-mois-année et 1192017 au format mois-jour-année. Le jour 20/01/2017 donne l'entier 20012017 au format jour-mois-année et 1202017 au format mois-jour-année. Le jour 21/01/2017 donne l'entier 21012017 au format jour-mois-année et 1212017 au format mois-jour-année. Le jour 22/01/2017 donne l'entier 22012017 au format jour-mois-année et 1222017 au format mois-jour-année. Le jour 23/01/2017 donne l'entier 23012017 au format jour-mois-année et 1232017 au format mois-jour-année. Le jour 24/01/2017 donne l'entier 24012017 au format jour-mois-année et 1242017 au format mois-jour-année. Le jour 25/01/2017 donne l'entier 25012017 au format jour-mois-année et 1252017 au format mois-jour-année. Le jour 26/01/2017 donne l'entier 26012017 au format jour-mois-année et 1262017 au format mois-jour-année. Le jour 27/01/2017 donne l'entier 27012017 au format jour-mois-année et 1272017 au format mois-jour-année. Le jour 28/01/2017 donne l'entier 28012017 au format jour-mois-année et 1282017 au format mois-jour-année. Le jour 29/01/2017 donne l'entier 29012017 au format jour-mois-année et 1292017 au format mois-jour-année. Le jour 30/01/2017 donne l'entier 30012017 au format jour-mois-année et 1302017 au format mois-jour-année. Le jour 31/01/2017 donne l'entier 31012017 au format jour-mois-année et 1312017 au format mois-jour-année. Le jour 01/02/2017 donne l'entier 1022017 au format jour-mois-année et 2012017 au format mois-jour-année. Le jour 02/02/2017 donne l'entier 2022017 au format jour-mois-année et 2022017 au format mois-jour-année. Le jour 03/02/2017 donne l'entier 3022017 au format jour-mois-année et 2032017 au format mois-jour-année. Le jour 04/02/2017 donne l'entier 4022017 au format jour-mois-année et 2042017 au format mois-jour-année. Le jour 05/02/2017 donne l'entier 5022017 au format jour-mois-année et 2052017 au format mois-jour-année. Le jour 06/02/2017 donne l'entier 6022017 au format jour-mois-année et 2062017 au format mois-jour-année. Le jour 07/02/2017 donne l'entier 7022017 au format jour-mois-année et 2072017 au format mois-jour-année. Le jour 08/02/2017 donne l'entier 8022017 au format jour-mois-année et 2082017 au format mois-jour-année. Le jour 09/02/2017 donne l'entier 9022017 au format jour-mois-année et 2092017 au format mois-jour-année. Le jour 10/02/2017 donne l'entier 10022017 au format jour-mois-année et 2102017 au format mois-jour-année. Le jour 11/02/2017 donne l'entier 11022017 au format jour-mois-année et 2112017 au format mois-jour-année. Le jour 12/02/2017 donne l'entier 12022017 au format jour-mois-année et 2122017 au format mois-jour-année. Le jour 13/02/2017 donne l'entier 13022017 au format jour-mois-année et 2132017 au format mois-jour-année. Le jour 14/02/2017 donne l'entier 14022017 au format jour-mois-année et 2142017 au format mois-jour-année. Le jour 15/02/2017 donne l'entier 15022017 au format jour-mois-année et 2152017 au format mois-jour-année. Le jour 16/02/2017 donne l'entier 16022017 au format jour-mois-année et 2162017 au format mois-jour-année. Le jour 17/02/2017 donne l'entier 17022017 au format jour-mois-année et 2172017 au format mois-jour-année. Le jour 18/02/2017 donne l'entier 18022017 au format jour-mois-année et 2182017 au format mois-jour-année. Le jour 19/02/2017 donne l'entier 19022017 au format jour-mois-année et 2192017 au format mois-jour-année. Le jour 20/02/2017 donne l'entier 20022017 au format jour-mois-année et 2202017 au format mois-jour-année. Le jour 21/02/2017 donne l'entier 21022017 au format jour-mois-année et 2212017 au format mois-jour-année. Le jour 22/02/2017 donne l'entier 22022017 au format jour-mois-année et 2222017 au format mois-jour-année. Le jour 23/02/2017 donne l'entier 23022017 au format jour-mois-année et 2232017 au format mois-jour-année. Le jour 24/02/2017 donne l'entier 24022017 au format jour-mois-année et 2242017 au format mois-jour-année. Le jour 25/02/2017 donne l'entier 25022017 au format jour-mois-année et 2252017 au format mois-jour-année. Le jour 26/02/2017 donne l'entier 26022017 au format jour-mois-année et 2262017 au format mois-jour-année. Le jour 27/02/2017 donne l'entier 27022017 au format jour-mois-année et 2272017 au format mois-jour-année. Le jour 28/02/2017 donne l'entier 28022017 au format jour-mois-année et 2282017 au format mois-jour-année. Le jour 01/03/2017 donne l'entier 1032017 au format jour-mois-année et 3012017 au format mois-jour-année. Le jour 02/03/2017 donne l'entier 2032017 au format jour-mois-année et 3022017 au format mois-jour-année. Le jour 03/03/2017 donne l'entier 3032017 au format jour-mois-année et 3032017 au format mois-jour-année. Le jour 04/03/2017 donne l'entier 4032017 au format jour-mois-année et 3042017 au format mois-jour-année. Le jour 05/03/2017 donne l'entier 5032017 au format jour-mois-année et 3052017 au format mois-jour-année. Le jour 06/03/2017 donne l'entier 6032017 au format jour-mois-année et 3062017 au format mois-jour-année. Le jour 07/03/2017 donne l'entier 7032017 au format jour-mois-année et 3072017 au format mois-jour-année. Le jour 08/03/2017 donne l'entier 8032017 au format jour-mois-année et 3082017 au format mois-jour-année. Le jour 09/03/2017 donne l'entier 9032017 au format jour-mois-année et 3092017 au format mois-jour-année. Le jour 10/03/2017 donne l'entier 10032017 au format jour-mois-année et 3102017 au format mois-jour-année. Le jour 11/03/2017 donne l'entier 11032017 au format jour-mois-année et 3112017 au format mois-jour-année. Le jour 12/03/2017 donne l'entier 12032017 au format jour-mois-année et 3122017 au format mois-jour-année. Le jour 13/03/2017 donne l'entier 13032017 au format jour-mois-année et 3132017 au format mois-jour-année. Le jour 14/03/2017 donne l'entier 14032017 au format jour-mois-année et 3142017 au format mois-jour-année. Le jour 15/03/2017 donne l'entier 15032017 au format jour-mois-année et 3152017 au format mois-jour-année. Le jour 16/03/2017 donne l'entier 16032017 au format jour-mois-année et 3162017 au format mois-jour-année. Le jour 17/03/2017 donne l'entier 17032017 au format jour-mois-année et 3172017 au format mois-jour-année. Le jour 18/03/2017 donne l'entier 18032017 au format jour-mois-année et 3182017 au format mois-jour-année. Le jour 19/03/2017 donne l'entier 19032017 au format jour-mois-année et 3192017 au format mois-jour-année. Le jour 20/03/2017 donne l'entier 20032017 au format jour-mois-année et 3202017 au format mois-jour-année. Le jour 21/03/2017 donne l'entier 21032017 au format jour-mois-année et 3212017 au format mois-jour-année. Le jour 22/03/2017 donne l'entier 22032017 au format jour-mois-année et 3222017 au format mois-jour-année. Le jour 23/03/2017 donne l'entier 23032017 au format jour-mois-année et 3232017 au format mois-jour-année. Le jour 24/03/2017 donne l'entier 24032017 au format jour-mois-année et 3242017 au format mois-jour-année. Le jour 25/03/2017 donne l'entier 25032017 au format jour-mois-année et 3252017 au format mois-jour-année. Le jour 26/03/2017 donne l'entier 26032017 au format jour-mois-année et 3262017 au format mois-jour-année. Le jour 27/03/2017 donne l'entier 27032017 au format jour-mois-année et 3272017 au format mois-jour-année. Le jour 28/03/2017 donne l'entier 28032017 au format jour-mois-année et 3282017 au format mois-jour-année. Le jour 29/03/2017 donne l'entier 29032017 au format jour-mois-année et 3292017 au format mois-jour-année. Le jour 30/03/2017 donne l'entier 30032017 au format jour-mois-année et 3302017 au format mois-jour-année. Le jour 31/03/2017 donne l'entier 31032017 au format jour-mois-année et 3312017 au format mois-jour-année. Le jour 01/04/2017 donne l'entier 1042017 au format jour-mois-année et 4012017 au format mois-jour-année. Le jour 02/04/2017 donne l'entier 2042017 au format jour-mois-année et 4022017 au format mois-jour-année. Le jour 03/04/2017 donne l'entier 3042017 au format jour-mois-a
Maintenant, il suffit de boucler, de tester si l'entier est premier, et de n'afficher que ceux qui le sont :
def date_premieres(conversion=date_vers_nombre, year=YEAR):
for date in tous_les_jours(year):
if isprime(conversion(date)):
yield date
On peut aussi facilement trouver la prochaine date qui sera première :
def prochaine_date_premiere(date=datetime.today(), conversion=date_vers_nombre):
year = date.year
un_jour = timedelta(days=1)
for i in range(0, 366):
if isprime(conversion(date)):
return date
date += un_jour
if date.year > year: # On est allé trop loin
return None
return None
date = datetime.today()
prochain = prochaine_date_premiere(date)
print("Pour le jour d'aujourd'hui ({:%x}), le prochain jour ayant une date première dans l'année {} est : {:%x} !".format(date, date.year, prochain))
Pour le jour d'aujourd'hui (02/24/17), le prochain jour ayant une date première dans l'année 2017 est : 03/06/17 !
for date in date_premieres(date_vers_nombre):
print("Le jour {:%d/%m/%Y} donne l'entier {:>8} qui est premier !".format(date, date_vers_nombre(date)))
Le jour 03/01/2017 donne l'entier 3012017 qui est premier ! Le jour 11/01/2017 donne l'entier 11012017 qui est premier ! Le jour 12/01/2017 donne l'entier 12012017 qui est premier ! Le jour 18/01/2017 donne l'entier 18012017 qui est premier ! Le jour 27/01/2017 donne l'entier 27012017 qui est premier ! Le jour 29/01/2017 donne l'entier 29012017 qui est premier ! Le jour 01/02/2017 donne l'entier 1022017 qui est premier ! Le jour 02/02/2017 donne l'entier 2022017 qui est premier ! Le jour 04/02/2017 donne l'entier 4022017 qui est premier ! Le jour 08/02/2017 donne l'entier 8022017 qui est premier ! Le jour 10/02/2017 donne l'entier 10022017 qui est premier ! Le jour 17/02/2017 donne l'entier 17022017 qui est premier ! Le jour 20/02/2017 donne l'entier 20022017 qui est premier ! Le jour 23/02/2017 donne l'entier 23022017 qui est premier ! Le jour 06/03/2017 donne l'entier 6032017 qui est premier ! Le jour 09/03/2017 donne l'entier 9032017 qui est premier ! Le jour 10/03/2017 donne l'entier 10032017 qui est premier ! Le jour 13/03/2017 donne l'entier 13032017 qui est premier ! Le jour 18/03/2017 donne l'entier 18032017 qui est premier ! Le jour 27/03/2017 donne l'entier 27032017 qui est premier ! Le jour 31/03/2017 donne l'entier 31032017 qui est premier ! Le jour 02/04/2017 donne l'entier 2042017 qui est premier ! Le jour 08/04/2017 donne l'entier 8042017 qui est premier ! Le jour 17/04/2017 donne l'entier 17042017 qui est premier ! Le jour 21/04/2017 donne l'entier 21042017 qui est premier ! Le jour 23/04/2017 donne l'entier 23042017 qui est premier ! Le jour 24/04/2017 donne l'entier 24042017 qui est premier ! Le jour 26/04/2017 donne l'entier 26042017 qui est premier ! Le jour 27/04/2017 donne l'entier 27042017 qui est premier ! Le jour 08/05/2017 donne l'entier 8052017 qui est premier ! Le jour 10/05/2017 donne l'entier 10052017 qui est premier ! Le jour 11/05/2017 donne l'entier 11052017 qui est premier ! Le jour 31/05/2017 donne l'entier 31052017 qui est premier ! Le jour 09/06/2017 donne l'entier 9062017 qui est premier ! Le jour 13/06/2017 donne l'entier 13062017 qui est premier ! Le jour 21/06/2017 donne l'entier 21062017 qui est premier ! Le jour 22/06/2017 donne l'entier 22062017 qui est premier ! Le jour 25/06/2017 donne l'entier 25062017 qui est premier ! Le jour 28/06/2017 donne l'entier 28062017 qui est premier ! Le jour 14/07/2017 donne l'entier 14072017 qui est premier ! Le jour 15/07/2017 donne l'entier 15072017 qui est premier ! Le jour 17/07/2017 donne l'entier 17072017 qui est premier ! Le jour 21/07/2017 donne l'entier 21072017 qui est premier ! Le jour 01/08/2017 donne l'entier 1082017 qui est premier ! Le jour 07/08/2017 donne l'entier 7082017 qui est premier ! Le jour 08/08/2017 donne l'entier 8082017 qui est premier ! Le jour 17/08/2017 donne l'entier 17082017 qui est premier ! Le jour 19/08/2017 donne l'entier 19082017 qui est premier ! Le jour 22/08/2017 donne l'entier 22082017 qui est premier ! Le jour 28/08/2017 donne l'entier 28082017 qui est premier ! Le jour 31/08/2017 donne l'entier 31082017 qui est premier ! Le jour 03/09/2017 donne l'entier 3092017 qui est premier ! Le jour 16/09/2017 donne l'entier 16092017 qui est premier ! Le jour 21/09/2017 donne l'entier 21092017 qui est premier ! Le jour 27/09/2017 donne l'entier 27092017 qui est premier ! Le jour 30/09/2017 donne l'entier 30092017 qui est premier ! Le jour 03/10/2017 donne l'entier 3102017 qui est premier ! Le jour 12/10/2017 donne l'entier 12102017 qui est premier ! Le jour 24/10/2017 donne l'entier 24102017 qui est premier ! Le jour 26/10/2017 donne l'entier 26102017 qui est premier ! Le jour 27/10/2017 donne l'entier 27102017 qui est premier ! Le jour 01/11/2017 donne l'entier 1112017 qui est premier ! Le jour 02/11/2017 donne l'entier 2112017 qui est premier ! Le jour 05/11/2017 donne l'entier 5112017 qui est premier ! Le jour 14/11/2017 donne l'entier 14112017 qui est premier ! Le jour 16/11/2017 donne l'entier 16112017 qui est premier ! Le jour 22/11/2017 donne l'entier 22112017 qui est premier ! Le jour 03/12/2017 donne l'entier 3122017 qui est premier ! Le jour 22/12/2017 donne l'entier 22122017 qui est premier ! Le jour 24/12/2017 donne l'entier 24122017 qui est premier ! Le jour 30/12/2017 donne l'entier 30122017 qui est premier !
for date in date_premieres(date_vers_nombre_2):
print("Le jour {:%d/%m/%Y} donne l'entier {:>8} qui est premier !".format(date, date_vers_nombre_2(date)))
Le jour 02/01/2017 donne l'entier 1022017 qui est premier ! Le jour 08/01/2017 donne l'entier 1082017 qui est premier ! Le jour 11/01/2017 donne l'entier 1112017 qui est premier ! Le jour 14/01/2017 donne l'entier 1142017 qui est premier ! Le jour 20/01/2017 donne l'entier 1202017 qui est premier ! Le jour 21/01/2017 donne l'entier 1212017 qui est premier ! Le jour 26/01/2017 donne l'entier 1262017 qui est premier ! Le jour 30/01/2017 donne l'entier 1302017 qui est premier ! Le jour 02/02/2017 donne l'entier 2022017 qui est premier ! Le jour 04/02/2017 donne l'entier 2042017 qui est premier ! Le jour 11/02/2017 donne l'entier 2112017 qui est premier ! Le jour 19/02/2017 donne l'entier 2192017 qui est premier ! Le jour 23/02/2017 donne l'entier 2232017 qui est premier ! Le jour 25/02/2017 donne l'entier 2252017 qui est premier ! Le jour 26/02/2017 donne l'entier 2262017 qui est premier ! Le jour 28/02/2017 donne l'entier 2282017 qui est premier ! Le jour 01/03/2017 donne l'entier 3012017 qui est premier ! Le jour 09/03/2017 donne l'entier 3092017 qui est premier ! Le jour 10/03/2017 donne l'entier 3102017 qui est premier ! Le jour 12/03/2017 donne l'entier 3122017 qui est premier ! Le jour 19/03/2017 donne l'entier 3192017 qui est premier ! Le jour 24/03/2017 donne l'entier 3242017 qui est premier ! Le jour 25/03/2017 donne l'entier 3252017 qui est premier ! Le jour 02/04/2017 donne l'entier 4022017 qui est premier ! Le jour 20/04/2017 donne l'entier 4202017 qui est premier ! Le jour 29/04/2017 donne l'entier 4292017 qui est premier ! Le jour 30/04/2017 donne l'entier 4302017 qui est premier ! Le jour 11/05/2017 donne l'entier 5112017 qui est premier ! Le jour 14/05/2017 donne l'entier 5142017 qui est premier ! Le jour 17/05/2017 donne l'entier 5172017 qui est premier ! Le jour 25/05/2017 donne l'entier 5252017 qui est premier ! Le jour 26/05/2017 donne l'entier 5262017 qui est premier ! Le jour 29/05/2017 donne l'entier 5292017 qui est premier ! Le jour 03/06/2017 donne l'entier 6032017 qui est premier ! Le jour 24/06/2017 donne l'entier 6242017 qui est premier ! Le jour 25/06/2017 donne l'entier 6252017 qui est premier ! Le jour 27/06/2017 donne l'entier 6272017 qui est premier ! Le jour 08/07/2017 donne l'entier 7082017 qui est premier ! Le jour 20/07/2017 donne l'entier 7202017 qui est premier ! Le jour 02/08/2017 donne l'entier 8022017 qui est premier ! Le jour 04/08/2017 donne l'entier 8042017 qui est premier ! Le jour 05/08/2017 donne l'entier 8052017 qui est premier ! Le jour 08/08/2017 donne l'entier 8082017 qui est premier ! Le jour 13/08/2017 donne l'entier 8132017 qui est premier ! Le jour 16/08/2017 donne l'entier 8162017 qui est premier ! Le jour 23/08/2017 donne l'entier 8232017 qui est premier ! Le jour 25/08/2017 donne l'entier 8252017 qui est premier ! Le jour 29/08/2017 donne l'entier 8292017 qui est premier ! Le jour 03/09/2017 donne l'entier 9032017 qui est premier ! Le jour 06/09/2017 donne l'entier 9062017 qui est premier ! Le jour 19/09/2017 donne l'entier 9192017 qui est premier ! Le jour 24/09/2017 donne l'entier 9242017 qui est premier ! Le jour 27/09/2017 donne l'entier 9272017 qui est premier ! Le jour 02/10/2017 donne l'entier 10022017 qui est premier ! Le jour 03/10/2017 donne l'entier 10032017 qui est premier ! Le jour 05/10/2017 donne l'entier 10052017 qui est premier ! Le jour 14/10/2017 donne l'entier 10142017 qui est premier ! Le jour 15/10/2017 donne l'entier 10152017 qui est premier ! Le jour 17/10/2017 donne l'entier 10172017 qui est premier ! Le jour 01/11/2017 donne l'entier 11012017 qui est premier ! Le jour 05/11/2017 donne l'entier 11052017 qui est premier ! Le jour 20/11/2017 donne l'entier 11202017 qui est premier ! Le jour 23/11/2017 donne l'entier 11232017 qui est premier ! Le jour 28/11/2017 donne l'entier 11282017 qui est premier ! Le jour 01/12/2017 donne l'entier 12012017 qui est premier ! Le jour 10/12/2017 donne l'entier 12102017 qui est premier ! Le jour 19/12/2017 donne l'entier 12192017 qui est premier ! Le jour 24/12/2017 donne l'entier 12242017 qui est premier ! Le jour 31/12/2017 donne l'entier 12312017 qui est premier !
Il y a 71 jours, en 2017, qui ont une date première si on les écrit "jour mois année", et 69 si on les écrits "mois jour année".
len(list(date_premieres(date_vers_nombre)))
71
len(list(date_premieres(date_vers_nombre_2)))
69
On aimerait afficher une courbe montrant l'évolution du nombre de dates premières au cours des années, selon les deux formats.
def nombres_dates_premieres(year=YEAR):
if year % 2 == 0:
return [0, 0]
else:
return [len(list(date_premieres(date_vers_nombre, year=year))), len(list(date_premieres(date_vers_nombre_2, year=year)))]
nombres_dates_premieres()
[71, 69]
On vérifie que pour les années paires il n'y a pas de dates premières :
len(list(date_premieres(date_vers_nombre, year=2016)))
0
On peut donc récupérer toutes ces nombres, jusqu'à l'année 3000. (On pourrait gagner du temps en ne considérant que les années impaires, et l'année 1)
import numpy as np
def intervale_nombres_dates_premieres(year1=1, year2=3000):
nombres = np.zeros((year2 - year1 + 1, 2))
for i, year in enumerate(range(year1, year2 + 1)):
nombres[i, :] = nombres_dates_premieres(year)
return nombres
On essaie sur un intervale de 11 ans :
%%time
nombres = intervale_nombres_dates_premieres(year1=2010, year2=2020)
print(nombres)
[[ 0. 0.] [ 46. 50.] [ 0. 0.] [ 52. 51.] [ 0. 0.] [ 0. 0.] [ 0. 0.] [ 71. 69.] [ 0. 0.] [ 50. 58.] [ 0. 0.]] CPU times: user 64 ms, sys: 0 ns, total: 64 ms Wall time: 65 ms
%%time
nombres = intervale_nombres_dates_premieres(year1=1, year2=3000)
print(nombres)
[[ 108. 108.] [ 0. 0.] [ 98. 104.] ..., [ 0. 0.] [ 64. 55.] [ 0. 0.]] CPU times: user 15.6 s, sys: 20 ms, total: 15.6 s Wall time: 15.6 s
np.shape(nombres)
(3000, 2)
Quelques statistiques :
print("- Au format jour-mois-année, il y a en moyenne {:.3g} jours premiers par an.".format(np.mean(nombres[:, 0])))
print("- Et en moyenne {:.3g} jours premiers par an, en enlevant les années paires.".format(np.mean(nombres[:, 0][nombres[:, 0] > 0])))
print("- Au format mois-jour-année, il y a en moyenne {:.3g} jours premiers par an.".format(np.mean(nombres[:, 1])))
print("- Et en moyenne {:.3g} jours premiers par an, en enlevant les années paires.".format(np.mean(nombres[:, 1][nombres[:, 1] > 0])))
- Au format jour-mois-année, il y a en moyenne 23.9 jours premiers par an. - Et en moyenne 59.7 jours premiers par an, en enlevant les années paires. - Au format mois-jour-année, il y a en moyenne 25.2 jours premiers par an. - Et en moyenne 63 jours premiers par an, en enlevant les années paires.
On va afficher tout ça :
%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(context="notebook", style="darkgrid", palette="hls", font="sans-serif", font_scale=1.4)
def affiche_nombres_dates_premieres(nombres):
plt.figure()
plt.plot(nombres[:, 0], 'b.', label="Format jour-mois-année")
plt.plot(nombres[:, 1], 'g*', label="Format mois-jour-année")
plt.title("Nombres de dates premières par an")
plt.legend(loc='best', numpoints=1, fancybox=True, shadow=True, framealpha=0.8)
plt.xlabel("Année")
plt.ylabel("Nombre de dates premières")
affiche_nombres_dates_premieres(nombres)
Avec un histogramme :
def hist_nombres_dates_premieres(nombres, ind=0):
nbs = nombres[:, ind]
nbs = nbs[nbs > 0]
plt.figure()
plt.hist(nbs, bins=100, label="Format %s-année" % ('jour-mois' if ind==0 else 'mois-jour'), color='bg'[ind])
plt.title("Répartition du nombres de dates premières par an")
plt.legend(loc='best', numpoints=1, fancybox=True, shadow=True, framealpha=0.8)
plt.xlabel("Nombres de dates premières")
plt.ylabel("Nombres")
hist_nombres_dates_premieres(nombres, 0)
hist_nombres_dates_premieres(nombres, 1)
On peut se poser une autre question : quelle date donne le plus de nombres premiers ?
On a vu que le 23 février donne 23022017
qui est premier, et 24022017
ne l'est pas.
Mais en sur 3000 années successives, est-ce que le 23 février donne plus souvent un nombre premier que le 24 février ?
def meme_jour_toutes_les_annees(days=0, year1=1, year2=3000):
date = datetime(year1, 1, 1)
date += timedelta(days=days)
for i, year in enumerate(range(year1, year2 + 1)):
yield date.replace(year=year)
list(meme_jour_toutes_les_annees(days=31+22, year1=2017, year2=2019))
[datetime.datetime(2017, 2, 23, 0, 0), datetime.datetime(2018, 2, 23, 0, 0), datetime.datetime(2019, 2, 23, 0, 0)]
def nombre_annees_qui_donnent_date_premiere(days=0, year1=1, year2=3000, conversion=date_vers_nombre):
for date in meme_jour_toutes_les_annees(days=days, year1=year1, year2=year2):
if isprime(conversion(date)):
yield date
Par exemple, pour mon anniversaire, entre ma naissance et maintenant, une seule année a donné une date 1201YEAR
qui soit première :
list(nombre_annees_qui_donnent_date_premiere(days=11, year1=1993, year2=2017))
[datetime.datetime(2017, 1, 12, 0, 0)]
Le 23 février a plus de chance :
list(nombre_annees_qui_donnent_date_premiere(days=31+22, year1=1993, year2=2017))
[datetime.datetime(1993, 2, 23, 0, 0), datetime.datetime(2001, 2, 23, 0, 0), datetime.datetime(2017, 2, 23, 0, 0)]
On peut récupérer ces données pour tous les jours de l'année :
def histogramme_par_jours(year1=1, year2=3000, conversion=date_vers_nombre):
jours = np.zeros(366)
for days in range(366):
jours[days] += len(list(nombre_annees_qui_donnent_date_premiere(days=days, year1=year1, year2=year2, conversion=conversion)))
return jours
%%time
jours = histogramme_par_jours(year1=1993, year2=2017)
jours
CPU times: user 124 ms, sys: 0 ns, total: 124 ms Wall time: 126 ms
%%time
jours_format1 = histogramme_par_jours(year1=1, year2=3000, conversion=date_vers_nombre)
jours_format1 /= 3000
CPU times: user 11.9 s, sys: 0 ns, total: 11.9 s Wall time: 11.9 s
%%time
jours_format2 = histogramme_par_jours(year1=1, year2=3000, conversion=date_vers_nombre_2)
jours_format2 /= 3000
CPU times: user 11.8 s, sys: 0 ns, total: 11.8 s Wall time: 11.8 s
Exploitons ces données :
def hist_nombres_dates_premieres(jours, ind=0):
plt.figure()
plt.plot(jours, label="Format %s-année" % ('jour-mois' if ind==0 else 'mois-jour'), color='bg'[ind])
plt.title("Répartition du nombres de dates premières selon la date\nEntre l'an 1 et l'an 3000")
plt.legend(loc='best', numpoints=1, fancybox=True, shadow=True, framealpha=0.8)
plt.xlabel("Jour dans l'année")
plt.ylabel("Fréquence")
hist_nombres_dates_premieres(jours_format1, ind=0)
hist_nombres_dates_premieres(jours_format2, ind=1)
def txt_date_de_jour(days):
date = datetime(year=1, day=1, month=1) + timedelta(days=int(days))
return "{:%d/%m}".format(date)
Sans trop de surprise, c'est le 1er janvier qui gagne, pour les deux cas :
txt_date_de_jour(np.argmax(jours_format1))
txt_date_de_jour(np.argmax(jours_format2))
'01/01'
'01/01'
Mais en enlevant le 1er janvier et le dernier jour de l'année, on trouve une différence :
np.argmax(jours_format1[1:-1])
txt_date_de_jour(_)
np.argmax(jours_format2[1:-1])
txt_date_de_jour(_)
242
'31/08'
7
'08/01'
jour-mois
ou mois-jour
.Ce n'était pas très dur à calculer, mais intéressant.
jour-mois
et le 8 janvier pour le format mois-jour
.C'est tout pour aujourd'hui les amis, allez voir d'autres notebooks si vous êtes curieux !.
See this repository for other Python notebook doing numerical simulations.