Misez p'tit, Optimisez - N°85 (L'Algorithme de Kaprekar)

Ici, on fait dans le petit, le LCD qui déchire sa race, on y cause même calculatrices quand on est en manque !

Modérateur : Politburo

Avatar de l’utilisateur
babaorhum
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 439
Inscription : 13 janv. 2013 20:44
Localisation : Toulon-ouest

Re: Misez p'tit, Optimisez - N°85 (L'Algorithme de Kaprekar)

Message par babaorhum » 26 août 2018 18:38

Salut les siliciens !

Ca fait bien longtemps que je n'ai pas posté sur Sili ... (mais ça ne m'a pas empêché de vous lire très régulièrement et de suivre vos aventures !)

Bon, C.Ret m'a fait ressortir mes machines. Voici donc un algo de Kaprekar méthode alphanumérique sur un 71B. Je ne rivalise pas avec les versions RPL et assembleur bien sûr ...
Le 71B considère ses chaînes alpha comme des tableaux. On accède ainsi simplement à chacun de ses caractères ... pratique pour trier !

Code : Tout sélectionner

10 INPUT A$ @ A$=STR$(VAL(A$))
20 L=LEN(A$) @ FOR J = L-1 TO 1 STEP -1 @ FOR I = 1 TO J
30 L$=A$[1,1] @ R$=A$[I+1,I+1]
40 IF R$>L$ THEN A$[I,I]=R$ @ A$[I+1,I+1]=L$
50 NEXT I @ NEXT J
60 B$=« » @ FOR I = 1 TO L @ B$[I,I]=A$[L-I+1,L-I+1] @ NEXT I
70 A$=STR$(VAL(A$)-VAL(B$))
80 PRINT A$ @ PAUSE @ GOTO 20
A$ contient le nombre initial (sous forme d'une chaine alpha), puis le nombre trié en décroissant
B$ contient le nombre trié en croissant
L$ et R$ contienne les caractères extraits pour les comparer et si besoin les échanger.

c'est un tri systématique de la gauche vers la droite ... c'est un tri à bulle ?

@ bientôt

Baba
BaBaoRhum
HP J728,200LX,1000CX,75C,71B, 48GX,42s,41CX,35s,32E,32Sii,28S,22s,21,16C,11C,12Cp
Sharp PC- E500,1600,1500,1350,1261,1245
Casio FX-502P,850P,3900P,4000P
TI-74&92 ; Canon X-07 ; Panasonic HHC RL-H1400 ; TANDY EC-4026

Avatar de l’utilisateur
C.Ret
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1859
Inscription : 31 mai 2008 23:43
Localisation : N 49°22 E 6°10

Re: Misez p'tit, Optimisez - N°85 (L'Algorithme de Kaprekar)

Message par C.Ret » 29 août 2018 21:48

Très beau code qui utilise bien les indices d'adressage des caractères d'une chaine spécifique au HP-71B.

J'aime bien aussi le N$=STR$ VAL N$ pour éviter que l'on ne démarre avec une chaine N$ ne contenant pas un nombre.


Du coup cela m'a donné l'idée de faire pareil sur SHARP PC-1360. Enfin presque pareil parce que le seul moyen d'accéder aux caractères d'une chaine est d'utiliser les instructions MID$ LEFT$ ou RIGHT$.

Code : Tout sélectionner

1:"K" AREAD N: ND$="", NC$=ND$: FOR L=1 TO LEN STR$ N: I$=MID$ (STR$ N,L,1), J=0
2:J=J+1 : IF I$< MID$ (ND$,J,1) GOTO 2
3:ND$= LEFT$ (ND$,J-1)+I$+ MID$ (ND$,J,9) , NC$= LEFT$ (NC$,L-J)+I$+ MID$ (NC$,1+L-J,9) 
4:NEXT L: N= VAL ND$- VAL NC$:  WAIT : PAUSE ND$;"-";NC$: PRINT N: GOTO 1
Pour lancer un nouveau calcul, saisir le nombre et lancer par [ DEF ] [ K ]. La transformation suivantes peut être enchainée soit directement par le même label DEF, soit en pressant simplement sur [ ENTER ]

Si un nombre plus grand que 10 chiffres est saisi, le programme s'arrête sur une erreur 3 en ligne 3. Notez que si l'on utilise les variables D$ et C$ au lieu de ND$ et NC$; le nombre de chiffres se limitera à 7. Au delà les résultats sont erronés, les variables simples ne pouvant contenir plus de 7 caractères.

