Misez p'tit Optimisez n°96 : Combien de bits à un dans cet entier ?

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 du membre
Schraf
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 499
Enregistré le : 05 mars 2020 20:45
Contact :

Re: Misez p'tit Optimisez n°96 : Combien de bits à un dans cet entier ?

Message par Schraf »

Bonjour,

Je n'arrive pas à trouver dans les docs sur la HP-Prime si on peut :
  • Convertir une chaine en liste ? Par exemple passer de S = "011" à L = ["0","1","1"]. MAKELIST ne fonctionne pas avec les chaines de caractères
  • Compter le nombre d'occurrences d'un caractère ? Si la question n°1 est résolue, un count(x->x=="1",L) ira
  • Un équivalent de SREPL dont vous avez parlé pour la HP50G ?
Donc pour le moment je ne vois pas plus court sur HP-Prime en mode CAS pour ce MPO :

fonction b
fonction b
bin.png (17.73 Kio) Vu 4793 fois
Avatar du membre
tyann
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 845
Enregistré le : 06 oct. 2012 14:37

Re: Misez p'tit Optimisez n°96 : Combien de bits à un dans cet entier ?

Message par tyann »

Bonsoir

Pour construire une liste à partir d'une chaîne MAKELIST fonctionne
C'est la méthode que j'ai utilisé dans ma collection de fonctions de traitement de chaînes :

Code : Tout sélectionner

EXPORT LIST(s)
BEGIN
 IF s=="" THEN
  {}
 ELSE
  MAKELIST(MID(s,I,1),I,1,DIM(s));
 END;
END;
Pour compter le nombre d'occurrences dans une liste il faut passer par une boucle
Enfin pour SREPL sur la Prime tu as REPLACE qui fonctionne pareil pour les chaînes.

Code : Tout sélectionner

REPLACE(chaine,sous chaine, chaine de remplacement)
sauf que contrairement à SREPL sur Hp50g, REPLACE ne renvoie pas le nombres de remplacement effectués.
Ti(s) 60, 62 Galaxy, 66, 67 Galaxy, 68, 74 Basical 80, 81, 82, 83+, 83 CE, 84+SE, 85, 86, 89, 89 titanium, 92, 95 Procalc, v200, nSpire cx
Hp(s) 35s, 41CX, 28S, 48g, 50g, 39gII, Prime G1 et G2,
Casio(s) fx 602P, 702P, 4000P, 4500P, 6000G, 6900G, 7700G, 8500g, PB-700, CG-20, Graph 95 sd
Psion(s)II LZ64, siena, s3a, s3mx, s5mx.
Sharp(s) pc-1350, 1403, 1500A, E500, El 5120, 9200, 9600
Canon X-07
Avatar du membre
Schraf
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 499
Enregistré le : 05 mars 2020 20:45
Contact :

Re: Misez p'tit Optimisez n°96 : Combien de bits à un dans cet entier ?

Message par Schraf »

Ah oui je vois, on récupère les éléments caractère par caractère dans MAKELIST.

En parcourant l'aide sur la machine, j'ai eu cette idée :

Code : Tout sélectionner

b(x):=∑LIST(ASC(bin(x))-48)-50
Puisque ASC(chaine) transforme directement une chaine en liste et que je cherchais juste à compter le nombre de "1" (code ASCII = 49). Dommage pour SREPL qui aurait donné tout de suite la réponse...

Merci.

Version ASC
Version ASC
asc.png (16.59 Kio) Vu 4768 fois
Je me rends compte que pour définir une fonction (en mode Accueil ou CAS), c'est plus pratique de passer Shift Define (en utilisant un "X" majuscule)

Définir une fonction
Définir une fonction
Shift Define.png (52.61 Kio) Vu 4745 fois

Nouvelle piste : SUPPRESS !

SUPPRESS permet de supprimer plusieurs caractères différents en une seule fois. Dans la conversion en binaire on obtient une chaine comme "0b1011101011101..." et donc pour compter le nombre de 1 il faut supprimer les "0" et le "b".

Avec SUPPRESS, fini le stress
Avec SUPPRESS, fini le stress
Suppress.png (18.42 Kio) Vu 4743 fois

