Collectionneur de manuels de mathématiques des années 70, je vous propose quelques exercices de 1976 tirés du cahier de vacances PASSEPORT POUR LE CE1.
Exercice sur les bases

En parcourant le livre “Mathematiques et graphismes” de 1985, j’ai trouvé page 41 un programme intéressant en BASIC (pour TO7/Apple/Commodore 64/Oric etc) permettant de tracer une enveloppe de droites (de la forme ax+by+c = 0). En faisant varier a,b et c en fonction d’un paramètre (noté t dans le programme), on obtient des visuels sympathiques :
import turtle
from math import *
from time import sleep
t = turtle.Turtle()
t.hideturtle()
t.pensize(2)
w, h = 800, 600
wn = turtle.Screen()
wn.colormode(255)
t.pencolor(255, 255, 0)
def ex0():
def g(t):
return 2 - t * t, -2 * t, t**3
return g, -5, 5, -2, 1.5, -3, 3
def ex1():
def g(t):
return cos(3 * t), sin(3 * t), sin(t) ** 2
return g, -1, 1, -1.1, 1.1, 0, 2 * pi
def ex2():
def g(t):
return cos(3 * t), sin(3 * t), cos(t)
return g, -1.2, 0.8, -1.2, 1.2, -pi / 2, pi / 2
def ex3():
def g(t):
return cos(t), sin(t), exp(-exp(-t / 5))
return g, -2, 2, -2, 3, -5, 10
def ex4():
def g(t):
return cos(t), sin(t), -sin(t) / t
return g, -0.3, 1.2, -0.9, 0.9, -5, 5
def ex5():
def g(t):
return cos(t), sin(t), -1 - int(t / 2 / pi)
return g, -6, 6, -6, 6, 0, 10 * pi
def ex6():
def g(t):
return cos(t), sin(t), 1 / t
return g, -2, 2, -1, 0.5, -10, 10
def ex7():
def g(t):
return cos(t), sin(t), log10(t)
return g, -4, 4, -4, 4, 0.2, 20
def ex8():
def g(t):
return cos(t), sin(t), t * t * sin(t)
return g, -4, 4, -10, 3, -pi, pi
def ex9():
def g(t):
return cos(t), sin(t), t * t / (1 + t * t)
return g, -1, 1, -1, 1, -2 * pi, 2 * pi
def ex10():
def g(t):
return cos(t), sin(t), (1 - t * t) / (1 + t * t)
return g, -1.5, 1.5, -1.5, 1.5, -2 * pi, 2 * pi
def ex11():
def g(t):
return cos(t), sin(t), sqrt(abs(t))
return g, -4, 4, -4, 4, -10, 10
def ex12():
def g(t):
return cos(t), sin(t), t / (1 + t)
return g, -3, 3, -3, 3, -10, 10
def ex13():
def g(t):
return cos(t), sin(t), 2 + cos(t / 2)
return g, -4, 4, -4, 4, -2 * pi, 2 * pi
def ex14():
def g(t):
return cos(t), sin(t), -0.5 + cos(t / 2)
return g, -2, 2, -2, 2, -2 * pi, 2 * pi
def ex15():
def g(t):
return cos(t), sin(t), t * t * sin(t)
return g, -4, 4, -10, 3, -pi, pi
def ex16():
def g(t):
return cos(t), sin(t), t * t / (1 - t * t)
return g, -1.5, 2, -2, 2, -2 * pi, 2 * pi
def ex17():
def g(t):
return cos(t), sin(t), sin(t) + sin(t) ** 2 / 2 + sin(t) ** 3 / 3
return g, -2, 2, -3, 0, -pi, pi
def tracer(x, y):
global f, pts
if x < xi or x > xs or y < yi or y > ys:
return
f += 1
pts[f] = [
-w / 2 + ceil(w * (x - xi) / (xs - xi)),
-h / 2 + ceil(h * (y - yi) / (ys - yi)),
]
if f == 1 and pts[0] == pts[1]:
f = -1
elif f == 1:
t.penup()
t.goto(pts[0])
t.pendown()
t.goto(pts[1])
t.hideturtle()
for k in range(18):
turtle.Screen().bgcolor(0, 0, 0)
t.clear()
wn.tracer(0)
g, xi, xs, yi, ys, ti, ts = eval("ex" + str(k) + "()")
pts = [[0, 0], [0, 0]]
n = 200
th = (ts - ti) / (n - 1)
for i in range(n):
try: a, b, c = g(ti + i * th)
except: continue
f = -1
if b != 0:
tracer(xi, -(c + a * xi) / b)
tracer(xs, -(c + a * xs) / b)
if a != 0:
tracer(-(c + b * yi) / a, yi)
tracer(-(c + b * ys) / a, ys)
wn.update()
sleep(2)
Simulateur 8080 : https://www.sim8085.com
Création d’un fichier binaire : https://www.asm80.com/
Simulateur ALTAIR 8800 : https://s2js.com/altair/sim.html
Tous les codes (00.MEM = 3n+1, 01.MEM = n/2, 02.MEM = pair/impair + saut, 03.MEM = avec temps de vol, 04.MEM = avec maximum, 16bits.bin = version 16 bits) : https://uabox.univ-angers.fr/s/o96B5MEfeQAcXLA
Chargement d’une bande perforée : https://youtu.be/qv5b1Xowxdk?feature=shared&t=235
Mettre une valeur N en 80h puis lancer le programme ci-dessous
Lire en 80h la valeur 3N+1 (modulo 256)
HEXA : 3A80004787803C32800076
Programme source :
LDA 80h
MOV B, A
ADD A
ADD B
INR A
STA 80h
HLT
Programme objet :
3A 80 00 LDA 80h
47 MOV B, A
87 ADD A
80 ADD B
3C INR A
32 80 00 STA 80h
76 HLT
Mettre une valeur N en 80h puis lancer le programme ci-dessous
Lire en 80h la valeur ENT(N/2)
HEXA : 373F3E1B1F32800076
Programme source :
STC
CMC
MVI A, 27
RAR
STA 80h
HLT
HEXA : 3A800047FE01CA2100E60178CA180087803C328000C30000373F1F328000C3000076
Programme source :
loop: LDA 80h
MOV B, A
CPI 1
JZ fin
ANI 1
MOV A, B
JZ pair
ADD A
ADD B
INR A
STA 80h
JMP loop
pair: STC
CMC
RAR
STA 80h
JMP loop
fin: HLT
HEXA : 3E003281 003A8000 47FE01CA 2E003A81 003C3281 0078E601 78CA2500 87803C32 8000C305 00373F1F 328000C3 050076
Programme source :
MVI A, 0
STA 81h
loop: LDA 80h
MOV B, A
CPI 1
JZ fin
LDA 81h
INR A
STA 81h
MOV A, B
ANI 1
MOV A, B
JZ pair
ADD A
ADD B
INR A
STA 80h
JMP loop
pair: STC
CMC
RAR
STA 80h
JMP loop
fin: HLT
HEXA : 3E003281 003A8000 3282003A 800047FE 01CA4000 3A81003C 32810078 E60178CA 37008780 3C328000 473A8200 B8D20B00 78328200 C30B0037 3F1F3280 00C30B00 76
Programme source :
MVI A, 0
STA 81h
LDA 80h
STA 82h
loop: LDA 80h
MOV B, A
CPI 1
JZ fin
LDA 81h
INR A
STA 81h
MOV A, B
ANI 1
MOV A, B
JZ pair
ADD A
ADD B
INR A
STA 80h
MOV B, A
LDA 82h
CMP B
JNC loop
MOV A, B
STA 82h
JMP loop
pair: STC
CMC
RAR
STA 80h
JMP loop
fin: HLT
Mettre la partie basse de N en 80h et la partie haute en 81h. Par exemple pour 27 : 00 011 011 en 80h et 00 000 000 en 81h
Lire le temps de vol en 84h et le maximum aux adresses 82h (partie basse) et 83h (partie haute)
2A 80 00 LHLD 80H ; Initialisation des mémoires 82h à 84h
22 82 00 SHLD 82H ; copie de 80-81h vers 82-83h
21 84 00 LXI H, 84H ;
36 00 MVI M, 0 ; Temps de vol = 0
21 81 00 collatz: LXI H, 81H
7E MOV A, M ; Si la valeur haute
B7 ORA A ; n'est pas nulle
C2 1A 00 JNZ parity ; On va tester la parité
2B DCX H ; sinon,
7E MOV A, M ; Si la valeur basse
FE 01 CPI 1 ; vaut 1
CA 5D 00 JZ fin ; on arrête le programme
21 84 00 parity:LXI H, 84H
34 INR M ; temps de vol augmente de +1
21 80 00 LXI H, 80H
7E MOV A, M
5F MOV E, A ; que l'on stocke dans E
E6 01 ANI 1 ; Si Z = 0
CA 3A 00 JZ pair ; C'est un nombre pair
23 INX H
56 MOV D, M
D5 PUSH D
E1 POP H ; HL = DE
29 DAD H ; HL = 2HL
19 DAD D ; HL = 3HL
23 INX H ; HL = 3HL + 1
22 80 00 SHLD 80h ; Nouvelle valeur en 80h
E5 PUSH H
D1 POP D ; On la stocke dans DE
CD 46 00 CALL maxi ; Sous-routine maxi
C3 0B 00 JMP collatz ; Retour à collatz
23 pair: INX H ; Si le nombre est pair
AF XRA A ; Carry = 0
7E MOV A, M ; Division par 2
1F RAR ; de la partie haute
77 MOV M, A
2B DCX H
7E MOV A, M ; division par 2 de la partie basse
1F RAR ; avec ajout éventuel de C à gauche
77 MOV M, A ;
C3 0B 00 JMP collatz ; Retour à collatz
2A 82 00 maxi: LHLD 82H ;
7A MOV A, D ; Récup partie haute du max
BC CMP H ; si égalité des parties hautes
CA 52 00 JZ unite ; tester les unités
D2 58 00 JNC change ; si retenue le max a été dépassé
C9 RET ; sinon ne rien faire
7B unite: MOV A, E ; test des unités
BD CMP L ; si une retenue
DA 58 00 JC change ; le max est dépassé
C9 RET ; retour
EB change: XCHG ; HL = DE
22 82 00 SHLD 82H ; que l'on place en 82h
C9 RET
76 fin: HLT
Résultats à obtenir aux adresses 82-83h et 84h
00 010 000 en 82h (partie basse) et 00 100 100 en 83h (haut)
parseInt('0010010000010000',2)
9232
01 101 111 à l'adresse 84h :
parseInt('01101111',2)
111
Résultats pour N = 639
>>> bin(639)
'0b1001111111'
Il faut donc mettre 01 111 111 à l'adresse 80h et 10 à l'adresse 81h
On lance le programme et on trouve :
Adresse 82h : 00 110 100
Adresse 83h : 10 100 010
Le maximum vaut donc :
>>> int('1010001000110100',2)
41524
Et le temps de vol est à l'adresse 84h : 10 000 011
>>> int('10000011',2)
131
Sur cette page de Wolfram, on peut voir différentes fractales :
Et en bas de cette même page les algorithmes utilisés pour transformer les cases :
Ci-dessous un programme Python qui permet d’appliquer le motif voulu, il suffit d’indiquer les coordonnées des cases blanches. Par exemple pour le (a), la seule case blanche est au milieu (coordonnées (1,1))
from PIL import Image, ImageDraw
import numpy as np
# Dimensions de l'image finale (à modifier comme vous le voulez)
source = Image.new("RGB", (600, 600), color="white")
draw = ImageDraw.Draw(source)
# Recherche s'il y a une case blanche
def has_common(str1, str2, pattern):
min_len = min(len(str1), len(str2))
for i in range(1, min_len + 1):
for p in pattern:
# Ne pas afficher si on trouve une case blanche
if str1[-i] == p[0] and str2[-i] == p[1]:
return False
# Sinon case noire
return True
# Construction de la fractale
def fractal(pattern):
# On parcourt les colonnes
for c in range(600):
# Convertir 'c' en base 3 (ici à l'aide de numpy)
t1 = np.base_repr(c, base=3)
# On parcourt les lignes
for l in range(600):
t2 = np.base_repr(l, base=3)
# Si pas de case blanche, afficher le point
if has_common(t1, t2, pattern):
draw.point((c, l), fill=(0, 0, 0))
# Exemple avec le tapis de Sierpiński
fractal(["11"])
source.show()
Et on peut en inventer de nouveaux :
Écrire un programme qui cherche tous les mots de 5 lettres pouvant être formés à partir de mots de 9 lettres en prenant 1 lettre sur 2, en commençant par la première lettre. Exemples :
Vous pouvez utiliser ces 2 dictionnaires (mots de 9 et 5 lettres) : https://uabox.univ-angers.fr/s/b3GotFzpTYkL4MT
with open('dictionary_9.txt', 'r') as f:
dictionary_9 = [line.strip() for line in f]
with open('dictionary_5.txt', 'r') as f:
dictionary_5 = set(line.strip() for line in f)
compte = 0 # Nb de mots trouvés
for word9 in dictionary_9:
word5 = word9[::2] # une lettre sur deux
if word5 in dictionary_5: # Si le mot existe
print(word9, word5) # on l'affiche
compte += 1 # et le compteur augmente de +1
print(f"Total = {compte}")
Résultat :
ABLATIONS ALTOS
ABLUTIONS ALTOS
ABREGEAIS ARGAS
ABROGEAIS ARGAS
ABSTIENNE ASINE
ACCONIERS ACNES
...
VIELLEUSE VELUE
VIELLIONS VELOS
VIENDRAIS VEDAS
VOILETTES VIETS
Total = 913
Cliquez sur ce lien puis bouton droit – Inspecter – Console. Copiez-collez le code suivant :
dictionary_9.reduce((a, m) => {
var mot5 = m.slice(0,2)+m[4]+m.slice(-2);
return dictionary_5.includes(mot5) ? [...a, [m, mot5]] : a
}, [])
Identifiez tous les mots de 10 lettres qui peuvent être composés de 2 mots de 5 lettres en respectant l’ordre des lettres. Exemple : RACHIDIENS s’écrit à partir de CHIEN et RADIS
Comme il y a beaucoup de solutions, on peut créer une fonction qui admet en paramètre un mot de 5 lettres et qui renvoie tous les mots de 10 lettres contenant ce mot ainsi que l’autre mot de 5 lettres pour compléter. Exemples :
>>> trouve("CHIEN")
BANCHAIENT CHIEN BANAT
CHARMAIENT CHIEN ARMAT
CHERRAIENT CHIEN ERRAT
CHIADERENT CHIEN ADRET
CHIENDENTS CHIEN DENTS
CHTHONIENS CHIEN THONS
CHTONIENNE CHIEN TONNE
CRASHAIENT CHIEN RASAT
DOUCHAIENT CHIEN DOUAT
LOUCHAIENT CHIEN LOUAT
MATCHAIENT CHIEN MATAT
RACHIDIENS CHIEN RADIS
TOUCHAIENT CHIEN TOUAT
TRICHAIENT CHIEN TRIAT
with open('dictionary_10.txt', 'r') as f:
dictionary_10 = [line.strip() for line in f]
with open('dictionary_5.txt', 'r') as f:
dictionary_5 = set(line.strip() for line in f)
def is_included(word1, word2):
positions = []
index = 0
for letter in word2:
index = word1.find(letter, index)
if index == -1: return False
positions.append(index)
index += 1
return positions
def trouve(word5):
for word10 in dictionary_10:
positions = is_included(word10, word5)
if positions:
reste = ''.join(word10[i] for i in range(10) if i not in positions)
if reste in dictionary_5:
print(word10, word5, reste)
Ci-dessous un jeu très simple trouvé dans le journal TV Télé Z. Dans notre cas nous allons travailler avec des mots de 9 et 5 lettres.
But : créer un programme qui, à partir d’une liste de mots de 5 lettres, va rechercher autant de mots de 9 lettres les contenant.
>>> jeu(["AIDER","CAPTER","GAINE","LOGER","FILES"])
PYRAMIDER AIDER PYR-M----
CAPTERAIT CAPTER ------AIT
GRAINIERS GAINE -R---I-RS
PLONGEOIR LOGER P--N--OI-
FILONIENS FILES ---ONI-N-
from random import choice
with open('dictionary_9.txt', 'r') as f:
dictionary_9 = [line.strip() for line in f]
with open('dictionary_5.txt', 'r') as f:
dictionary_5 = set(line.strip() for line in f)
def is_included(word1, word2):
positions = []
index = 0
for letter in word2:
index = word1.find(letter, index)
if index == -1: return False
positions.append(index)
index += 1
return positions
def trouve(word5):
res = [] # On cherche toutes les solutions
for word9 in dictionary_9:
positions = is_included(word9, word5)
if positions: res.append((word9, positions))
if len(res) > 0: return choice(res) # on renvoie une solution au hasard
return False
def jeu(arr):
for mot in arr:
r = trouve(mot)
if r: # Si un mot de 9 lettres a été trouvé
cache = ''.join(r[0][i] if i not in r[1] else '-' for i in range(9))
print(r[0], mot, cache)
else: print(f"Rien trouvé pour {mot}")
Pas Touches
01 2
02 Kin ÷ 1 # n / 2
03 Kout 1
04 -
05 1
06 Kin + 3 # TOF = TOF + 1
07 =
08 1/x # Si n = 1 arrêt sur une erreur
09 Kout 1
10 -
11 RND # Partie entière quand on est en FIX 0
12 +
13 .
14 5
15 = # Si n est pair on obtient 1 et 0 sinon
16 x > 0 # Retour pas n°1 si n pair
17 6 # Sinon...
18 Kin × 1
19 1
20 Kin + 1 # 3n+1
21 Kout 1
22 x ≤ M # Si n <= max retour au pas n°1
23 Min # sinon mise à jour du max
24 x > 0
Exemple d’utilisation pour N = 27 puis N = 17 :
MODE FIX 0
KAC
27 Min Kin 1 P1
Le programme s'arrête sur -E-
AC puis MR pour voir le maximum (9232) et Kout 3 pour le temps de vol (111)
Pour un autre calcul faire :
KAC
17 Min Kin 1 P1
Résultats : max = 52 et TOF = 12
Programme P1 :
001 Min
002 1
003 Kin 1
004 Mode 7 0 # Fix 0
Programme P2 :
001 MR
002 ÷
003 1
004 Kin + 1
005 Kout 1
006 -
007 RND
008 =
009 x > 0
010 +/-
011 x > 0 # Cela revient à tester x ≠ 0
012 Kout 1
013 HLT
014 1/x
015 ×
016 MR
017 =
018 Min
019 1
020 Kin - 1
021 Kout 1
022 x ≤ M
023 AC
Utilisation : Décomposition de 2024 en facteurs premiers
2024 P1
P2
Affichage : 2
RUN
Affichage : 2
RUN
Affichage : 2
RUN
Affichage : 11
RUN
Affichage : 23
RUN
0
Donc 2024 = 2 × 2 × 2 × 11 × 23
Lorsque le nombre est premier :
13 P1
P2
Affichage : 13
RUN
0
import threading
import time
# Nombre de tickets disponibles (ressource partagée)
nb_tickets = 10
def achat_ticket():
global nb_tickets
if nb_tickets > 0:
# Simuler une lecture de la base de données
current_tickets = nb_tickets
# Simuler un délai
time.sleep(0.1)
# Simuler une écriture dans la base de données
nb_tickets = current_tickets - 1
print(f"Ticket acheté, tickets restants : {nb_tickets }\n")
else: print("Plus de tickets disponibles.\n")
# Plusieurs utilisateurs essayant d'acheter des tickets en même temps
for _ in range(20):
threading.Thread(target=achat_ticket).start()
import threading
import time
# Nombre de tickets disponibles (ressource partagée)
nb_tickets = 10
lock = threading.Lock()
def achat_ticket():
global nb_tickets
with lock:
if nb_tickets > 0:
# Simuler une lecture de la base de données
current_tickets = nb_tickets
# Simuler un délai
time.sleep(0.1)
# Simuler une écriture dans la base de données
nb_tickets = current_tickets - 1
print(f"Ticket acheté, tickets restants : {nb_tickets }\n")
else: print("Plus de tickets disponibles.\n")
# Plusieurs utilisateurs essayant d'acheter des tickets en même temps
for _ in range(20):
threading.Thread(target=achat_ticket).start()
import sqlite3
def buy_ticket(event_name):
try:
# Connexion à la base de données SQLite (ou création de la base si elle n'existe pas)
conn = sqlite3.connect('example.db')
cursor = conn.cursor()
# Démarrer une transaction
cursor.execute('BEGIN TRANSACTION')
# Étape 1 : Vérifier le nombre de tickets disponibles
cursor.execute('SELECT available_tickets FROM tickets WHERE event_name = ?', (event_name,))
result = cursor.fetchone()
if result is None:
print(f"Événement '{event_name}' introuvable.")
conn.rollback()
return
available_tickets = result[0]
print(f"Tickets disponibles avant l'achat : {available_tickets}")
if available_tickets > 0:
# Étape 2 : Réserver un ticket
cursor.execute('UPDATE tickets SET available_tickets = available_tickets - 1 WHERE event_name = ?', (event_name,))
print("Achat réussi !")
# Valider la transaction
conn.commit()
else:
print("Échec de l'achat : plus de tickets disponibles.")
conn.rollback()
except sqlite3.Error as e:
print(f"Erreur SQL : {e}")
conn.rollback()
finally:
conn.close()
# Exemple d'utilisation avec plusieurs "acheteurs"
if __name__ == "__main__":
# Création de la table et insertion initiale (exécuté une seule fois)
conn = sqlite3.connect('example.db')
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS tickets (
id INTEGER PRIMARY KEY AUTOINCREMENT,
event_name TEXT NOT NULL,
available_tickets INTEGER NOT NULL
)
''')
cursor.execute('INSERT INTO tickets (event_name, available_tickets) VALUES (?, ?)', ('concert', 100))
conn.commit()
conn.close()
# Simulation d'achats concurrents
for _ in range(55): buy_ticket('concert')
from datetime import datetime
import pytz
# Obtenir l'heure actuelle en UTC
utc_now = datetime.now(pytz.utc)
print(f"Heure actuelle en UTC : {utc_now}")
for endroit in 'Europe/Paris', 'America/New_York', 'Africa/Cairo', 'Australia/Sydney', 'Asia/Tokyo', 'Antarctica/Troll':
local_tz = pytz.timezone(endroit)
local_time = utc_now.astimezone(local_tz)
print(f"Heure locale {endroit} : {local_time}")
Remarque sur les calculatrices TI : comme précisé dans la vidéo, la fonction dbd des TI-82/83/84 permet de trouver le nombre de jours entre 2 dates entre 1950 et 2049. Cependant, sur les TI-84 Plus CE cette plage a été décalée à l’intervalle 1980 – 2079.
import datetime
from datetime import timezone
dt = datetime.datetime(2024,8,5,14,33,17, tzinfo=timezone.utc)
>>> dt.timestamp()
1722868397.0
import time
>>> time.gmtime(1722868397.0)
time.struct_time(tm_year=2024, tm_mon=8, tm_mday=5, tm_hour=14, tm_min=33, tm_sec=17, tm_wday=0, tm_yday=218, tm_isdst=0)
>>> time.gmtime(0)
time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0)
>>> time.gmtime(-2000 * 365 * 86400)
time.struct_time(tm_year=-29, tm_mon=5, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=5, tm_yday=121, tm_isdst=0)
>>> time.time()
1722867076.132498
>>> datetime.datetime.now(timezone.utc).timestamp()
def paques(annee):
cycle_lune = 29.53058853
j_sem = 6 # Samedi 5/1/1901
delta = nb_jours(5, 1, 1901, 21, 3, annee)
nb_cycles = 1 + int(delta / cycle_lune)
ajout = int(nb_cycles * cycle_lune)
while (j_sem + ajout) % 7 != 0: ajout +=1
nb = ajout - delta
if nb <= 10: j, m = 21 + nb, 3
else: j, m = nb - 10, 4
return (m, j)
def formule(j,m,a):
if m < 3:
a -= 1
m += 12
return int(365.25 * a) + int(30.6 * (m + 1)) + j - 3
def nb_jours(j1, m1, a1, j2, m2, a2):
return formule(j2, m2, a2) - formule(j1, m1, a1)
def dow(j,m,a): return 1 + (formule(j,m,a) % 7)
def easter(annee):
a = annee % 19
b = annee // 100
c = annee % 100
d = b // 4
e = b % 4
f = (b + 8) // 25
g = (b - f + 1) // 3
h = (19 * a + b - d - g + 15) % 30
i = c // 4
k = c % 4
l = (32 + 2 * e + 2 * i - h - k) % 7
m = (a + 11 * h + 22 * l) // 451
mois = (h + l - 7 * m + 114) // 31
jour = ((h + l - 7 * m + 114) % 31) + 1
return (annee, mois, jour)
import math
def nb_diviseurs(n):
count = 0
for i in range(1, int(math.sqrt(n)) + 1):
if n % i == 0:
if n == i * i: count += 1
else: count += 2
return count
maxi = 0
for n in range(1, 100):
t = nb_diviseurs(n)
if t > maxi:
print(f"{n} a {t} diviseurs")
maxi = t
# Résultats :
1 a 1 diviseur
2 a 2 diviseurs
4 a 3 diviseurs
6 a 4 diviseurs
12 a 6 diviseurs
24 a 8 diviseurs
36 a 9 diviseurs
48 a 10 diviseurs
60 a 12 diviseurs
mois_jours = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
def est_bissextile(annee):
return (annee % 4 == 0 and annee % 100 != 0) or annee % 400 == 0
def jours_dans_annee(jour, mois, annee):
jours = jour
for m in range(1, mois):
jours += mois_jours[m - 1]
if mois > 2 and est_bissextile(annee): jours += 1
return jours
def jours_entre_dates(j1, m1, a1, j2, m2, a2):
if (a1, m1, j1) > (a2, m2, j2):
j1, m1, a1, j2, m2, a2 = j2, m2, a2, j1, m1, a1
jours_total = 0
if a1 == a2:
return jours_dans_annee(j2, m2, a2) - jours_dans_annee(j1, m1, a1)
jours_total += (366 if est_bissextile(a1) else 365) - jours_dans_annee(j1, m1, a1)
jours_total += jours_dans_annee(j2, m2, a2)
for annee in range(a1 + 1, a2):
jours_total += 366 if est_bissextile(annee) else 365
return jours_total
# Exemple
>>> jours_entre_dates(15,10,1582,4,8,2024)
161366
Disp "JJMM.AA ?"
Input D
Disp "LONGITUDE ?"
Input L
dbd(101+fPart(D),D→N
2π(N-81)/365→B
7.678sin(B+1.374)-9.87sin(2B)→E
Disp "CULMINATION"
12+E/60-L/15▸DMS
Disp "CULMINATION"
Disp "HH°MM'SS''?"
Input H
getDate→L₁
100L₁(3)+L₁(2)+remainder(L₁(1),100)/100→D
dbd(101+fPart(D),D→N
2π(N-81)/365→B
7.678sin(B+1.374)-9.87sin(2B)→E
Disp "LONGITUDE :"
15*(12+E/60-H)
cycle_lunaire = 29.53058853
delta = cycle_lunaire / 8
phases = "Nouvelle lune","Premier croissant","Premier quartier", "Gibbeuse croissante","Pleine lune","Gibbeuse décroissante","Dernier quartier","Dernier croissant"
visuel = ['🌑','🌒','🌓','🌔','🌕','🌖','🌗','🌘']
def phase_lune(nb_jours):
nb_cycles = int(nb_jours / cycle_lunaire)
reste = nb_jours - nb_cycles * cycle_lunaire
tranche = int(round(reste / delta, 0) % 8)
return phases[tranche], visuel[tranche]
>>> phase_lune(365)
('Gibbeuse croissante', '🌔')
def zodiaque_chinois(annee):
elements = "Bois", "Feu", "Terre", "Métal", "Eau"
aspects = "Yang", "Yin"
signes_zodiaque = (
"Rat", "Buffle", "Tigre", "Lapin", "Dragon", "Serpent",
"Cheval", "Chèvre", "Singe", "Coq", "Chien", "Cochon"
)
annee_ref = 1924 # Année du Rat, début d'un cycle de 60 ans
diff_annees = annee - annee_ref
ind_signe_zodiaque = diff_annees % 12
ind_aspect = diff_annees % 2
ind_element = (diff_annees % 10) // 2
signe_zodiaque = signes_zodiaque[ind_signe_zodiaque]
aspect = aspects[ind_aspect]
element = elements[ind_element]
annee_chinoise = annee_ref + (diff_annees % 60)
return f"{annee_chinoise} : {signe_zodiaque} ({element} {aspect})"
>>> zodiaque_chinois(2024)
1964 : Dragon (Bois Yang)
def bissextile_julien(annee):
return annee % 4 == 0
def bissextile_gregorien(annee):
return (annee % 4 == 0 and annee % 100 != 0) or (annee % 400 == 0)
def bissextile_perso(annee):
return annee % 4 == 0 and annee % 128 != 0
def compare(ans, methode):
total = 0
for an in range(ans):
total += 365
if methode(an): total += 1
return total - 365.2421904482 * ans
>>> compare(10000, bissextile_julien)
78.09551799995825
>>> compare(10000, bissextile_gregorien)
3.095517999958247
>>> compare(10000, bissextile_perso)
-0.904482000041753