Comme le mois dernier, ce challenge LabVIEW est sponsorisé par Programmez, le gagnant aura un abonnement de 1 an à ce magazine au format PDF. http://www.programmez.com/
Comment gagner ? et en passant assez peu de temps si possible ?
C’est parti !
Dans le thème de comprendre notre univers qui semble géré par des nombres, nous allons étudier la persistance des nombres en base 10. Cela correspond à quoi ? Il s’agit de multiplier les chiffres qui composent un nombre entier (en base 10 cette fois) et on obtient un nouveau nombre afin de recommencer le processus.
La persistance est le nombre de fois que l’on peut effectuer l’opération avant d’atteindre un chiffre unique.
Par exemple : 382 -> 3x8x2 = 48 (opération 1) -> 4x8 = 32 (opération 2) -> 3x2 = 6 (opération 3)
La persistance de 382 est de 3. Pour 679 la persistance est de 5…
Ce qui est magique c’est qu’actuellement, en base 10, on conjecture qu'il n'existe pas de nombre dont la persistance multiplicative est supérieure à 11 ! étrange…
Pour tenter de remporter le défi il faut écrire un programme LabVIEW qui puisse calculer les persistances jusqu’à 11 (et au-delà si possible).
En entrée une commande avec un nombre à saisir et en sortie un indicateur avec la persistance trouvée. Facile ?
Défi complémentaire optionnel :
Pour ceux qui arriveront à ce résultat, le défi complémentaire (pour le fun), afin de percer les rouages de l’univers, seront peut-être amusés de réaliser un code qui remplit un tableau des 65536 premières valeurs et de les placer dans un graphe d’intensité XY (1 = noir et 11 = très blanc) disposé en spirale. Y aurait-il des motifs récurrents dans le dessin ?
5----4----3
| | .
| | .
6 1----2 .
| |
| |
7----8----9----10
Envoyez votre code nommé Ch44_persistance_votre pseudo.vi à emmanuel.roset@ni.com avant le 1er Juin. Et postez s’il vous plait sur la communauté un message « code envoyé » pour vérifier ma boite email en cas de non réception.
Le gagnant sera tiré au sort (avec un jeu de hasard) parmi les bonnes réponses avec un code fonctionnel.
Les codes seront publiés à la fin du mois
Bon codage et attention aux dépassements de taille !
MAJ 09/06: Publication des codes réponses
Emmanuel
Bon, j'ai peut être mal compris l'énoncé car je n'arrive pas jusqu'à la persistance 11.
Pour des valeurs allant de 0 à 10000000, je trouve une persistance moyenne de 1,84 avec une plage de 1 à 8, et un temps de calcul de 14385 ms. On est bien d'accord que les chiffres uniques vont de 0 à 9, 0 compris ?
Aurais tu un exemple de valeur avec une persistance de 11 ?
NB : Chose étrange, en éditant mon poste, j'ai enfin pu faire des sauts de ligne pour apporter un peu de légèreté à mes propos....
Indice : La persistance 11 est beaucoup plus grande
Autre indice : Capable de calculer
J'en suis à la valeur 5000000000 (Je suis partie de la valeur 1 avec un incrément de 1 et je teste toute les persistances avec un arrêt une fois la persistance 11 obtenue) et ça doit bien faire 1H que mon programme tourne...L’approche brute n'a pas l'air très appropriée ici 🙂
Une valeur pour la persistance de 11 est 277777788888899. Il est demandé que le code puisse la calculer mais pas de la trouver (sauf par wikipedia par exemple ). Cela suffit pour le défi.
Mais il serai intéressant de pouvoir optimiser son code afin de prévoir en combien de temps il est possible de retrouver cette valeur en force brute en fonction de son PC. Des personnes ont remarqué que l'on peut sauter certains nombres qui comportent un 0 par exemple, et ainsi gagner du temps.
Amusez vous bien !
Aspect calcul : OK
Temps à passer pour trouver la valeur : En cours 🙂
J'ai pris connaissance de ce nouveau challenge hier, j'ai donc planché dessus histoire de faire un code.
Côté persistance 11, mon programme est en cours de recherche, mais bon, ça prend du temps 🙂 j'imagine, comme Emmanuel l'a précisé dans l'énoncé, que le persistance 12 a peu de probabilité d'exister 🙂
Affaire en cours
Pffff, j'en suis à 394830284789 et toujours rien trouvé pour une persistance 11 😞 et mon code tourne depuis hier non stop
Bien sûr, mais bon, c'est le temps qu'il faudrait pour trouver la solution qui me semble énorme, enfin, par cette méthode de test d'approche brute 😞
Je me demande d'ailleurs comment Emmanuel a fait pour trouver cette valeur, il nous prépare ce challenge depuis deux mois sans doute
PhilB58, oui, c'est possible qu'Emmanuel prépare ça depuis 2 mois ! Ou alors, il a pu regarder ici !
Je me pose personnellement la question de savoir comment réaliser efficacement le calcul de la persistance d'un nombre allant au-delà du U64 non-signé (ie. au delà de 18446744073709551600).
La seule méthode (lourde) que j'ai trouvé consiste à demander à l'utilisateur d'écrire le nombre voulu dans une chaine de caractère en interdisant tous les caractères autres que les chiffres grâce... à une structure évenement. Un bazooka pour une fourmi, en somme.
Cette conjecture n'a toujours pas été résolue pour savoir s'il existe une persistance supérieure à 11. A priori dans les années 80 il fallait une semaine de calcul, aujourd'hui il faut quelques minutes. Mais cela dépend de l'algorithme qui filtre et restreint les éléments inutiles (déduit en regardant les autres persistances) comme le 0 ou le fait qu'ils ont toujours un ordre croissant de gauche a droite, etc..
Je rappelle que pour gagner l’algorithme doit juste savoir gérer des chiffres en entrée suffisamment grands pour accepter la valeur de la première occurrence de persistance 11, même saisie à la main.
Mais c'est utile d'essayer d'optimiser son code pour qu'il tourne plus vite avec les fonction LabVIEW "elements en place" par exemple ou autres optimisations pour trouver la première persistance 11 le plus vite possible !
Merci pour les codes Julien_V avec en plus celui en spirale avec une méthode intéressante pour les obtenir les coordonnées. Un code qui sera partagé à la fin du mois.
Bonjour à tous, au travers de mes recherches, je suis tombé la dessus.
Je vous le partage, car je trouve l'article vraiment intéressant, et accessible même au allergique des mathématiques.
http://www.lifl.fr/~jdelahay/pls/2013/237.pdf
PS 2: concernant mes bugs de "post" dans cette section, je viens de me rendre compte que lorsque je clique sur répondre, le bandeau de mise en forme (gras, italique,...) n'apparait même pas.
Il doit donc y avoir un bug dans la routine d'affichage lors du clic sur "répondre". Bizarre que je sois le seul à le constater.
Bonne journée à tous.
Bon article et en Français ! On voit qu'avec du simple on peut aller loin...
[Hors sujet ON]
Youpi, j'ai trouvé l'origine de mon problème de gestion des messages.
En fait, j'ai le souci uniquement dans la section challenge, car c'est la seule section qui affiche une fenêtre de "réponse rapideé", au lieu des autres sections.
Et de là, j'ai identifié que la zone de traitement de la réponse (Fenêtre d'écriture, de mise en forme,...) se chargeait mal à cause d'un module installé dans Firefox "Addblock plus".
En désactivant celui-ci, tout se charge correctement, et je peux enfin aller à la ligne dans mes réponses.
Un des filtres de gestions d'ADP, bloque le script suivant : "http://s7.addthis.com/js/300/addthis_widget.js", ce qui génère le mauvais chargement de la zone de texte.
[Hors sujet OFF]
C'est plus long de mettre des exceptions que de traiter tout enfin pour mon code
60s pour 100 000 000 premiers
Question comment on peut faire une boucle while avec U64 au lieu d'un I32 en variable?
Merci d'avance
Merci Michael.C, pertinent comme toujours !
Je ne suis pas sur de comprendre la question ghost67, mais si tu souhaites passer la variable d'incrémentation en U64, il suffit d'utiliser la petite fonction native "En entier quad non signé".
ca marche pas mais le registre a décalage cest bon 🙂
Je pense pas que ça suffise, car la constante "i" qui va générerla valeur va forcément reboucler vis à vis de ses bornes "i32".
Il te faut donc créer ta propre constante d'incrémentation en U64 , au travers d'un registre à décalage, et d'un incrément de +1 à chaque itération.
oui, j'ai fait ainsi 🙂 je pense que c'est le seul bon moyen d'utiliser une variable de boucle en U64!
Maintenant, ça consomme un peu de code avec l'incrémentation puis un peu de mémoire aussi (8 octets plus ceux alloués au registre à décalage), mais on ne devrait pas avoir de soucis à trouver ça au fond de nos ordis
Code envoyé 😉
code envoyé
Cordialement
Bonsoir à tous,
Dans les codes envoyés, certains d'entre vous pourrait fournir le temps de découverte de la persistance 11, en partant de 0 🙂
Pour l'instant, je n'arrive pas à optimiser mon code, pour le découvrir sans prendre plus d'un jour.
Sachant que le calcul d'un nombre donné (ex. 277777788888899) prend moins de 1 ms.
Salut Michael,
j'ai essayé d'aller jusque la persitance 11 par "approche brute", mais bon, j'ai lâché l'affaire.
je faisais par étape, je lancais mon code pendant la journée et je l'arrêtais le soir, il conservait le nombre où il était arrivé! Plusieurs heures, je n'ai plus fait de décompte, et quand j'ai stoppé, découragé, j'étais encore bien loin de 277777788888899
J'avais mis des filtres, mais bon, ça ne m'a pas fait gagner grand chose
je viens d'améliorer un peu mon code de recherche, j'arrive à plus ou moins 700000 tests par seconde, donc, rapide calcul, il me faudrait 110300 heures pour atteindre 277777788888899 j'ai bien fait de ne pas insister
Lol :D, moi j'ai fait un benchmark de mon code.
Actuellement, cela donne :
Persistance -> Durée de calcul
1 -> 2ms
2 -> 2ms
3 -> 3ms
4 -> 3 ms
5 -> 8 ms
6 -> 66 ms
7 -> 600 ms
8 -> 10 sec
9 -> 90 sec
10 -> 193 minutes.
Je viens de lancer la persistance 11, on va voir 😄
Michael, je te sens plein de courage et d'optimisme c'est très bien
j'ai fait pareil que toi et voilà mes résultats:
1 -> 0ms
2 -> 0ms
3 -> 0ms
4 -> 0 ms
5 -> 0 ms
6 -> 2ms
7 -> 37 ms
8 -> 407 ms
9 -> 3927 ms
10 -> 563195 ms (soit 9.38 minutes)
j'ai calculé, il me faudrait près de 12 années de calculs non stop pour atteindre le chiffre ayant la persistance de 11
Bon courage
Oui j'ai fait le calcul aussi ca fait peur 😄
Après, j'ai remarqué que si tu mets toutes les optimisations pour améliorer le calcul de la persistance 11, tu passes à côté des autres. Il faut donc tenir compte de la persistance attendue pour activer ou non certaines optimisations.
Par exemple, pour la persistance 3, le nombre attendu est 39, hors si tu analyses (pour optimiser le calcul à P=11) que les nombres composés de chiffre premier (2,3,5,7), et bien tu passes à côté 😞
Oui, il faut faire gaffe pour choisir les bonnes optimisations de code.
Pour moi, il y en a plusieurs et j'ai choisi:
- ne pas prendre en compte les nombres qui ne finissent pas par 9 au delà de la persistance 6
- laisser tomber les nombres qui contiennent 0
Après, on pourrait aussi laisser tomber les nombres dont les chiffres successifs ne sont pas égaux ou décroissants (67889 -> OK, 67989 ->pas OK).
Le tout est de trouver un compromis entre un code léger à exécuter <> un nombre minimum de test.
Whoua cela semble efficace Nico_EMC ! A priori certain disent que la 12 se situe dans les 400 chiffres, du coup cela fait beaucoup 🙂
Pour le dessin en spirale, des zones sombres répétitives se dégagent en diagonales mais il faut des matrices supérieures à 300 pour commencer à les voir.
Oufti Nico , je me réjouis de voir ton code
code envoyé
Aller j'arrête de réfléchir -> Code envoyé.
Je n'arrive malheureusement pas au perfomance de Nico, mais bon je m'en tire avec 23 secondes pour la persistance 10 et 10 minutes pour la persistance 11
Vivement la publication des codes 🙂
Bonne journée à tous.
Bonsoir à tous,
Code envoyé.
Pour les temps j'obtiens :
1 -> 0 ms
2 -> 0 ms
3 -> 0 ms
4 -> 0 ms
5 -> 0 ms
6 -> 2ms
7 -> 5 ms
8 -> 32 ms
9 -> 39 ms
10 -> 165 ms
11 -> 2982 ms
Mais je ne comprends pas très bien ce qu'il faut faire en option.
Bonne soirée à tous.
Code spirale envoyé aussi.
Code envoyé... sur le fil!
Code envoyé.
Après recherche d'optimisation des temps de calcul et optimisation des nombres a analyser eux-même j'en suis à environ 80ms pour trouver les premiers nombres des 11 persistances 🙂
Félicitation Alepar29, je n'arrive pas à descendre en dessous de 1850ms pour trouver les 11 nombres.
En tout cas je suis curieux de voir comment vous avez généré la spirale...
Merci Rodolph,
mais as tu bien pris en comptes toutes les règles de calcul pour les persistances élevées ? c'est ce qui m'a fait gagner beaucoup de temps.
AllanB54, pour la spirale, je ne prends en compte les règles de calcul.
Dans mon IHM, j'ai un control tab avec 3 onglets, 1 que j'ai appelé test perf (screenshot 2-3 messages ci-dessus), un second dans lequel tu mets un nombre et ça te donne la persistance.
Le 3ème onglet pour la spirale avec les persistances des nombres bornés, le principe de la spirale est de représenter toutes les persistances de tous les nombres donc il ne faut pas se servir des règles de calcul qui permettent de trouver le 1er nombre de persistance 11 le plus vite possible (si j'ai bien interprété le sujet).
Pour la spirale, pour trouver toutes les persistances et les représenter dans le graph, mon programme met environ 30 secondes pour aller de 0 à 2500000. D'où l'importance des règles de calcul pour aller beaucoup plus vite si besoin de trouver des nombres de grande persistance
Merci Alepar29,
j'ai bien compris le calcul, ma curiosité concerne juste la manière de placer les points dans le graphe XY pour représenter une spirale... J'ai bien une idée mais elle me parait tirée par les cheveux! Et j'imagine qu'il doit y avoir bien plus facile pour y arriver. Donc vivement que les codes soient dispo!
Bonne journée à tous
Mon code pour la spirale est un peu lourd je pense. je l'ai fais très rapidement, il y a des fils qui se croisent et pas de coms... désolé.
pour le principe, toutes les persistances sont dans un tableau 1D, je place le 1er élément au milieu d'un tab 2D, puis j'utilise 4 fonctions:
col+1, col-1, lig-1, lig+1 dans boucles for avec le nombre d'itération incrémentée pour chaque élément du tableau 1D de persistance
TabPersistance[i] fait col +1 une fois. TabPersistance[i+1] fait lig-1 une fois. TabPersistance[i+2] fait col -1 2fois. TabPersistance[i+3] fait lig+1 3fois. TabPersistance[i+4] fait col +1 3fois
col +1 : 1 / 3 / 5 / 7 / 9 / ..
lig -1 : 1 / 3 / 5 / 7 / 9 / ..
col -1 : 2 / 4 /6 / 8 / 10 /..
lig +1: 2 / 4 /6 / 8 / 10 /..
et ça crée ma spirale, il y a surement plus simple et plus rapide mais ça marche