Autre piste : count_eq(element, liste)

Cette fonction équivaut à count(x->x==element, liste) mais ne s'applique hélas pas à une chaine de caractères. Le code ASCII du "1" étant 49, on obtient :

Compter dans une liste
Compter dans une liste
count_eq.png (18.56 Kio) Vu 4743 fois
Modifié en dernier par Schraf le 21 avr. 2021 09:11, modifié 4 fois.
Avatar du membre
tyann
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 845
Enregistré le : 06 oct. 2012 14:37

Re: Misez p'tit Optimisez n°96 : Combien de bits à un dans cet entier ?

Message par tyann »

Bonjour

En fait REPLACE permet de supprimer un ou plusieurs caractères dans une chaîne
en mettant pour la chaîne de remplacement une chaîne vide.

Code : Tout sélectionner

REPLACE(chaîne,souschaîne,"")
Donc en soustrayant la longueur de chaîne après REPLACE à celle d'avant tu obtiens le nombre de caractères.
Si souschaîne a plus d'un caractère il faut diviser par sa longueur.
Ti(s) 60, 62 Galaxy, 66, 67 Galaxy, 68, 74 Basical 80, 81, 82, 83+, 83 CE, 84+SE, 85, 86, 89, 89 titanium, 92, 95 Procalc, v200, nSpire cx
Hp(s) 35s, 41CX, 28S, 48g, 50g, 39gII, Prime G1 et G2,
Casio(s) fx 602P, 702P, 4000P, 4500P, 6000G, 6900G, 7700G, 8500g, PB-700, CG-20, Graph 95 sd
Psion(s)II LZ64, siena, s3a, s3mx, s5mx.
Sharp(s) pc-1350, 1403, 1500A, E500, El 5120, 9200, 9600
Canon X-07
Avatar du membre
dprtl
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 463
Enregistré le : 27 janv. 2013 00:26
Localisation : Strasbourg
Contact :

Re: Misez p'tit Optimisez n°96 : Combien de bits à un dans cet entier ?

Message par dprtl »

Voici une version très courte, avec la calculette que j'utilise le plus souvent, qui est 'bc'. Elle pourrait devenir un peu moins hors sujet dans la catégorie "Pockets" dès que j'aurai reçu ma Pyra tant attendue.

Code : Tout sélectionner

$ cat count_bits.sh
#!/bin/sh
echo "obase=2;$1" | BC_LINE_LENGTH=0 bc | tr -d "0|\n" | wc -c
$ ./count_bits.sh 1968
6
$ ./count_bits.sh 65535
16
$ ./count_bits.sh 4294967295
32
$ ./count_bits.sh 31415926535897932384626433832795
52
$ ./count_bits.sh 3141592653589793238462643383279531415926535897932384626433832795
100
Ces utilitaires ('bc', 'tr' et 'wc') pèsent moins de 100 Ko chacun ; ce qui devient assez rare par les temps qui courent !
FLISZT
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 655
Enregistré le : 09 mars 2022 19:14

Re: Misez p'tit Optimisez n°96 : Combien de bits à un dans cet entier ?

Message par FLISZT »

Je rajoute deux programmes que j'avais écrits sur HP 50g alors que je n'étais pas encore inscrit.
Ils fonctionnent avec des listes binaires du type { 1 0 0 0 1 1 ], etc.

Code : Tout sélectionner

<<
     DUP
     <<
	0 >
     >>
     MAP
     SWAP	@ suite à la question de C.Ret et après tests, il apparaît clairement que ce SWAP ne sert à rien !
     IFT
     ΣLIST
>>

46 octets (44 octets sans le SWAP)

Code : Tout sélectionner

<<
     → liste
     <<
	liste liste 0 >
     >>
     SWAP	@ suite à la question de C.Ret et après tests, il apparaît clairement que ce SWAP ne sert à rien !
     IFT
     ΣLIST
>>

46,5 octets (43,5 octets sans le SWAP)
Je passe sur ma "belle" version en 31,5 octets puisque Gilles59 avait publié le même programme ici même à l'époque (sept. 2020) :
viewtopic.php?f=46&t=45636#p546647

… non, non Gilles59, je ne trouve pas que ce soit de la gruge, même un peu. :pirat:
:)