Les chiffres de N sont triés directement dans les chaines ND$ et NC$ respectivement par ordre décroissant et croissant à partir du test unique de la ligne 2. l'idée est que les chaines ND$ et NC$ sont triées dans un sens et dans l'autre, il y a donc une antisymétrie. Si le chiffre de N doit être placé à la J-ième position à partir de la gauche dans D, il sera à la même J-ième position mais à partir de la droite dans C (c'est à dire (L-J)-ième position comptée à partir de la gauche pour être compatible avec les instructions LEFT$ ou MID$).


AJOUT 30/08/2018:
Et la version pour Commodore VIC-20 :
MPO 85 VIC-20 list+run color.gif
MPO 85 VIC-20 list+run color.gif (82.68 Kio) Consulté 725 fois
Comme cela ne se voit pas sur cette capture fixe, le curseur clignote. Il est possible de modifier la valeur ou de taper directement sur [ RETURN ] pour obtenir le détail de la transformation suivante.
SHARP PC-1211 + CE-121 + CE-122. | VIC 20 Commodore 128D + Printer P-803. | TI-57 LCD | TI-74 BasiCalc | TI-92 II | HP-15C | HP-28S + HP82240A | HP-41C + (2 memory + stat + IR) modules. | HP Prime Wireless Graphing Calculator . .Sommaire des M.P.O.. . Sommaire du P.C.T.M. .

Avatar de l’utilisateur
C.Ret
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1859
Inscription : 31 mai 2008 23:43
Localisation : N 49°22 E 6°10

Re: Misez p'tit, Optimisez - N°85 (L'Algorithme de Kaprekar)

Message par C.Ret » 30 août 2018 19:22

babaorhum a écrit :
26 août 2018 18:38
[…] Le 71B considère ses chaînes alpha comme des tableaux. On accède ainsi simplement à chacun de ses caractères ...[...]
Intéressant ça, je constate qu'il y a à chaque fois deux indices. S'agit-il des indices de début et de fin du "tableau" de caractères ?

Si c'est le cas, il devient possible de manipuler plus d'un caractère à la fois :

Code : Tout sélectionner

10 INPUT N$ @ N$=STR$(VAL(N$)) @ D$="" @ C$="" @ FOR I = 1 TO LEN(N$) @ J=1
20 IF J<I THEN IF N$[I,I]<D$[J,J] THEN J=J+1 @ GOTO 20
30 D$[J,0]=N$[I,I] @ C$[1+I-J,0]=N$[I,I] @ NEXT I @ N$=D$&"-"&C$ 
40 PRINT N$;" :";VAL(N$) @ PAUSE @ GOTO 10
Je n'ai pas d' HP-71B, le code ci-dessus a-t-il une chance de fonctionner ??
SHARP PC-1211 + CE-121 + CE-122. | VIC 20 Commodore 128D + Printer P-803. | TI-57 LCD | TI-74 BasiCalc | TI-92 II | HP-15C | HP-28S + HP82240A | HP-41C + (2 memory + stat + IR) modules. | HP Prime Wireless Graphing Calculator . .Sommaire des M.P.O.. . Sommaire du P.C.T.M. .

Avatar de l’utilisateur
babaorhum
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 439
Inscription : 13 janv. 2013 20:44
Localisation : Toulon-ouest

Re: Misez p'tit, Optimisez - N°85 (L'Algorithme de Kaprekar)

Message par babaorhum » 30 août 2018 22:14

Bonjour,

j'ai peut être été un peu rapide mes explications ... On peut accéder au contenu des variables alpha du HP71B comme dans un tableau :

A$ = B$[3,5] affectera à A$ 3 caractères : du 3ème au 5ème de B$ - comme un MID$(B$,3,3) sur une Sharp par exemple.

Le gros avantage HP est que ça marche dans l'autre sens - Dans mon code je l'ai utilisé pour affecter un caractère (A$[I,I]= "x") . Facile.
Pour plusieurs caractères ça mérite de s'y pencher un peu plus ...

extrait du manuel P74, traduit à la volée :
V$[I,J] = "teacup" étend ou contracte la partie de V$ à partir de la position I jusqu'à la position J de manière à ce que le mot "teacup" entre exactement - tout caractère existant auparavant entre I et J sont écrasés, y compris les positions I et J
Ca mérite un essai pour bien comprendre ... sortons la bête et essayons :

Code : Tout sélectionner

A$="SILICIUM C'EST SUPER"
LEN(A$) renvoit 20
A$[5,8] = "GLOUPS"
A$ renvoie "SILIGLOUPS C'EST SUPER"  donc on élimine les 4 caractères entre du 5éme au 8éme et on les remplace par les 6 caractères de "GLOUPS"
A$[5,10] = "CIUM"
A$ contient "SILICIUM C'EST SUPER"  on élimine les 6 caractères (entre 5 et 10) et on les remplace par 4 "CIUM"
Voilà, maintenant on comprend mieux le manuel effectivement ...

