Misez p'tit, Optimisez - N°116 : Jeu "RamiSum"

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

Répondre
Avatar du membre
Schraf
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 499
Enregistré le : 05 mars 2020 20:45
Contact :

Misez p'tit, Optimisez - N°116 : Jeu "RamiSum"

Message par Schraf »

Vous connaissez probablement le jeu de cartes rami ou le Rummikub, une de ses variantes. Il s'agit pour résumer de déposer au moins 3 cartes (ou jetons) ayant des valeurs identiques ou en ordre croissant.

Afin que ce MPO soit accessible aux machines ayant peu de pas de programme, notre mini-jeu RamiSum se bornera aux valeurs identiques. Plus précisément les seules combinaisons valables sont celles avec au moins 3 nombres identiques.

Quelques exemples :

J'ai le tirage 84884284, les combinaisons valables sont 888, 8888 et 444.
J'ai le tirage 123456, je ne peux pas jouer

Votre mission :

En entrée : un nombre composé de chiffres entre 1 et 9, de taille arbitraire (on peut en effet imaginer que l'on a pioché beaucoup de jetons)
En sortie : le score maximum que l'on peut obtenir ou 0 si aucun coup n'est possible.

Exemples :

Code : Tout sélectionner

MPO116(84884284) = 32	' 4 * 8 = 32
MPO116(123456) = 0
MPO116(444444999) = 27	' 3 * 9 > 6 * 4
MPO116(44499) = 12
MPO116(11) = 0
MPO116(111) = 3
Démo en vidéo du résultat attendu (sur un PSION ORGANISER II)

Sommaire des MPO
FLISZT
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 655
Enregistré le : 09 mars 2022 19:14

Re: Misez p'tit, Optimisez - N°116 : Jeu "RamiSum"

Message par FLISZT »

Hier soir avant de manger, j'ai fait un premier programme. Il fonctionne avec une liste en entrée…

Manque de chance j'ai oublié certains éléments de l'énoncé. :mrgreen:

Du coup, il ne fonctionne pas pour (par ex.) :

MPO116(123456) = 0 … mon programme retourne 6 !
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°116 : Jeu "RamiSum"

Message par C.Ret »

Bon ,je me lance avec un code pour HP-71B (muni d'un module JPC:E et un module MATH:1A.

Mais ce premier jet d'instructions est très certainement perfectible.

Code : Tout sélectionner

CAT
MPO116   BASIC   116 octets  22/03/23 22:27
LIST
10 DIM N(9)
 @ LOOP
 @    MAT N=ZER @ S=0 @ M$=""
 @    REPEAT
 @       DISP M$;S
 @       C=VAL(KEYWAIT$)
20       IF C THEN M$=M$&STR$(C) @ N(C)=N(C)+1 @ S=MAX(S,C*RES*(RES>2))
30    UNTIL NOT C
 @ END LOOP
Utilisation: lancer le programme avec la touche [ RUN ] ou une commande ad'hoc.
Le pocket affiche uniquement la main et le score maximal.
Pour ajouter une carte à la main utiliser les touches 1 à 9. L'affichage se met à jour après chaque pression d'une touche.
Appuyer sur la touche 0 pour remettre à zéro la main et le score.
Pour sortir appuyer sur une touche fonction (ON, RUN, END-LINE, = , SPC ,etc) ou sur la lettre N. La lettre C permet de répéter la dernière touche.
Le programme finit sur une erreur. C'est normal, j'ai pas cherché à faire propre.

Petits exemples d'utilisation:
[Touche] Affichage

Code : Tout sélectionner

[RUN]    0   
[ 8 ]   8 0
[ 4 ]   84 0
[ 8 ]   848 0
[ 8 ]   8488 24
[ 4 ]   84884 24
[ 2 ]   848842 24
[ 8 ]   8488428 32
[ 4 ]   84884284 32

Code : Tout sélectionner

[ 0 ]    0
[ 4 ]   4 0
[ 9 ]   49 0
[ 4 ]   494 0
[ 4 ]   4944 12
[ 9 ]   49449 12
[ 4 ]   494494 16
[ 4 ]   4944944 20
[ 9 ]   49449449 27
[ 4 ]   494494494 27
10 DIM N(9) @ LOOP @ MAT N=ZER @ S=0 @ M$="" @ REPEAT @ DISP M$;S @ C=VAL(KEYWAIT$)
20 IF C THEN M$=M$&STR$(C) @ N(C)=N(C)+1 @ S=MAX(S,C*RES*(RES>2))
30 UNTIL NOT C @ END LOOP
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
zpalm
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 2918
Enregistré le : 03 mai 2008 15:33
Localisation : Grenoble

Re: Misez p'tit, Optimisez - N°116 : Jeu "RamiSum"

Message par zpalm »

Voici un petit programme pour HP Prime utilisant des listes:

Code : Tout sélectionner

EXPORT MPO116(N)
BEGIN
 L1:=ASC(STRING(N))-48;
 L2:=EXECON("ΣLIST(L1==&1)",L1);
 MAX(L1*L2*(L2>2));
END;
Je l’ai testé avec les différents exemples et il donne les résultats attendus.

EDIT: je n’avais pas vu le code de C.Ret avant de poster le mien , mais j’y retrouve certaines similitudes.
FLISZT
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 655
Enregistré le : 09 mars 2022 19:14

Re: Misez p'tit, Optimisez - N°116 : Jeu "RamiSum"

Message par FLISZT »


Dans le MPO-114, j'avais donné dans l'accélérateur nucléaire.
Inspiré (?) par Rachmaninov et Prokofiev, cette nuit j'ai donné dans l'usine à gaz et dans le jonglage entre pile, listes dont une liste de listes…

Le programme principal M116 :

Code : Tout sélectionner

<< {{0 0} {0 0} {0 0} {0 0} {0 0} {0 0} {0 0} {0 0} {0 0}} → A Z
	<<	1 A SIZE FOR k 
			A k GET DUP
			Z SWAP GET 
			1 ROT PUT DUP
			2 GET 1 +
			2 SWAP PUT
			Z A k GET ROT PUT
			'Z' STO 
		NEXT
		Z FILTR
		1 << ∏LIST >> DOLIST
		SORT DUP SIZE GET
	>>
>>
La routine FILTR pour filtrer (les impuretés gazeuses inférieures à 3 Å) :

Code : Tout sélectionner

<< → a
	<<	1 a SIZE 
		FOR j
		a j GET DUP 2 GET
		3 < IF
			THEN 2 0 PUT a j ROT PUT 'a' STO
			ELSE DROP
			END
		NEXT
	>>
>> 
L'application est certifiée "Schraf-tests-2023" .

Usage : entrer une liste de n chiffres (avec n ≠ 0) puis lancer le programme 'M116' (pas trop fort…).

Bilan : ce n'est pas "tout à fait" optimisé (pour partie l'algo consiste à défaire ce qui a été fait :oops: ) mais ça tient éveillé !

:D
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°116 : Jeu "RamiSum"

Message par FLISZT »

Une optimisation du programme principale :oops: :

Code : Tout sélectionner

<< {{1 0} {2 0} {3 0} {4 0} {5 0} {6 0} {7 0} {8 0} {9 0}} → A Z
	<<	1 A SIZE FOR k 
			A k GET DUP
			Z SWAP GET DUP
			2 GET 1 +
			2 SWAP PUT
			Z UNROT PUT
			'Z' STO
		NEXT
		Z FILTR
		1 << ∏LIST >> DOLIST
		SORT
		DUP SIZE GET
	>>
>>
:lol:
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°116 : Jeu "RamiSum"

Message par Schraf »

@FLIZT : Ca ressemble effectivement à un réacteur nucléaire, je cours acheter une carte 256Mo à mettre sur ma HP 50g pour tester ton programme 😆 !

Voici ma version pour la HP 50g (j'ai pas testé sur les HP 48-49 mais a priori ça devrait fonctionner) :

Code : Tout sélectionner

« 0 + →t 	' j'ajoute 0 à la liste car ΣLIST ne fonctionne pas lorsqu'il y a un unique élément
« 0 1 9 FOR i 	' On teste les chiffres de 1 à 9. Le '0' correspond à l'initialisation du MAX
  t i - NOT	' On cherche les éléments égaux à 'i', astuce avec '-' puis NOT car '==' ne fonctionne pas
  ΣLIST		' Calcul du nombre d'éléments dans 't' égaux à 'i'
  DUP 2 > * i *	' Si > 2 on a 1 dans la pile sinon 0. Même astuce que @zpalm et @C.Ret en faisant ensuite le produit par 'i'
  MAX NEXT » »	' MAX entre le résultat et le maximum précédent

'MPO116 STO

{4 4 4 4 9 9 9 }
VAR MPO116
27

{1}
MPO116
0
Une autre solution serait comme @zpalm de tester uniquement les chiffres qui composent le nombre du départ et pas tous les chiffres de 1 à 9. Ceci dit, si je ne dis pas de bêtise, l'algo de @zpalm comporte malgré tout des répétitions, par exemple avec N=11111111, le même calcul sera répété 8 fois.

Astuce du "- NOT "pour remplacer le "==" :

Code : Tout sélectionner

2: {4 4 9 4 9 9}
1: 4
==	'PRG - TEST - ==
1: 0	' Ne fonctionne pas, alors que cela marche avec >, < etc.

2: {4 4 9 4 9 9}
1: 4
-
1: {0 0 5 0 5 5}
NOT
1: {1 1 0 1 0 0}	' On a bien trouvé les éléments égaux à 4
Avatar du membre
zpalm
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 2918
Enregistré le : 03 mai 2008 15:33
Localisation : Grenoble

Re: Misez p'tit, Optimisez - N°116 : Jeu "RamiSum"

Message par zpalm »

Schraf a écrit : 23 mars 2023 12:58 Une autre solution serait comme @zpalm de tester uniqueme les chiffres qui composent le nombre du départ et pas tous les chiffres de 1 à 9. Ceci dit, si je ne dis pas de bêtise, l'algo de @zpalm comporte malgré tout des répétitions, par exemple avec N=11111111, le même calcul sera répété 8 fois.
C’est vrai que chaque chiffre du nombre de départ est considéré séparément donc on va refaire le calcul plusieurs fois si un chiffre apparaît plusieurs fois. J’ai privilégié la compacité du code. On peut optimiser le nombre d’opérations en ajoutant une liste intermédiaire :

Code : Tout sélectionner

EXPORT MPO116(N)
BEGIN
 L1:=ASC(STRING(N))-48;
 L2:=UNION(L1);
 L3:=EXECON("ΣLIST(L1==&1)",L2);
 MAX(L2*L3*(L3>2));
END;
Avatar du membre
zpalm
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 2918
Enregistré le : 03 mai 2008 15:33
Localisation : Grenoble

Re: Misez p'tit, Optimisez - N°116 : Jeu "RamiSum"

Message par zpalm »

Une version pour la WP 34s:

Code : Tout sélectionner

001 LBL "A"
002 CLREGS
003 RCL X          
004 #010  
005 MOD 
006 INC->X    
007 3   
008 RCL->Y 
009 x<? Y
010 CLx
011 RCL* Z 
012 STO↑ 00 
013 R↑
014 SDR 001
015 IP
016 X#0?
017 BACK 014
018 RCL 00
019 END
A noter au pas 012 l’instruction STO↑ 00 (STO Max 00) qui stocke dans R00 le max de X et de R00.
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°116 : Jeu "RamiSum"

Message par C.Ret »

Joli, ce dernier code ressemble un peu à ce que j'ai mis sur mon HP-41C.

Par contre, c'est quoi l'instruction SDR 001 ?


J'ai trouvé le moyen de dépasser la limite des dix cartes par main sur mon HP-41C avec le code suivant:

Code : Tout sélectionner

01 LBL"MPO116
02   CLRG  CLA
04   LBL 00
05     ARCL X
06     LBL 01
07       STO 00  10  ST/ 00  MOD  X>0?  ISG IND X  GTO 02
14       RCL 10  RCL IND Y  3  X>Y?  GTO 02
19       X<> T  *  X>Y?  STO 10
23     LBL 02
24     RCL 00  INT  X>0?  GTO 01
28   RCL 10  AVIEW  STOP
31   GTO 00
.END.
Evidemment, ce code est un tout petit peu plus long que celui ne pouvant traiter qu'une main d'au plus dix chiffres.

L'astuce consiste à accumuler les mains d'au plus dix cartes en les séparant d'une pression sur la touche R/S.
On utilise f-RTN pour indiquer une nouvelle série de mains.
On saisie une main et on presse R/S, cette main est ajoutée au cumul.
Le registre alpha accumule la composition des mains et les registre R01 à R09 le nombre d'occurrences de chaque chiffre. R10 mémorise le score maximal et R00 sert à la décomposition numérique de la saisie.

Il est recommandé d'utiliser le format d'affichage FIX 0 CF 29.


Par exemple:
11 XEQ "MPO116" affiche la main "11" presser sur [<- ] pour voir apparaitre le score 0.
1 R/S affiche le cumul des mains saisies "111" une pression sur [ <- ] affiche le score 3.

Pour recommencer, on réinitialise à l'aide de l'instruction RTN :
shift RTN 4444 R/S affiche "4444" puis [ <- ] affiche le score 16.
999 R/S affiche "4444999" et [<- ] affiche le score 27.

On peut aussi faire
shift RTN 4444 R/S qui affiche "4444" taper 999 R/S qui affiche 4444999 et presser sur [ <- ] pour voir le score 27.
ou
4444999 shift RTN R/S qui affiche "4444999" et presser [ <- ] qui affiche 27.

On peut accumuler autant de mains que l'on souhaite. Le registre ALPHA sera limité aux 24 derniers chiffres, mais pas le score qui fait le décompte de toutes les entrées.

A tout moment , une pression sur la touche [ALPHA] affiche la main cumulée.
Modifié en dernier par C.Ret le 23 mars 2023 22:11, 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.
Avatar du membre
zpalm
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 2918
Enregistré le : 03 mai 2008 15:33
Localisation : Grenoble

Re: Misez p'tit, Optimisez - N°116 : Jeu "RamiSum"

Message par zpalm »

C.Ret a écrit : 23 mars 2023 21:51 Joli, ce dernier code ressemble un peu à ce que j'ai mis sur mon HP-41C.

Par contre, c'est quoi l'instruction SDR 001 ?.
Shifts Digits Right, SDR 001 revient à diviser par 10.
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°116 : Jeu "RamiSum"

Message par C.Ret »

zpalm a écrit : 23 mars 2023 22:07Shifts Digits Right, SDR 001 revient à diviser par 10.

Merci zpalm !

C'est une sorte de 10 ST/01 en une seule instruction. Nos deux programmes se ressemblent donc beaucoup plus que je ne l'ai cru au premier coup d'œil.

La WP-34S (et entre SM 43) devraient être interdites aux MPOs, avec leur sauts directs qui économisent les nombreux LBL/GTO, leurs instructions qui cumulent plusieurs opérations, l'arithmétique mémoire et autres RCL->Y et bizarreries qui dispensent de toutes opérations de mouvement de la pile,...

Je comprends mieux pourquoi mon code, qui ressemble si fortement dans le principe de fonctionnement, fait presque le double de pas.
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
zpalm
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 2918
Enregistré le : 03 mai 2008 15:33
Localisation : Grenoble

Re: Misez p'tit, Optimisez - N°116 : Jeu "RamiSum"

Message par zpalm »

C.Ret a écrit : 23 mars 2023 22:18 La WP-34S (et entre SM 43) devraient être interdites aux MPOs, avec leur sauts directs qui économisent les nombreux LBL/GTO, leurs instructions qui cumulent plusieurs opérations, l'arithmétique mémoire et autres RCL->Y et bizarreries qui dispensent de toutes opérations de mouvement de la pile,...
Voici la version WP43, quasi identique mais qui fonctionne avec des nombres entiers jusqu’à 1000 digits.

Code : Tout sélectionner

001 LBL "MPO116"
002 0.1
003 R-CLR
004 DROP
005 RCL X          
006 10  
007 MOD 
008 INC->X    
009 3   
010 RCL->Y 
011 x<? Y
012 CLX
013 RCL* Z 
014 STO↑ 00
015 R↑
016 SDR 001
017 X#0?
018 BACK 014
019 RCL 00
020 END
Étrangement l’instruction CLREGS n’est pas programmable sur la WP43, je l’ai remplacée par R-CLR plus sélective, qui permet de n’effacer ici que 10 registres en partant de R00, au prix de deux pas supplémentaires. On en regagne un en supprimant IP qui n’est pas nécessaire avec les nombres de type entier (vs. réels).
Avatar du membre
Marge
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 6172
Enregistré le : 01 oct. 2008 14:39
Localisation : En bas, tout au fond à gauche.

Re: Misez p'tit, Optimisez - N°116 : Jeu "RamiSum"

Message par Marge »

Bonsoir, voici une version assez longue en RPN pour HP-29C.

Après avoir mesuré la longueur (le cardinal, me semble-t-il) du nombre (LBL 9), le programme compte les occurences indirectement dans les registres 1 à 9 (LBL 8) puis, une fois tous les chiffres passés en revue, vérifie pour chaque registre s’il contient plus d'une paire (LBL 7) auquel cas il compare le contenu du registre 10 (attention, registre à double emploi) avec le total obtenu (LBL 6) et si ce dernier est supérieur, place ce nouveau résultat dans ledit registre (LBL 5). La présentation du résultat se fait à la fin, après un effacement des registres (LBL 0).

Code : Tout sélectionner

LBL 9         0          Rd           GTO 8         GTO 0       LBL 5
ENTER         /          Rd           9             LBL 6       X<~>Y
LOG           ENTER      INT          STO 0         RCL 0       STO.0
INT           FRAC       RCL.0        LBL 7         *           DSZ
1             1          STO 0        2             RCL.0       GTO 7
+             0          1            RCL(i)        X<=Y        LBL 0
STO.0         *          -            X>Y           GTO 5       RCL.0
Rd            STO 0      STO.0        GTO 6         DSZ         CLEAR REG.
LBL 8         1          Rd           DSZ           GTO 7       RTN
1             STO+(i)    DSZ          GTO 7         GTO 0
59 pas, 11 registres : 136 octets.
3 hommes, 3 demis, un 3a... Magnéto, Serge !

Quelques-uns de mes petits programmes pour machines Hewlett-Packard :
15C : Knight's Tour ;
29C : (k-)Permutations, Combinations, Linear Regression and Pseudo-random number ;
34C : Hanoi Towers - Automatic & Manual resolutions ;
67
__: A L I E N .

« Boris », c'était juste Maurice enrhumé.
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°116 : Jeu "RamiSum"

Message par Schraf »

Merci pour toutes vos propositions... pour les HP !

Mais la version de @Marge inspirera peut-être les adeptes des autres marques.

Dans un langage de haut niveau comme Python, cela peut donner :

Code : Tout sélectionner

from collections import Counter

def mpo116(n):
  return max(int(k) * v * (v > 2) for (k, v) in Counter(str(n)).items())
  
>> list(map(mpo116,(84884284, 123456, 444444999, 44499, 11, 111, 1)))
[32, 0, 27, 12, 0, 3, 0]

>> Counter('44444999')
Counter({'4': 5, '9': 3})
Et sur les calculatrices récentes ayant Python mais pas la bibliothèque collections :

Code : Tout sélectionner

def mpo116(n):
 s = str(n)
 return max(v * u * (u > 2) for (v, u) in ((int(v), s.count(v)) for v in set(s))) 
Le script et exemples ici
Répondre

Retourner vers « Tous les Pockets »