EDIT 1 :

Du fait d'un bug de ΣLIST, ces programmes ne fonctionnent pas si la liste contient un seul élément (ni si elle est vide).
Ce bug a dû être corrigé en newRPL… (?)

EDIT 2 :

Dans un programme pour lequel on sait qu'il risque d'y avoir au moins une liste vide ou contenant un seul élément, on pourra remplacer :

Code : Tout sélectionner

<<
     ΣLIST
>>

15,5 octets
par :

Code : Tout sélectionner

<<
     OBJ→		@ LIST→  sur hp-28
     DROP
     WHILE
          DEPTH 
          1 >
     REPEAT
          +
     END
>>

32,5 octets
Ce code pourra également être utile quand on utilise une hp-28 dépourvue de la fonction ΣLIST.

EDIT 3 :

Voir les deux premiers programmes de ce post (commentaires à propos des SWAP) : viewtopic.php?f=46&t=45636&start=45#p571089
Modifié en dernier par FLISZT le 27 août 2022 20:17, modifié 3 fois.
Bruno
Sanyo CZ-0124 ? TI-57 ? HP-15C ? Canon X-07 + XP-140 Monitor Card ? HP-41CX ? HP-28S ? HP-50G ? HP-50G
Avatar du membre
C.Ret
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 3404
Enregistré le : 31 mai 2008 23:43
Localisation : N 49°22 E 6°10

Re: Misez p'tit Optimisez n°96 : Combien de bits à un dans cet entier ?

Message par C.Ret »

FLISZT a écrit : 25 août 2022 17:12Ils fonctionnent avec des listes binaires du type { 1 0 0 0 1 1 ], etc.
Bonjour,

Je ne comprends pas bien la logique de tout cela. Si la liste contient déjà la valeur de l'entier n sous forme binaire, pourquoi faut-il faire autant de trucs dont un SWAP en plein milieu ??

Par exemple, pour n = 1968, la liste le représentant sera { 1 1 1 1 0 1 1 0 0 0 0 }. C'est bien cela ?

Alors, il n'y a plus rien à faire, on voit immédiatement qu'il y a exactement six bits à 1 !? Pourquoi un simple { 1 1 1 1 0 1 1 0 0 0 } ΣLIST ne suffit pas ? Pourquoi le code pour HP50g est-il aussi compliqué (à quoi sert le SWAP ? et le test > 0 ? )

Le code intéressant n'est-il pas plus certainement celui qui transforme 1968 en { 1 1 1 1 0 1 1 0 0 0 0 } ?


Sinon, voici une version pour système SHARP EL-5150 ou autre AER et Formulae Library, ainsi que sa traduction pour quelques autres systèmes:
MPO 96 - Algo ADD FRAC WHILE N.gif
MPO 96 - Algo ADD FRAC WHILE N.gif (23.98 Kio) Vu 2963 fois
Evidemment, pour l'HP-71B, il existe une autre façon de faire plus courte et plus directe (si l'on a les ROMs JPC et MATH 1) qui ressemble beaucoup aux codes proposés ci-dessus pour HP Prime :
MPO 96 - Algo NILL ZERO COUNT ONEs.gif
MPO 96 - Algo NILL ZERO COUNT ONEs.gif (1.48 Kio) Vu 2970 fois
Modifié en dernier par C.Ret le 26 août 2022 22:28, modifié 1 fois.
SHARP PC-1211 PC-1360 EL-5150 PC-E500 | Commodore C=128D | Texas Instruments Ti-57LCD Ti-74BASICalc Ti-92II Ti-58c Ti-95PROCalc Ti-30XPROMathPrint | Hewlett-Packard HP-28S HP-41C HP-15C HP-Prime HP-71B | CASIO fx-602p | NUMWORKS | Graphoplex Rietz Neperlog | PockEmul | Sommaire des M.P.O. | Ma...dov'il sapone.
FLISZT
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 655
Enregistré le : 09 mars 2022 19:14

Re: Misez p'tit Optimisez n°96 : Combien de bits à un dans cet entier ?

Message par FLISZT »

C.Ret a écrit : 26 août 2022 07:53 Je ne comprends pas bien la logique de tout cela.
Bonjour,

