RETROGICIEL
RECHERCHE AMICALE
RETROGICIEL
RECHERCHE AMICALE
⇩. Présentation
Deux nombres amicaux sont des nombres qui ont une relation spéciale. Bien que connus depuis l'Antiquité, ils sont assez rares et se rencontrent obligatoirement par paire. On les dit amicaux, car ils semblent “se rendent la pareille”. Bien qu'aucun écrit direct de Pythagore ne prouve qu’il les aurait étudiés, on attribue traditionnellement leur découverte à son école. Les pythagoriciens considéraient les nombres amicaux comme un symbole d’amitié et d’harmonie.
Soit deux nombres entiers strictement positifs, A et B. A et B sont des nombres amicaux si la somme des diviseurs stricts (c’est-à-dire tous les diviseurs sauf le nombre lui-même) de A est égale à B ET si la somme des diviseurs stricts de B est égale à A. Par exemple, les nombres 220 et 284 sont amicaux car la sommes des diviseurs stricts de :
- 220 est : 1 + 2 + 4 + 5 + 10 + 11 + 20 + 22 + 44 + 55 + 110 = 284
- 284 est : 1 + 2 + 4 + 71 + 142 = 220.
Donc pour savoir si un entier N, >1, possède un nombre ami, on calcule S1, la somme de ses diviseurs stricts, puis S2, la somme des diviseurs stricts de S1. Si S2 = N et si S1 ≠ N alors N et S1 sont des nombres amicaux.
⇩. Consignes
Le programme doit :
demander 1 nombre entier à l'utilisateur (N) ;
vérifier qu'il est bien un nombre entier > 1 ;
faire la somme des diviseurs stricts de N (S1) ;
si N ≠ S1 ;
faire la somme des diviseurs stricts de S1 (S2) ;
évaluer si N = S2 ;
- afficher N a un nombre ami ou non ;
- demander si l'utilisateur souhaite recommencer ou ;
- quitter le programme.
D'abord, faite-le fonctionner. Ensuite, faite-le beau. Enfin, faite-le performant.
Amusez-vous bien !
Télécharger RETROGICIEL - Recherche amicale.
Cette présentation nécessite que Python 3 soit installé sur votre machine.
Après avoir téléchargé le fichier Le poids ideal.7z, décompressez-le dans le répertoire de votre choix.
Ouvrez le répertoire qui vient d'être créé.
Lancez le fichier Retrogiciel.py.
Cliquez sur l'onglet RUN et testez le programme.
Créez votre propre script dans un des langages proposés ou un autre de votre choix.
Le répertoire contient aussi :
- Python.py, l'exemple en PYTHON sans tkinter ;
- Tkinter.py, l'exemple en PYTHON avec tkinter ;
- Qb84.bas, l'exemple en QBASIC avec qb64 ;
- Bbc.bas, l'exemple en BBC BASIC avec bbc sdl.
# --- Origine Nerd ---
# --- RETROGICIEL - PYTHON ---
# ---Recherche amicale ---
# -*- coding: utf-8 -*-
# --- DÉFINITION DES FONCTIONS PERSONNALISEES ---
# --- Décomposition d'un nombre en ses diviseurs stricts ---
def FNC_Decomposition ( Q ) :
# --- Recherche des diviseurs stricts ---
kdiviseurs = [ 1 ]
kracine = int ( Q ** .5 )
for kvaleur in range ( 2 , ( kracine + 1 ) ) :
if Q % kvaleur == 0 :
kpaire = [ kvaleur , ( Q // kvaleur ) ] if kvaleur != ( Q // kvaleur ) else [ kvaleur ]
kdiviseurs.extend ( kpaire )
kdiviseurs.sort ( )
print ( f"\nLes diviseurs strict de { Q } sont : " )
print ( kdiviseurs )
return sum ( kdiviseurs )
# --- PRESENTATION ---
print ( "LES NOMBRES AMICAUX.\n" )
# --- BOUCLE PRINCIPALE ---
while True :
# --- Saisie et controle du nombre entier de référence ---
while True :
try :
knombre_A = int ( input ( f"Saisissez le nombre de référance ... " ) )
if knombre_A < 1 : raise ValueError
break
except :
print ( "ERREUR DE SAISIE !" )
print ( "Vous devez saisir un nombre entier strictement positif.\n" )
# --- Calcul de la somme des diviseurs stricts du nombre de référence ---
ksomme_A = FNC_Decomposition ( knombre_A )
print ( f"La sommes des diviseurs stricts de { knombre_A } est { ksomme_A }." )
# --- Calcul de la somme des diviseurs stricts de cette somme ---
ksomme_B = FNC_Decomposition ( ksomme_A )
print ( f"La sommes des diviseurs stricts de { ksomme_A } est { ksomme_B }." )
# --- Comparaison du nombre de référence et de la deuxième somme ---
if knombre_A == ksomme_B : print ( f"\nLe { knombre_A } a comme nombre amical l'entier { ksomme_B }." )
else : print ( f"\nIl n'y a pas de nombre entier qui soit l'amical de { knombre_A }." )
# --- Choix du bouclage du programme ---
kchoix = input ( "\nVoulez-vous recommencer (O ou N) ?" )
if kchoix.upper ( ) == "N" : break
# --- FIN DU PROGRAMME ---
print ( "Au revoir" )
# --- Programme : JFB ---
# --- Avril 2026 ---
# --- Fin ---
Pour mieux comprendre l'exemple en PYTHON sans tkinter.
# --- Origine Nerd ---
# --- RETROGICIEL - TKINTER ---
# --- Recherche amicale ---
# -*- coding: utf-8 -*-
# --- IMPORTATION DES MODULES ---
# --- Modules de la bibliothèque standard ---
import tkinter
# --- DÉFINITION DES FONCTIONS PERSONNALISEES ---
# --- Comparaisons d'un nombre et de la somme des diviseurs de l'autre nombre ---
def FNC_Comparaison ( ) :
# --- Recheche des diviseurs stricts de la somme et calcul leur somme ---
kmessage = f"La somme des diviseurs de { TKV_Nombre.get ( ) } est { TKV_Somme.get ( ) }.\n"
kdiviseurs = FNC_Decomposition ( TKV_Somme.get ( ) )
BOX_Liste_B.delete ( 0 , "end" )
BOX_Liste_B.insert ( 0 , *kdiviseurs )
ksomme = sum ( kdiviseurs )
kmessage += f"La somme des diviseurs de { TKV_Somme.get ( ) } est { ksomme }.\n"
# --- Evaluation de la rechercje d'un nombre ---
if TKV_Nombre.get ( ) == ksomme :
LAB_Message [ "background" ] = "yellow"
LAB_Message [ "foreground" ] = "red"
LAB_Message [ "text" ] = kmessage + f"\n{ TKV_Nombre.get ( ) } a comme nombre ami { TKV_Somme.get ( ) }."
else :
LAB_Message [ "background" ] = "aqua"
LAB_Message [ "foreground" ] = "blue"
LAB_Message [ "text" ] = kmessage + f"\n{ TKV_Nombre.get ( ) } n'a pas de nombre ami."
# --- Décomposition d'un nombre en ses diviseurs stricts ---
def FNC_Decomposition ( Q ) :
kdiviseurs = [ 1 ]
kracine = int ( Q ** .5 )
for kvaleur in range ( 2 , ( kracine + 1 ) ) :
if Q % kvaleur == 0 :
kpaire = [ kvaleur , ( Q // kvaleur ) ] if kvaleur != ( Q // kvaleur ) else [ kvaleur ]
kdiviseurs.extend ( kpaire )
kdiviseurs.sort ( )
return kdiviseurs
# --- Controle les modifications et acttualise les controles ---
def FNC_Saisie ( *Qevent ) :
BOX_Liste_A.delete ( 0 , "end" )
try :
kentier = int( TKV_Nombre.get ( ) )
if kentier < 2 : raise
else : TKV_Nombre.set ( kentier )
kdiviseurs = FNC_Decomposition ( kentier )
BOX_Liste_A.insert ( 0 , *kdiviseurs )
TKV_Somme.set( sum ( kdiviseurs ) )
LAB_Somme [ "text" ] = TKV_Somme.get ( )
FNC_Comparaison ( )
except :
TKV_Nombre.set ( 0 )
LAB_Message [ "background" ] = "white"
LAB_Message [ "foreground" ] = "black"
LAB_Message [ "text" ] = "ERREUR DE SAISIE !"
# --- CREATION DE L'INTERFACE GRAPHIQUE ---
# --- Création de la fenêtre principale ---
TKI_Principal = tkinter.Tk ( )
TKI_Principal.title ( "RETROGICIEL - Recherche amicale" )
# --- Création des variables de controles ---
TKV_Nombre = tkinter.IntVar()
TKV_Somme = tkinter.IntVar()
# --- Création des controles nommées ---
ENT_Nombre = tkinter.Entry ( TKI_Principal , textvariable = TKV_Nombre , width = 12 )
BOX_Liste_A = tkinter.Listbox ( TKI_Principal , height = 4 )
BOX_Liste_B = tkinter.Listbox ( TKI_Principal , height = 4 )
LAB_Message = tkinter.Label ( TKI_Principal , relief = "solid" , bd = 3 , height = 5 )
LAB_Somme = tkinter.Label ( TKI_Principal , textvariable = TKV_Somme , relief = "solid" )
# --- Mise en place des controles (anonymes et nommés) dans la fenêtre principale ---
tkinter.Label ( TKI_Principal , text = "LISTES DES DIVISEURS" ).grid( row = 0 , column = 1 , sticky = "nesw" )
tkinter.Label ( TKI_Principal , text = "NOMBRE" ).grid( row = 1 , column = 0 , sticky = "s" )
BOX_Liste_A.grid( row = 1 , column = 1 , rowspan = 2 , sticky = "nesw" )
ENT_Nombre.grid( row = 2 , column = 0 , sticky = "nesw" )
tkinter.Label ( TKI_Principal , text = "SOMME" ).grid( row = 3 , column = 0 , sticky = "s" )
BOX_Liste_B.grid( row = 3 , column = 1 , rowspan = 2 , sticky = "nesw" )
LAB_Somme.grid( row = 4 , column = 0 , sticky = "nesw" )
LAB_Message.grid( row = 5 , column = 0 , columnspan = 3 , sticky = "nesw" )
tkinter.Button ( TKI_Principal , text = "Quitter" , command = TKI_Principal.destroy ).grid ( row = 0 , column = 2 , rowspan = 5 , sticky = "nesw" )
# --- Création du Gestionnaire d'événements ---
TKV_Nombre.trace ( "w" , FNC_Saisie )
# --- Mise à jour de controle ---
TKV_Nombre.set( 0 )
# --- DEBUT DU PROGRAMME ---
TKI_Principal.mainloop ( )
# --- Programme : JFB ---
# --- Avril 2026 ---
# --- Fin ---
Pour mieux comprendre l'exemple en PYTHON avec tkinter.
' --- Origine Nerd propose pour ---
' --- RETROGICIEL - QB64 ---
' --- Recherche amicale ---
' --- INITIALISATION GENERALE ---
DIM SHARED LST_Diviseurs~&&(500)
' --- BOUCLE PRINCIPALE ---
DO
' --- Saisie du nombre a tester ---
CLS: PRINT "RECHERCHE AMICALE.": PRINT
DO
INPUT "Entrez un nombre entier superieur a 1, svp ... ", knombre~&&
LOOP UNTIL knombre~&& > 1
' --- Somme des diviseurs du nombre saisie ---
ksomme_A~&& = FNC_Somme(knombre~&&)
PRINT "La somme des diviseurs stricts de"; knombre~&&; "est"; ksomme_A~&&
' --- Somme des diviseurs de la somme des diviseurs du nombre saisie ---
ksomme_B~&& = FNC_Somme(ksomme_A~&&)
PRINT "La somme des diviseurs stricts de"; ksomme_A~&&; "est"; ksomme_B~&&
' --- Comparaison des sommes et resultat ---
PRINT: PRINT
IF knombre~&& = ksomme_B~&& THEN
PRINT knombre~&&; "a comme nombre amical"; ksomme_A~&&; "."
ELSE
PRINT "Le nombre"; knombre~&&; "n'a pas de nombre ami."
END IF
' --- Bouclage du programme ---
PRINT: PRINT: INPUT "Voulez-vous recommencer [ O ou N ] "; kchoix$
CLS
LOOP UNTIL UCASE$(kchoix$) = "N"
' - FIN DU PROGRAMME ---
PRINT "Au revoir."
END
' --- DEFINITION DES FONCTIONS PERSONNALISEES ---
' --- Sommes des diviseurs stricts d'un nombre entier ---
FUNCTION FNC_Somme (Q~&&)
ksomme~&& = 0
FNC_Diviseurs (Q~&&)
FOR kindex = 0 TO 500
IF LST_Diviseurs~&&(kindex) <> 0 THEN
ksomme~&& = ksomme~&& + LST_Diviseurs~&&(kindex)
ELSE
EXIT FOR
END IF
NEXT kindex
FNC_Somme = ksomme~&&
END FUNCTION
' --- Recherche des diviseurs stricts d'un nombre entier ---
SUB FNC_Diviseurs (Q~&&)
' --- Initialisation de la recherche ---
FOR kindex = 0 TO 500: LST_Diviseurs~&&(kindex) = 0: NEXT kindex
kindex = 1
LST_Diviseurs~&&(0) = 1
kfin~&& = INT(SQR(Q~&&)) + 1
' --- Recherche des diviseurs ---
FOR kvaleur~&& = 2 TO kfin~&&
IF Q~&& MOD kvaleur~&& = 0 THEN
LST_Diviseurs~&&(kindex) = kvaleur~&&
kindex = kindex + 1
IF Q~&& \ kvaleur~&& <> kvaleur~&& THEN
LST_Diviseurs~&&(kindex) = Q~&& \ kvaleur~&&
kindex = kindex + 1
END IF
END IF
NEXT kvaleur~&&
' --- Affiche les diviseurs du plus petit au plus grand ---
FNC_Tri
PRINT: PRINT "Les diviseurs stricts de"; Q~&&; "sont :";
FOR kindex = 0 TO 500
IF LST_Diviseurs~&&(kindex) = 0 THEN
EXIT FOR
ELSE
PRINT LST_Diviseurs~&&(kindex);
END IF
NEXT kindex
END SUB
' --- Mise en ordre des divisseurs ---
SUB FNC_Tri
' --- Recherche le nombre de diviseurs presents dans LST_Diviseurs&() ---
FOR kfin = 0 TO 500
IF LST_Diviseurs~&&(kfin) = 0 THEN EXIT FOR
NEXT kfin
' --- Tri uniquement les diviseurs superieurs a zero ---
FOR kitem = (kfin - 2) TO 1 STEP -1
FOR kindex = 0 TO kitem
IF LST_Diviseurs~&&(kindex) > LST_Diviseurs~&&(kindex + 1) THEN SWAP LST_Diviseurs~&&(kindex), LST_Diviseurs~&&(kindex + 1)
NEXT kindex
NEXT kitem
END SUB
' --- Programme : JFB ---
' --- Avril 2026 ---
' --- Fin ---
Pour mieux comprendre l'exemple en QB64.
REM --- Origine Nerd propose pour ---
REM --- RETROGICIEL - BBC BASIC ---
REM --- Recherche amicale ---
REM --- INITIALISATION GENERALE ----
DIM LST_Diviseurs%%( 500 )
REM --- BOUCLE PRINCIPALE ---
REPEAT
REM --- Saisie du nombre a tester ---
CLS : PRINT "RECHERCHE AMICALE." : PRINT
REPEAT
INPUT "Entrez un nomre entier superieur a 1 ..." ; knombre%%
UNTIL knombre%% > 1
REM --- Sommes des diviseurs stricts du nombre saisie ---
ksomme_A%% = FN_Somme( knombre%% )
PRINT "La somme des diviseurs stricts de "; knombre%% ; " est "; ksomme_A%%
REM --- Sommes des diviseurs stricts de la somme des diviseurs stricts du nombre ---
ksomme_B%% = FN_Somme( ksomme_A%% )
PRINT "La somme des diviseurs stricts de "; ksomme_A%% ; " est "; ksomme_B%%
REM --- Comparaison et affichage du résultat ---
PRINT : PRINT
IF knombre%% = ksomme_B%% THEN
PRINT knombre%% ; " a comme nombre amical "; ksomme_A%% ; "."
ELSE
PRINT knombre%% ; " n'a pas de nombre ami."
ENDIF
REM --- Bouclage du programme ---
PRINT : PRINT : INPUT "Voulez-vous recommencer [ O ou N ] " ; kchoix$
UNTIL kchoix$ = "N" OR kchoix$ = "n"
REM --- FIN DU PROGRAMME ---
PRINT "Au revoir."
END
REM --- DEFINITION DES FONCTIONS PERSONNALISEES ---
REM --- Sommes des diviseurs stricts d'un nombre entier ---
DEF FN_Somme( Q%% )
ksomme%% = 0
PROC_Diviseurs( Q%% )
FOR kindex = 0 TO 500
IF LST_Diviseurs%%( kindex ) <> 0 THEN
ksomme%% = ksomme%% + LST_Diviseurs%%( kindex )
ELSE
EXIT FOR
ENDIF
NEXT kindex
= ksomme%%
REM --- Fin de la defnition ---
REM --- Recherche des diviseurs stricts d'un nombre entier ---
DEF PROC_Diviseurs( Q%% )
REM --- Initialisation de la recherche ---
FOR kindex = 0 TO 500 : LST_Diviseurs%%( kindex ) = 0 : NEXT kindex
kindex = 1
LST_Diviseurs%%( 0 ) = 1
kfin%% = INT( SQR( Q%% ) ) + 1
REM --- Recherche des diviseurs ---
FOR kvaleur%% = 2 TO kfin%%
IF Q%% MOD kvaleur%% = 0 THEN
LST_Diviseurs%%( kindex ) = kvaleur%%
kindex = kindex + 1
IF Q%% DIV kvaleur%% <> kvaleur%% THEN
LST_Diviseurs%%( kindex ) = Q%% DIV kvaleur%%
kindex = kindex + 1
ENDIF
ENDIF
NEXT kvaleur%%
REM --- Affiche les diviseurs du plus petit au plus grand ---
PROC_Tri
PRINT: PRINT "Les diviseurs stricts de " ; Q%% ; " sont : " ;
FOR kindex = 0 TO 500
IF LST_Diviseurs%%( kindex ) = 0 THEN
EXIT FOR
ELSE
PRINT STR$( LST_Diviseurs%%( kindex ) ) ; " " ;
ENDIF
NEXT kindex
ENDPROC
REM --- Mise en ordre des divisseurs ---
DEF PROC_Tri
REM --- Recherche le nombre de diviseurs presents dans LST_Diviseurs&() ---
FOR kfin = 0 TO 500
IF LST_Diviseurs%%( kfin ) = 0 THEN EXIT FOR
NEXT kfin
REM --- Tri uniquement les diviseurs superieurs a zero ---
FOR kitem = ( kfin - 2 ) TO 1 STEP -1
FOR kindex = 0 TO kitem
IF LST_Diviseurs%%( kindex ) > LST_Diviseurs%%( kindex + 1 ) THEN SWAP LST_Diviseurs%%( kindex ), LST_Diviseurs%%( kindex + 1 )
NEXT kindex
NEXT kitem
ENDPROC
REM --- Programme : JFB ---
REM --- Avril 2026 ---
REM --- Fin ---
Pour mieux comprendre l'exemple en BBC BASIC.