Avec cet éclaircissement, C.ret, il faut je pense revoir ta ligne 30 (pas le temps d'aller plus loin aujourd'hui ...)

Autre précision, l'instruction N$=STR$(VAL(N$)) sert aussi à éliminer d'éventuels zéros en début de ligne, changer par exemple, 0001485 en 1485 - sinon les zéros sont considérés, on est en mode alpha ...

A suivre

Baba
BaBaoRhum
HP J728,200LX,1000CX,75C,71B, 48GX,42s,41CX,35s,32E,32Sii,28S,22s,21,16C,11C,12Cp
Sharp PC- E500,1600,1500,1350,1261,1245
Casio FX-502P,850P,3900P,4000P
TI-74&92 ; Canon X-07 ; Panasonic HHC RL-H1400 ; TANDY EC-4026

Avatar de l’utilisateur
C.Ret
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1859
Inscription : 31 mai 2008 23:43
Localisation : N 49°22 E 6°10

Re: Misez p'tit, Optimisez - N°85 (L'Algorithme de Kaprekar)

Message par C.Ret » 30 août 2018 23:08

OUi, c'est une spécificité bien pratique du HP-71B les crochets permettent bien plus de choses que les MID$ ou LEFT$ / RIGHT$ d'autres BASICs

De plus si on a D$="952" et C$="259" alors D$[3,0]="4" et C$[2,0]="4" insèrent respectivement la chaine "4" dans D$ (avant le 3ième caractère) et C$ (avant le second) de telle sorte que l'on obtient alors D$="9542" et C$="2459". je ne sais pas si c'est bien expliqué bien dans le manuel HP, mais c'est à essayer sur un HP-71B (ROM BBBB)

Sans compter les HP-71B qui aurait l'instruction REV$. Dans ce cas, mon C$ devient inutile, il est remplacé par REV$(D$) !
SHARP PC-1211 + CE-121 + CE-122. | VIC 20 Commodore 128D + Printer P-803. | TI-57 LCD | TI-74 BasiCalc | TI-92 II | HP-15C | HP-28S + HP82240A | HP-41C + (2 memory + stat + IR) modules. | HP Prime Wireless Graphing Calculator . .Sommaire des M.P.O.. . Sommaire du P.C.T.M. .

Avatar de l’utilisateur
badaze
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 6478
Inscription : 12 févr. 2007 19:36
Localisation : Pas très loin de Lyon
Contact :

Re: Misez p'tit, Optimisez - N°85 (L'Algorithme de Kaprekar)

Message par badaze » 31 août 2018 18:13

Ma contribution avec un programme pour Casio PB-100 (en fait un Olympia OP 544).

Le programme est sans fioritures et pas spécialement optimisé. J'ai utilisé un tableau A(15+I) avec 0<=I<=9 pour remplir les variables de O à X. J'aurais pu utiliser le tableau O(I).
On saisit le nombre qui est mis dans la variable $ qui a une capacité de 30 caractères.

PS : le cas de 52 est correctement géré.

zone P0 - programme principal

Code : Tout sélectionner

10 INPUT $
20 GOSUB #1
30 GOSUB #2
40 GOSUB #3
50 F=G-H
60 PRINT F
70 GOTO 10
80 END
Malheureusement le PB-100 n'a pas de fonction STR qui convertit un nombre en chaîne mais seulement VAL. De ce fait il est impossible de faire boucler le programme automatiquement pour afficher les résultats de la suite. J'ai quand même mis un GOTO 10 car il suffit d'appuyer sur la touche ANS pour que le dernier résultat soit automatiquement copié.

zone P1 - calcul des positions

Code : Tout sélectionner

-- Initialisation du tableau 
10 FOR I=0 TO 9
20 A(15+I) = 0
30 NEXT I 
-- Comptage du nombre de chiffres par chiffre
40 FOR I=1 TO LEN($)
50 B$ = MID(I,1)
60 C = VAL(B$)
70 A(15+C) = A(15+C)
80 NEXT I
90 RETURN
Les chiffres du nombre saisi sont comptés et le comptage est mis dans un tableau. Par exemple pour 562545 le poste 5 du tableau est égal à 3 car il y a 3 cinq dans le nombre.
Image

