Bon, comme je n'avais pas mon HP-28S sous la main, j'ai composé une première solution pour SHARP PC-1360
Code : Tout sélectionner
10:CLEAR : INPUT "Lenght =";L,"Initial=";B:T=B/2,P=-(T=INT T): WAIT 0: USING : DIM H(L),E(L)
20:N=N+1,H(N)=B,E(B)=N,B=P,P= NOT P
30:IF N=L LET T=H(1):GOSUB 100: IF T FOR T=1 TO N: PRINT H(T);: NEXT T: BEEP 1: PRINT
40:B=2+B: IF B>L LET B=H(N),E(B)=0,H(N)=0,N=N-1,P= NOT P: GOTO 60
50:IF E(B)=0 LET T=B: GOSUB 100: IF T GOTO 20
60:IF N GOTO 40
70:BEEP 2: END
100:T=T+H(N): GOSUB 120: IF T=0 RETURN
110:T= ABS (T-2*H(N))
120:IF T=1 OR T=9 OR T=15 OR T=21 OR T=25 OR T=27 OR T=33 LET T=0
130:RETURN
avec:
L = Longueur de l'horloge
H() = Tableau des L heures premières déjà placées
E() = non nul pour les heures déjà placées
N = Nombre d'heures premières placées
B = Heure suivante / initiale
P = parité de la dernière heure placée (-1:pair 0:impair)
T = Argument et résultat du "test de primalité" (GOSUB 100)
Petites explications :
"pair+pair" et "impair+impair" donne des résultats "pair".
Il est donc nécessaire d'organiser les heures de l'horloge première en alternant heures paires et impaires.
Ensuite, parmi les nombres impairs que l'on peut composer avec les heures d'une horloge à 12, 14 ou 16 positions horaires, seuls 9 15 21 25 27 et 33 ne sont pas des nombres premiers (ainsi que 1 comme demandé dans l'énoncé).
Le test de primalité se réduit donc aux tests de la ligne 120. C'est plus simple et se sera réalisable (je l'espère) sur une HP-25C.
Ensuite pour que l'heure
b puisse suivre l'heure
a, il faut vérifier que
a+b et
|a-b| sont tous deux premiers.
Si l'on pose
T=a+b, le second test revient à tester
| T-2b | d'où la ligne 110
Le programme est basé sur une boucle de recherche, on donne la taille de l'horloge et l'heure initiale.
Les heures déjà données sont mémorisées dans le tableau H(), à la position H(N) se trouve la dernière heure posée de l'horloge.
La ligne 20 se charge de poser l'heure B dans l'horloge en incrémentant N et en mémorisant celle-ci dans le tableau à la position H(N). Comme il faut alterner heures paires et impaires, la parité P est changée en NOT P et B est initialisée à 0 ou -1 afin de commencer la recherche de l'heure suivante en testant successivement 2 4 6 8 ... ou 1 3 5 7 ... selon la parité de H(N).
Si on arrive à N=L c'est que l'horloge est remplie, on teste alors que la première heure et la dernière sont compatibles. On utilise pour cela le sous-programme commençant à la ligne 100 qui testera la primalité H(1)+H(N) et |H(1)-H(N)|.
Si les heures sont compatibles, la ligne 30 affiche l'horloge (en fait le contenu du tableau H()) et le pocket émet un BEEP pour faciliter le chronométrage.
Si l'horloge n'est pas remplie, la recherche d'une heure suivante possible commence à la ligne 40. Si l'on arrive à B>L, c'est qu'aucune heure ne convient, on retire alors la dernière heure posée de l'horloge en décrémentant N d'une unité. On prend le soin de mémoriser B qui servira pour la recherche de l'heure suivante et l'on change la parité P.
A la ligne 50, si l'heure B n'existe pas encore dans l'horloge, on effectue le test de parité de B+H(N) et |B-H(N)|. Si le test est valide, l'heure B est posée dans l'horloge.
Le tableau E() permet de facilement tester l'existence de l'heure dans l'horloge. En effet, une valeur (non nulle) est mémorisée dans E(B) pour chaque heure B posée (cf. ligne 20) et E(B) est remis à zéro pour chaque heure B retirée de l'horloge (cf. ligne 40).
Le rôle de E() est assez binaire, je compte sur HP-41C utiliser les drapeaux SF nn et CF nn pour mimer le rôle de E() en RPN.
Ce code, ne vérifie pas le sens de rotation de l'horloge, il donne donc pour l'horloge de 12 positions horaires les 2 solutions dans les deux sens :
Code : Tout sélectionner
Display: Keystrokes: Times:
-------- ----------- ------
RUN MODE [ON]
RUN [R][U][N][ENTER]
Lenght =12 [1][2][ENTER]
Inital =12_ [1][2]
[ENTER] 0'00"00
12.1.6.11.8.3.10.7.4.9.2.5. 1'11"98
12.5.2.9.4.1.6.11.8.3.10.7. 1'48"65
12.5.2.9.4.7.10.3.8.11.6.1. 1'57"45
12.7.10.3.8.11.6.1.4.9.2.5. 4'22"60
> 4'32"59
RUN [R][U][N][ENTER]
Lenght =14 [1][2][ENTER]
Inital =1 [1][ENTER] 0'00"00
1.4.7.10.13.6.11.8.3.14.9.2.5.12. 1'25"12
1.12.5.2.9.14.3.8.11.6.13.10.7.4. 12'50"35
> 15'32"59
J'ai sous le coude une version qui va 4x plus vite...
... c'est cette version que j'adapte pour le RPL et qui servira de base pour une solution en RPN.
Mais je suis loin encore d’une version pour HP-25C