Grace au
MPO 75 je me suis penché dans mes archives et je me suis apercu que je n'avais pas posté ma solution à celui-ci. La voici donc telle que je l'avais rédigée alors.
Tout d'abord comme ledudu j'ai regardé le comportement de la suite ce qui m'a permis de trouver un algorithme de calcul évitant les boucles et les délais de la récursion.
En effet à partir de u
3, la suite se compose de la série des entiers n >1 répétés n fois: 11 22 333 4444 55555 666666 7777777 ...
On en déduit que si u
x = n alors x-1 se trouve dans l'intervalle ](n-1)n/2, n(n+1)/2], soit: ](n²-n)/2, (n²+n)/2]
n²/2 étant au milieu de cet intervalle alors INT(SQRT(2x)) est égal soit à n soit à n-1 suivant la position de x par rapport n²/2.
On arrive à l'algorithme suivant permettant de calculer u
x:
- n=INT(SQRT(2x))
- si n(n+1)/2 < x-1 alors n=n+1 (le test peut aussi se faire sur <= x-2)
- ux = n
L'avantage de cet algorithme c'est qu'il donne un résultat exact pour u
x quelque soit x dans la limite des entiers supportés par la machine que l'on utilise, ce qui permet de valider des formules approchées.
Ma solution en 15 pas sur WP 34S:
Code : Tout sélectionner
01 LBL A 09 RCL* Y
02 DEC X 10 2
03 RCL X 11 /
04 RCL+ X 12 x<? Z
05 SQRT 13 INC Y
06 IP 14 RDN
07 RCL X 15 RTN
08 INC X
En 21 pas sur HP 41C:
Code : Tout sélectionner
01 LBL"BR 11 RCL Y 21 RTN
02 RCL X 12 *
03 2 13 2
04 ST- Z 14 /
05 * 15 RCL Z
06 SQRT 16 x<y?
07 INT 17 GTO 01
08 RCL X 18 ISG Z
09 1 19 LBL 01
10 + 20 RCL Z
En 63 pas sur Casio Pro FX-1:
Code : Tout sélectionner
001 ENT 1 :
004 2 = ? x K 2 ? + K 1 0 10^x - K 1 0 10^x :
022 3 = 2 + K 1 x 2 / K 2 + K 1 :
037 IF 3 = 1 : 2 : 3 : 3 :
048 ST# 2 : 2 = 2 + K 1 :
058 ST# 3 : ANS 2 :
Ensuite, C.Ret a proposé
une formule approchée qui malheureusement ne donne pas toujours le bon résultat, mais il m'a donné l'idée de reprendre le calcul en cherchant une formule approchée plus simple que l'algorithme précédent.
En repartant de l'intervalle défini ci-dessus, si u
x = n alors
(n²-n)/2 < x-1 donc n² < 2(x-1) + n donc n étant entier on a n = INT(SQRT(2(x-1) + n))
que l'on peut approximer par INT(SQRT(2(x-1) + INT(SQRT(2(x-1)))))
On peut vérifier que cette approximation donne de très bon résultats jusqu'à de très grandes valeurs de x (999.999.999) voire plus sur la 34S, au delà en fonction des machines on se heurte aux erreurs d'arrondi sur le calcul des racines carrées.
Ce qui donne en 12 pas sur HP 41C:
Code : Tout sélectionner
01 LBL"BR 07 SQRT
02 1 08 INT
03 - 09 +
04 2 10 SQRT
05 * 11 INT
06 ENTER 12 RTN
Enfin dprtl a eu
l'idée d'utiliser l'arrondi de l'affichage en FIX 0 qui évite le test de l'algorithme initial, ce qui m'a donné l'idée de ce programme sur WP 34S en 6 pas:
Je crois que seule la WP 34S dispose l'instruction ROUNDI: arrondi à l'entier le plus proche.