zone P2 - mise en forme du nombre (chiffres dans l'ordre croissant)

Code : Tout sélectionner

-- ligne 10 = paramètres de la boucle FOR NEXT de la zone 4
10 L=9:M=0:N=-1
20 GOSUB #4
30 H=D
40 RETURN
zone P3 - mise en forme du nombre (chiffres dans l'ordre décroissant)

Code : Tout sélectionner

-- ligne 10 = paramètres de la boucle FOR NEXT de la zone 4
10 L=0:M=9:N=1
20 GOSUB #4
30 G=D
40 RETURN
zone P4 - sous routine générique de mise en forme

Code : Tout sélectionner

10 D=0:J=0:K=0
20 FOR I=L TO M STEP N
30 IF A(15+I) = 0 THEN 80
40 FOR J=1 TO A(15+I)
50 D=D+(I*(10^K))
60 K=K+1
70 NEXT J
80 NEXT I
90 RETURN
La sous routine P4 est appelée par les sous routines P2 et P3. P4 parcourt le tableau du comptage des chiffres de 0 à 9 (appel depuis P3) ou de 9 à 0 (appel depuis P2) et donne un nombre dont les chiffres sont triés par ordre croissant (P2) ou décroissant (P3).
Le principe est d'utiliser les puissances de 10 pour positionner les chiffres dans le nombre final (incrément de la variable K à chaque fois qu'un chiffre est utilisé).
La seconde boucle FOR NEXT sert à traiter le cas où le même chiffre se retrouve plusieurs fois dans le nombre initial.
Image
.
.
.
.
.
.
.
Pièces jointes
Capture20180831_001.JPG
Capture20180831_001.JPG (11.78 Kio) Consulté 675 fois
Tout est bon dans le pocket.
Moi j'aime tout.... Casio, HP, Sharp, TI et les autres sauf que les TI semblent ne pas m'aimer :(
http://www.emmella.fr
Mes Casio - HP - Sharp - TI
Homme invisible.

Avatar de l’utilisateur
badaze
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 6478
Inscription : 12 févr. 2007 19:36
Localisation : Pas très loin de Lyon
Contact :

Re: Misez p'tit, Optimisez - N°85 (L'Algorithme de Kaprekar)

Message par badaze » 31 août 2018 23:32

J'ai réussi à convertir un nombre en chaîne de caractères.

zone P0 - programme principal

Code : Tout sélectionner

10 INPUT $
20 GOSUB #1
30 GOSUB #2
40 GOSUB #3
50 F=G-H
60 PRINT F
65 GOSUB #9
70 GOTO 20
80 END
Le code des zones P1, P2, P3 et P4 ne change pas.

zone P9 - conversion numérique en numérique alpha

Code : Tout sélectionner

10 $="0123456789":Y=0:K=0
20 FOR I=0 TO 9
30 O$(I)=""
40 NEXT I
50 Y=F
60 Y=Y/10
70 Z=FRAC(Y)*10
80 Y=INT(Y)
90 O$=MID(Z+1,1):H$=P$(K):J=LEN(H$)
100 IF J>7;K=K+1
110 P$(K)=O$+P$(K)
120 IF Y<>0 THEN 60
130 $=""
140 FOR I=0 TO K
150 $=$+P$(I)
160 NEXT I
170 RETURN
et vous savez quoi. Le code de la zone P9 m'a donné un nouvel algorithme.
EDIT : en fait non :(
Tout est bon dans le pocket.
Moi j'aime tout.... Casio, HP, Sharp, TI et les autres sauf que les TI semblent ne pas m'aimer :(
http://www.emmella.fr
Mes Casio - HP - Sharp - TI
Homme invisible.

cgh
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1850
Inscription : 30 août 2011 12:23
Localisation : Vous êtes ici -> .

Re: Misez p'tit, Optimisez - N°85 (L'Algorithme de Kaprekar)

Message par cgh » 01 sept. 2018 01:47

Ma petite contribution sur... CASIO FX-702P 8)
Le programme occupe 188 octets (1680-1492) et utilise les variables C, I, J, K, L, N, P, S, T. On pourrait de plus n'avoir que K (et pas P) :geek:
Il y a un peu de message quand meme: NOMBRE= et K(...)=... :mrgreen:
Le code suivant occupe le programme P0.

Code : Tout sélectionner

10 INP "NOMBRE=",N
20 C=0:S=0:T=0:L=INT LOG (INT N+.1)
30 FOR I=1 TO L+1:C=C+10^INT (10*FRAC (N/10^I)):NEXT I
40 FOR I=0 TO 9:P=INT (FRAC (C/10^(I+1))*10)
50 IF P=0 THEN 70
60 FOR J=1 TO P:T=T*10+I:S=S/10+I:NEXT J
70 NEXT I:K=S*10^L-T:PRT "K(";N;")=";K:N=K:GOTO 20
Lancer le programme par P0. Entrer votre nombre et EXE. K(...) va s'afficher. Appuyer sur CONT pour continuer la sequence ou si vous voulez un nouveau nombre, relancer le programme par P0.

Ligne 20: le # est le caractere different qui est present sur le FX-702P ;)
Dernière édition par cgh le 01 sept. 2018 03:37, édité 3 fois.
J'adore parler de rien, c'est le seul domaine où j'ai de vagues connaissances ! - Oscar Wilde
Ce n'est pas parce que les choses sont difficiles que nous n'osons pas. C'est parce que nous n'osons pas que les choses sont difficiles. - Sénèque

cgh
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1850
Inscription : 30 août 2011 12:23
Localisation : Vous êtes ici -> .

Re: Misez p'tit, Optimisez - N°85 (L'Algorithme de Kaprekar)