:lol:
La logique de tout cela ?! Oui C.Ret, la question se pose ! :lol:

Je suppose − 2 ans plus tard − que j'étais parti avec l'idée de supprimer les zéros de la liste ; c'est effectivement ce que font ces deux programmes.
Après avoir fait le plus "dur", certaines évidences m'auront quelque peu échappé…

… ou alors c'était délibéré : après avoir "joué" avec les listes − dans mon coin / hors forum − fallait quand même bien donner le résultat ! :D
Avant de publier, je me suis seulement contenté de vérifier que ça fonctionnait… et voilà !
C.Ret a écrit : 26 août 2022 07:53 Le code intéressant n'est-il pas plus certainement celui qui transforme 1968 en { 1 1 1 1 0 1 1 0 0 0 0 } ?
… oui c'est incontestable ! Mais je ne crois pas avoir fait un code similaire… ou alors pour un autre MPO (?).

EDIT :
C.Ret a écrit : 26 août 2022 07:53 …dont un SWAP en plein milieu ??
… tu as l'œil C.Ret ! Ces SWAP ne servent à… RIEN ! 8O
Modifié en dernier par FLISZT le 27 août 2022 20:05, modifié 1 fois.
Bruno
Sanyo CZ-0124 ? TI-57 ? HP-15C ? Canon X-07 + XP-140 Monitor Card ? HP-41CX ? HP-28S ? HP-50G ? HP-50G
FLISZT
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 655
Enregistré le : 09 mars 2022 19:14

Re: Misez p'tit Optimisez n°96 : Combien de bits à un dans cet entier ?

Message par FLISZT »

FLISZT a écrit : 26 août 2022 20:37
C.Ret a écrit : 26 août 2022 07:53 Le code intéressant n'est-il pas plus certainement celui qui transforme 1968 en { 1 1 1 1 0 1 1 0 0 0 0 } ?
… oui c'est incontestable ! Mais je ne crois pas avoir fait un code similaire… ou alors pour un autre MPO (?).
Finalement, je l'avais déjà ± fait pour ce MPO…

Après qq vérif, je peux proposer à l'arrach ce code sûrement perfectible de 85,5 octets (!) qui transforme un nombre en une liste binaire :
Le plus long à faire sont, et de loin, les commentaires…… bien alignés !!! :evil:

Code : Tout sélectionner