Message par cgh » 01 sept. 2018 03:27

Une solution BASIC (oui, oui, cela m'arrive :mrgreen:) sur SHARP PC1500.

Code : Tout sélectionner

10 INPUT N$
20 T$="":S$="":L=LEN N$:FOR I=48TO 57:C$=CHR$ I:FOR J=1TO L
30 IF MID$ (N$,J,1)=C$LET T$=T$+C$:S$=C$+S$
40 NEXT J:NEXT I
50 K$=STR$ (VAL S$-VAL T$):PRINT "K(";N$;")=";K$:N$=K$:GOTO 20
Lancer le programme par RUN. Entrer votre nombre; le resultat K(n)=k sera affiche. Appuyer sur ENTER pour la suite de la sequence, sinon relancer le programme par RUN pour un nouveau nombre.

Note: 48 correspond au code ASCII de "0" et 57 a celui de "9"... :geek:
J'adore parler de rien, c'est le seul domaine où j'ai de vagues connaissances ! - Oscar Wilde
Ce n'est pas parce que les choses sont difficiles que nous n'osons pas. C'est parce que nous n'osons pas que les choses sont difficiles. - Sénèque

cgh
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1850
Inscription : 30 août 2011 12:23
Localisation : Vous êtes ici -> .

Re: Misez p'tit, Optimisez - N°85 (L'Algorithme de Kaprekar)

Message par cgh » 01 sept. 2018 03:59

Du coup, en appliquant la meme methode au programme du FX-702P, le programme occupe maintenant 140 octets (1680-1540).

Code : Tout sélectionner

10 INP "NOMBRE=",N
20 C=0:S=0:T=0:L=INT LOG (INT N+.1)
30 FOR I=0 TO 9:FOR J=1 TO L+1
40 IF I=INT (FRAC (N/10^J)*10);T=T*10+I:S=S/10+I
50 NEXT J: NEXT I:
70 NEXT I:K=S*10^L-T:PRT "K(";N;")=";K:N=K:GOTO 20
J'adore parler de rien, c'est le seul domaine où j'ai de vagues connaissances ! - Oscar Wilde
Ce n'est pas parce que les choses sont difficiles que nous n'osons pas. C'est parce que nous n'osons pas que les choses sont difficiles. - Sénèque

Avatar de l’utilisateur
C.Ret
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1859
Inscription : 31 mai 2008 23:43
Localisation : N 49°22 E 6°10

Re: Misez p'tit, Optimisez - N°85 (L'Algorithme de Kaprekar)

Message par C.Ret » 13 oct. 2018 17:08

Je suis aux 9ième Pocketicaires et. J'ai pu corriger mon code pour TI-71B

Code : Tout sélectionner

10 INPUT N$ @ N$=STR$(VAL(N$)) @ D$="" @ C$="" @ FOR I = 1 TO LEN(N$) @ J=1
20 IF J<I AND N$[I,I]<D$[J,J] THEN J=J+1 @ GOTO 20
30 D$[J,0]=N$[I,I] @ C$[1+I-J,0]=N$[I,I] @ NEXT I @ N$=D$&"-"&C$ 
40 PRINT N$;" :";VAL(N$) @ PAUSE @ GOTO 10
SHARP PC-1211 + CE-121 + CE-122. | VIC 20 Commodore 128D + Printer P-803. | TI-57 LCD | TI-74 BasiCalc | TI-92 II | HP-15C | HP-28S + HP82240A | HP-41C + (2 memory + stat + IR) modules. | HP Prime Wireless Graphing Calculator . .Sommaire des M.P.O.. . Sommaire du P.C.T.M. .

Répondre

Revenir vers « Tous les Pockets »