<<
     BIN R→B                   @ transforme le réel en un "binary"
     →STR TAIL TAIL            @ transforme le "binary" en chaîne de car puis suppress des 2 car de tête (# et espace)
     OBJ→ DROP                 @ transformation en réel et suppression de "b"
     →STR                      @ transformation en chaîne de car
     "1" "1 " SREPL            @ remplace les "1" par "1 " 
     DROP                      @ effacement du nbr d'occurrences de "1" / nbr qui est le résultat attendu dans ce MPO…
     "0" "0 " SREPL DROP       @ remplace les "0" par "0 " et efface le nombre de zéros
     OBJ→                      @ transforme la chaîne de car en N objets
     DEPTH →LIST               @ les N objets sont regroupés en une liste
>>
Pour n = 1963 on obtient bien { 1 1 1 1 0 1 0 1 0 1 1 } … je peux aller manger ! :tongue:
Bruno
Sanyo CZ-0124 ? TI-57 ? HP-15C ? Canon X-07 + XP-140 Monitor Card ? HP-41CX ? HP-28S ? HP-50G ? HP-50G
FLISZT
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 655
Enregistré le : 09 mars 2022 19:14

Re: Misez p'tit Optimisez n°96 : Combien de bits à un dans cet entier ?

Message par FLISZT »

Bonjour,


En repensant à mon petit prog (reproduit ci-dessous) transformant un réel en une liste "binaire" , j'ai eu l'idée d'en faire un pour la hp-28s…

Code : Tout sélectionner

<<
     BIN R→B                   @ transforme le réel en un "binary"
     →STR TAIL TAIL            @ transforme le "binary" en chaîne de car puis suppress des 2 car de tête (# et espace)
     OBJ→ DROP                 @ transformation en réel et suppression de "b"
     →STR                      @ transformation en chaîne de car
     "1" "1 " SREPL            @ remplace les "1" par "1 " 
     DROP                      @ effacement du nbr d'occurrences de "1" / nbr qui est le résultat attendu
     "0" "0 " SREPL            @ remplace les "0" par "0 "
     DROP                      @ effacement du nbr d'occurrences de "0"
     OBJ→                      @ transforme la chaîne de car en N objets
     DEPTH →LIST               @ les N objets sont regroupés en une liste
>>
(85,5 octets)

Évidement, pas de TAIL (hp-48gx… ), pas de SREPL (hp-49g… ), ni même de REPL (hp-48sx… ) !

La fonction TAIL, qui fonctionne sur les LISTes et les CHARS, n'est pas très difficile à reproduire sur une hp-28 c/s.
Adaptation pour une liste :

Code : Tout sélectionner

<<
	LIST→ 1 − →LIST          @ on peut rajouter SWAP DROP si l'on veut que le 1er élt disparaisse de la pile
>>
Pour une chaîne de caractères, c'est à peine moins simple :

Code : Tout sélectionner

<<
	DUP SIZE 2 SWAP SUB
>>

Voici une premiière tentative testée sur hp-28s /// réel ⇒ liste "binaire" :

Code : Tout sélectionner

<<
     BIN R→B                   @ transforme le réel saisi en un "binary"
     →STR DUP                  @ transforme le "binary" en une chaîne de chars
     SIZE 1 − 3 SWAP SUB       @ Suppress des 2 car de tête (# et espace) et de "b" (à la fin)
     DUP SIZE                  @ Taille de la chaîne "nettoyée"
     {} → l                    @ Initialisation d'une var locale (liste vide)
     <<
          1 SWAP	
          FOR i                @ Boucle de 1 à "SIZE" (taille du chars)
               DUP
               IF i i SUB "1" ==        @ si le i⋅ème car est égal à "1"
                 THEN l 1 + 'l' STO     @ alors on ajoute 1 à 'l' 
                 ELSE l 0 + 'l' STO     @ sinon (donc égal à "0") on ajoute 0 à 'l'
               END
          NEXT
          DROP                 @ Suppress d'un élt résiduel sur la pile
          l                    @ Valeur de l = résultat
     >>
>>
(164 octets)


En travaillant avec la chaîne de caractères telle qu'elle est (= sans "nettoyage" ), j'ai pu descendre à 151,5 octets.
C'est ce que j'ai fait ici :

Code : Tout sélectionner

<<
     BIN R→B                   @ Transforme le réel saisi en un "binary"
     →STR DUP                  @ Transforme le "binary" en une chaîne de chars
     SIZE 1 −                  @ Taille de la chaîne moins le "b" (à la fin)
     {} → l                    @ Initialisation d'une var locale (liste vide)
     <<
          3 SWAP               @ SWAP valeurs : 3 et "SIZE − 1"
          FOR i                @ Boucle de 3 à "SIZE − 1"
               DUP                   
                 i i SUB "1" ==      @ si le i⋅ème car est égal à "1"
                 "l 1 + 'l' STO"     @ alors on ajoutera 1 à 'l'
                 "l 0 + 'l' STO"     @ sinon (donc égal à "0") on ajoutera 0 à 'l'
                 IFTE                
                 STR→                @ exécution clause (vraie ou fausse) écrite sous forme d'une chaîne
          NEXT
          DROP                 @ Suppress d'un élt résiduel sur la pile
          l                    @ Valeur de l / Résultat
     >>
>>
129,5 octets… plus court mais plus lent (et nettement sur une hp-28) !


Pour le "fun", une variante très lisible (… enfin je crois :mrgreen: ) avec deux variables locales :

Code : Tout sélectionner

<<
     BIN R→B                   @ transforme le réel saisi en un "binary"
     →STR DUP                  @ transforme le "binary" en une chaîne de chars
     SIZE 1 − 3 SWAP SUB       @ Suppress des 2 car de tête (# et espace) et de "b" (à la fin)
     {} → char l               @ Initialisation de 2 var locales (avec chaîne "nettoyée" / liste vide)
     <<
          1 char SIZE	       
          FOR i                @ Boucle de 1 à "SIZE" (taille de la chaîne)
               char
               IF i i SUB "1" ==        @ si le i⋅ème car est égal à "1"
                 THEN l 1 + 'l' STO     @ alors on ajoute 1 à 'l'
                 ELSE l 0 + 'l' STO     @ sinon (donc égal à "0") on ajoute 0 à 'l'
               END
          NEXT
          l                    @ Valeur de l = résultat
     >>
>>   
(176,5 octets)
Bruno
Sanyo CZ-0124 ? TI-57 ? HP-15C ? Canon X-07 + XP-140 Monitor Card ? HP-41CX ? HP-28S ? HP-50G ? HP-50G
Avatar du membre
C.Ret
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 3404
Enregistré le : 31 mai 2008 23:43
Localisation : N 49°22 E 6°10

Re: Misez p'tit Optimisez n°96 : Combien de bits à un dans cet entier ?

Message par C.Ret »

FLISZT a écrit : 02 sept. 2022 08:01Évidement, pas de TAIL (hp-48gx… ), pas de SREPL (hp-49g… ), ni même de REPL (hp-48sx… ) !
Héhé c'est là bien tout le charme de cette machine; le plus primitif et dépourvu des RPL.

Une bonne solution pour corriger ces lacunes est effectivement de créer les manques et de coder ses propres TAIL, REPL ou autre DOSUB ... C'est ce que je faisais en 1992 et j'avais pas moins d'une trentaine de de "primitives" que j'utilisais dans tous mes calculs, programmes ou utilitaires (gestion des sous-répertoires, données ou programmes, mise en forme des impressions, etc...). Cela marchait bien et rendait les codes bien plus courts, fonctionnels et surtout plus facile à maintenir... L'HP-28S est ainsi resté mon assistant numérique professionnel jusqu'en 2008.

Une autre solution est de se passer des TAIL, SREPL, REPL ou autre DOSUB ou MAP en codant la transformation en un seul programme autonome. C'est en réalité une solution moins astucieuse qui ne tire pas parti de l'esprit global de la machine; faire un réseau personnel de petits utilitaires courts qui s'emboitent à l'infini pour faire des programmes et utilitaires plus complexes est certainement la solution modulaire à privilégier. Elle optimise en fait l'utilisation de la mémoire et rends les codes plus courts, plus simples et plus facile à maintenir ou débugger.
C'est pas contre un code qu'il est plus facile de partager ici, surtout si le code en question est très court.

Je donne donc ci-dessous une solution possible de →BLST qui transforme un entier en la liste binaire le représentant.
Il ne s'agit donc pas de ma version personnelle qui utiliserai des "primitives" personnelles telles RSTF pour sauvegarder et restorer les modes du HP-28S (ce code a donc l'inconvénient de sélectionner le mode BIN et de ne pas le restaurer. Lorsque j'utilisais mon HP-28S dans mes activité professionnelles cela n'aurait pas été maintenu ainsi, très vite le code aurait été modifié pour s'intégrer.
Mais c'est un code bien fonctionnel et surtout facile à partager ici, tout le monde pourra l'essayer sans avoir à programmer de multiples arcanes.

→BLST prend le nombre au niveau 1: de la pile et le remplace par la liste binaire, car composée uniquement de 0 et de 1, correspondant à sa représentation binaire.

Code : Tout sélectionner

→BLST:
« { ] BIN SWAP R→B DO DUP #1b AND B→R ROT + SWAP SR UNTIL DUP #0b == END DROP »
( 81 bytes)

Le début du programme crée la liste vide { } qui sera la liste résultat.
Puis il sélectionne le mode BIN et converti le nombre donné en argument en un entier binaire à l'aide de R→B. C'est là la méthode la plus directe pour obtenir la représentation binaire d'un nombre.
Ensuite une boucle utilise l'entier binaire pour construire élément par élément la liste résultat en égrainant les bits à l'aide de l'instruction SR.
Notons qu'il n'y a pas de tests rendus inutiles car chaque élément est en fait simplement le résultat d'un DUP #1 AND.
La fin de la construction est détectée en testant la valeur de l'entier binaire.
En fin, le programme efface la valeur finale de l'entier binaire pour ne laisser que la liste résultat.

20220903 →BLST affiche { 1 0 0 1 1 0 1 0 0 1 0 0 0 1 0 1 1 1 1 1 0 0 1 1 1 }

Notons qu'il est alors facile d'obtenir le nombre de bits à un, soit en transformant le résultat de →BLST (ce qui serait bien dans l'esprit du HP-28S), soit en modifiant le code (méthode hérétique)

Code : Tout sélectionner

→B:
« 0 BIN SWAP R→B DO DUP #1b AND B→R ROT + SWAP SR UNTIL DUP #0b == END DROP »
( 78.5 bytes)
SHARP PC-1211 PC-1360 EL-5150 PC-E500 | Commodore C=128D | Texas Instruments Ti-57LCD Ti-74BASICalc Ti-92II Ti-58c Ti-95PROCalc Ti-30XPROMathPrint | Hewlett-Packard HP-28S HP-41C HP-15C HP-Prime HP-71B | CASIO fx-602p | NUMWORKS | Graphoplex Rietz Neperlog | PockEmul | Sommaire des M.P.O. | Ma...dov'il sapone.
FLISZT
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 655
Enregistré le : 09 mars 2022 19:14

Re: Misez p'tit Optimisez n°96 : Combien de bits à un dans cet entier ?

Message par FLISZT »

Bonjour,

Première constatation : j'ai écrit « évidement » !
À croire que j'étais à fond dans l'esprit MPO mais pas à bon escient ! :mrgreen:

Je suis tout à faire d'accord avec toi C.Ret, l'idée du RPL est de créer son propre vocabulaire.
C'est bien dans l'esprit du FORTH − selon ce que j'en ai compris − langage dont découle le RPL pour partie.

Par exemple, on peut faire une routine qui va insérer un << HALT >> quand on veut tester un prog.
Une autre va supprimer ce même << HALT >> une fois le test terminé.

Composer des modules, entre autres avantages, rend la programmation en RPL plus lisible… et modulaire. :mrgreen:

Vingt-cinq lignes de << DUP ROT SWAP POS … :: → a ← b << ←b >> NEXT END HALT ; >>

… ça pique les yeux bien avant la fin. 8O :geek:

… et ça peut même parfois être dangereux pour la santé psychique voire physique : :evil: :pirat:

Mais publier un prog en "morceaux" sur un forum, c'est peut-être moins bien en termes de présentation / lecture (?).
En tout cas, ça peut coûter des octets dans un MPO…

Perso, je n'aime pas trop jongler avec la pile bien qu'on y soit toujours "contraint" à minima en RPL.
Je ne suis pas arrivé à me débarrasser du DROP de fin, sauf dans mon prog utilisant deux (oui… pardon :oops: ) variables locales.
Je vois que toi aussi… pour l'instant. Peut-être que d'ici peu…

Après… le RPL et son inséparable amie la pile − dite "la gloutonne", "l'affâmée", "TVA", "la sulfateuse" ou encore "Halt Zoll" outre-Rhin − ont leurs exigences… (oops, le frein à main était desserré ! ) :lol:

Comme toujours (non ? :wink: ), tes programmes sont très astucieux.
Je n'ai pas l'habitude de manier la langue de Monsieur Boole ni donc les possibilités de la hp-28 dans ce domaine.
Ici, une hp-50g ne fait pas mieux que son aînée.

Évidemment ( :wink: ) dans un MPO qui traite de bits, les fonctions boléennes peuvent être utiles voire même décisives !

J'ai fait tourner en mode pas-à-pas tes deux programmes sur ma hp-50g (le confort de l'écran, toussa… ) pour mieux les comprendre…

Bravo !

Tout cela m'a fait penser que des MPO (*) qui auraient pour thème de simuler telle ou telle fonction pourraient être intéressants.

Exemples avec des machines qui peuvent manipuler des listes : simulation des fonctions MAP, ΣLIST, MAX, etc.
(les plus récentes "Basic Casio" ou "Basic TI" sauf erreur(s) et autres RPL, LISP sur Casio AI-1000 ou Python)

En tout cas, ce MPO m'aura bien amusé ! :)

Edit : (*) MPO ou rubrique Pot Commun ?
Bruno
Sanyo CZ-0124 ? TI-57 ? HP-15C ? Canon X-07 + XP-140 Monitor Card ? HP-41CX ? HP-28S ? HP-50G ? HP-50G
Avatar du membre
Schraf
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 499
Enregistré le : 05 mars 2020 20:45
Contact :

Re: Misez p'tit Optimisez n°96 : Combien de bits à un dans cet entier ?

Message par Schraf »

Je suis en train de préparer une petite vidéo de présentation de l'application RPN83P qui permet d'avoir une calculatrice RPN sur une TI 83+ ou 84+. Le projet est actuellement en évolution mais déjà pas mal de fonctionnalités intéressantes, en particulier il y a les fonctions arithmétiques du HP 16C ce qui permet de répondre à ce MPO. Comme cette calculatrice RPN n'est pas encore programmable (c'est dans les projets du créateur), je ne peux donner que la commande qui est CNTB (Count BIT)

Nombre de bits à 1 dans 20220903
Nombre de bits à 1 dans 20220903
cntb.jpg (35.89 Kio) Vu 250 fois

En savoir plus sur l'appli : https://github.com/bxparks/rpn83p
Avatar du membre
C.Ret
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 3404
Enregistré le : 31 mai 2008 23:43
Localisation : N 49°22 E 6°10

Re: Misez p'tit Optimisez n°96 : Combien de bits à un dans cet entier ?

Message par C.Ret »

Ah! Du RPN sur des Ti ? Ca fait bizarre, mais effectivement les Ti-83 et Ti-84+ ont une touche ENTER. Alors je dis pourquoi pas :)

Mais, que fait-on des touches parenthèses ?? :mrgreen: :mrgreen:

P.S./ Je voulais juste confirmer que je trouve bien moi aussi 14 bits à un dans 20220903, mais aujourd'hui nous sommes le 20240205. Ca va aller, ça fait aussi 14 bits à un.
SHARP PC-1211 PC-1360 EL-5150 PC-E500 | Commodore C=128D | Texas Instruments Ti-57LCD Ti-74BASICalc Ti-92II Ti-58c Ti-95PROCalc Ti-30XPROMathPrint | Hewlett-Packard HP-28S HP-41C HP-15C HP-Prime HP-71B | CASIO fx-602p | NUMWORKS | Graphoplex Rietz Neperlog | PockEmul | Sommaire des M.P.O. | Ma...dov'il sapone.
Avatar du membre
tyann
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 845
Enregistré le : 06 oct. 2012 14:37

Re: Misez p'tit Optimisez n°96 : Combien de bits à un dans cet entier ?

Message par tyann »

Bonsoir

Je propose une version pour fx-702p avec une piste qui n'a pas été explorée :
Utiliser la fonction 'SIGNE' sur la partie fractionnaire de la division pour incrémenter le compteur de 1.

Code : Tout sélectionner

10 VAC :INP A
12 IF A>0;A=A/2:B=B+SGN FRAC A:A=INT A:GOTO 12
14 PRT B
42 octets, sur le petit Casio le test IF A ne passe pas --> ERREUR 5
Je voulais faire ça sur ma Ti 95 mais à ma grande surprise celle ci répond 1
à SGN 0 comme la Hp 41.

Version optimisée 38 octets

Code : Tout sélectionner

1 VAC :INP A
2 IF INT A>0;A=INT A/2:B=B+SGN FRAC A:GOTO 2
2 PRT B
Ti(s) 60, 62 Galaxy, 66, 67 Galaxy, 68, 74 Basical 80, 81, 82, 83+, 83 CE, 84+SE, 85, 86, 89, 89 titanium, 92, 95 Procalc, v200, nSpire cx
Hp(s) 35s, 41CX, 28S, 48g, 50g, 39gII, Prime G1 et G2,
Casio(s) fx 602P, 702P, 4000P, 4500P, 6000G, 6900G, 7700G, 8500g, PB-700, CG-20, Graph 95 sd
Psion(s)II LZ64, siena, s3a, s3mx, s5mx.
Sharp(s) pc-1350, 1403, 1500A, E500, El 5120, 9200, 9600
Canon X-07
Répondre

Retourner vers « Tous les Pockets »