[Selection 2010]: Des chiffres ?! Des corrections ?!

TLN : « JJ ton code pour la question 3 ne passe pas tous les tests ? »
→ Nope.

TLN : « structure de donnée un peu capilotractée xD »
→ structure de données* capillotractée*
Ça ne sert à rien d'employer des mots compliqués si c'est pour se planter sur l'orthographe :P

alex3er : « lol le sphinx, si c'est pour embrouiller les debutants que tu as fait écrit ce code , c'est reussi lol »
→ Rectification : ce n'était pas pour embrouiller les débutants, mais pour embrouiller les orgas (remarque, c'est un peu la même chose).

roket, jojomolo → Vous devriez regarder http://www.ideone.com :)

Je poste que l'algo 3 parceque j'ai pas de site et que ça prend de la place, et que c'est le plus interessant ;)

J'ai posté un truc comme le_spinx avec un arbre, sauf que pour moi ça passe tous les tests,
Puis en me repenchant dessus un peu plus tard (après avoir soumis l'autre -_-) j'ai trouvé un peu plus rapid (d'un chouilla), voila les 2 :

le plus rapid des 2:
(je sais pas si ça s'apparente à du hachage ?)
http://pastebin.com/f6109a84

l'arbre :
http://pastebin.com/f54cdd047

En gros, l'idée c'est de stocker chaque sous-séquence rencontrée dans un tableau. Ensuite on trie le tableau, histoire d'avoir des "plages" de cases avec la même sous-séquence pour compter combien de fois cette séquence apparaît.
Le tout est de trouver comment stocker toutes les sous-chaînes présentes : les stocker tel quel ne passe pas en mémoire et demandera trop de temps pour les trier. On associe donc à chaque sous-séquence un nombre (quelqu'un pourraît me dire si c'est ça le hachage d'ailleurs ?) : on considère qu'une lettre représente un chiffre parmi {0, 1, 2, 3} et que l'ensemble forme un nombre écrit en base 4. Le nombre associé à une sous-chaîne est en fait ce nombre écrit en base 10.

JJ j'aime ta maniere de montrer aux orgas que tu trouve ça trop facile.....
Mais as tu réellement poster un code de plaisantin pareille ?

Ou est-ce juste pour faire le clown sur le forum ?

PS : je me fiche de ta réponse vu que seul les orgas détiennent la vérité absolu et ne nous donnerons certainement jamais le fin mot de l'histoire....

wumzi => C'est vraiment nécessaire d'indiquer la licence dans les exercices du QCM ...

Par contre pas mal l'astuce pour le premier exo. Je ne savais pas qu'on pouvait mettre un argument à count, c'est cool :)

Pour le deuxième, y'a beaucoup plus simple : http://pastebin.com/f5a9e9544

Pour le dernier, il existe également une version récursive beaucoup plus courte, mais plus gourmande en mémoire sur les grosses chaines (elle ne passe donc pas les tests, contrairement à la version optimisée du Levenshtein classique comme l'a donnée Alexis B.) : http://pastebin.com/f6c7c4167
Mais elle a même l'air de carrément partir dans la paille avec Python et des chaines de longueur moyenne :s.

Par contre, quand on voit les codes en C, on a envie de pleurer :'( (enfin pour JJ, c'est de rire hein :-P)

Et comme grapsus le dit, rien de tel qu'un hébergement à la maison, sur son routeur.

alex3er => C'est clair, le plus long algo écrit en Python prends 10 lignes, et sans réellement utiliser de « tweak » du langage.
Enfin y'a ceux qui utilisent des structures plus artisanales car elles n'existent pas en C/C++, mais même, on voit des triples boucles imbriquées là où une petite fonction récursive passe sans soucis ...

Pas besoin des orgas. Bien sur qu'il l'a fait. Et tu vas rire, mais avec ça il arrive à se qualifier jusqu'en finale. Et il fait quoi à la finale ? Bah il joue à Tetrinet toute la journée. :D

Le connaissant, ça ne m'étonnerait pas que ce soit ce qu'il ait proposé ...

Ça ne sert à rien d'employer des mots compliqués si c'est pour se planter sur l'orthographe :P

Ça sert à rien d'employer des noms de variables si compliqués si c'est pour se planter sur son algo :P

Le tout est de trouver comment stocker toutes les sous-chaînes présentes : les stocker tel quel ne passe pas en mémoire et demandera trop de temps pour les trier. On associe donc à chaque sous-séquence un nombre (quelqu'un pourrait me dire si c'est ça le hachage d'ailleurs ?) : on considère qu'une lettre représente un chiffre parmi {0, 1, 2, 3} et que l'ensemble forme un nombre écrit en base 4. Le nombre associé à une sous-chaîne est en fait ce nombre écrit en base 10.

C'est une fonction de hachage parfaite (qui ne génère pas de collisions) ... si on utilise une table de 2³⁰ éléments ... (puisque les sous-chaînes sont de longueurs

@ alex3er : Je te rassure le code OCaml que j'ai écrit et qui utilise des tables de hachage est beaucoup plus compact et passe aussi tous les tests ...
Là disons que j'ai implémenté ça ... pour le fun, mais que je n'aurai jamais fait ça lors d'une demi-finale (enfin j'en sais rien, je ne suis encore jamais allé en demi-finale xD). C'est d'ailleurs sans doute pour ça que j'ai récolté que 10 points à la question ;p

@ jojomolo : Erf ... En fait, c'est pas vraiment évident à expliquer sans un papier et un crayon, mais je veux bien réessayer xD
Globalement si on fait un schéma on se rend bien compte que ça marche, là où il faut réfléchir un peu c'est juste sur l'analyse de complexité amortie.
Grosso-modo tu veux stocker n éléments dans un tableau, en ayant des fonctions d'insertion et de recherche (l'élément i appartient-il à mon tableau ?) efficaces. Plutôt que de stocker ça dans un seul grand tableau trié (ce qui rendrait la fonction d'insertion pas terrible : imagine que tu insères toujours au début du tableau, il faudrait à chaque fois tout redécaler), on utilise plusieurs tableaux de tailles différentes.
Mettons que n s'écrive en binaire n.(k-1),...,n.(1),n.(0).
On a un premier tableau A[0] est de taille 1, A[1] de taille 2, A[2] de taille 2²=4, etc.
On décide de ranger dans A[i] exactement 2\^i éléments si et seulement si on a n.(i) = 1. (*)
De plus les éléments au sein du tableau A[i] doivent être rangés dans l'ordre croissant.
On aura bien stocké dans nos k tableaux somme(n.(i)*2\^i, i=0 à k-1) = n éléments.

Après l'opération d'insertion vise principalement à s'assurer qu'on garde la propriété (*), et que les éléments sont toujours triés au sein d'un tableau A[i].
L'opération de recherche se contente de parcourir nos k tableau, en effectuant une recherche dichotomique au sein de ce tableau (d'où la nécessité de garder les éléments triés).

Au niveau des algo' proposés aux questions 3 et 4, globalement je vois les mêmes idées qui reviennent, mais je me demande si quelqu'un a tenté autre chose que l'algo de prog' dyn' pour la distance de levenshtein (question 4), ou en tout cas une autre variante qui ne limite pas juste la plage de recherche à ±100 ?

TLN je comprend pas ton histoire de tableaux ;p c'est possible d'avoir un peu plus de détails, même avec le roman que tu as écrit en début de code j'ai pas saisie :)

@ roket tes algos 3 et 4 passent tous les tests ?
pour l'algo 3 pourquoi tu te fais ch** avec un vecteur, ta map est déjà triée il suffit de la parcourir dans l'ordre avec un iterator pour trouver le max.

@ TLN
Punaise aussi je suis trop embrouillé avec tes histoire de binaire et bits je crois. Donc au début tous tes tableaux sont créés ? et quand tu veux ajouter tu cherches le premier tableau dispo où il reste de la place ? et c'est quoi l'histoire de les refusionner entre eux ? pourquoi les tableaux n'ont pas tous la même taille ? c'est quoi n.(i), désolé si je pose autant de questions mais c'est vraiment interessant comment tu l'as fait en plus j'ai testé chez moi c'est très performant.

Je ne sais pas vraiment quel niveau d'étude tu as pour tenter de te l'expliquer de manière adaptée, mais j'imagine que tu sais que les entiers sont représentés en machine par une suite de bits (des 0 et des 1). Par exemple 23 s'écrit en binaire 10111 car 23 = 16 + 4 + 2 + 1 = 2⁴+2²+2¹+2⁰
Bref c'est à cela que correspondent les n.(i) dans mon post précédent (difficile d'utiliser de bonnes notations avec juste du texte).

Ensuite, quand je veux ajouter un élément, je cherche le premier tableau vide, j'y ajoute mon élément, et j'y déplace tous les éléments des tableaux précédents. Par exemple, j'ai A[0] = {2}, A[1] = {1 ; 4}, A[2] = {Ø ; Ø ; Ø ; Ø} (vide). Il y a donc n = 3 = 011 (en binaire) éléments dans mon tableau. J'ajoute un élément mettons 5. Il se passe quoi : je range 5 dans A[2] (le premier tableau vide), puis je recopie les éléments de A[0] et A[1] dans A[2]. J'aurai donc A[2] = {5 ; Ø ; Ø ; Ø}, puis A[2] = {2 ; 5 ; Ø ; Ø}, puis A[2] = {1 ; 2 ; 4 ; 5} après mes différentes fusions. Je me retrouve donc au final avec A[0] = {Ø}, A[1] = {Ø ; Ø}, et A[2] = {1 ; 2 ; 4 ; 5}.

On remarque au passage que les deux propriétés que j'ai énoncées sont conservées : les éléments de A[2] sont triés, et j'ai au final n = 4 = 100 (en binaire) éléments dans mon tableau. Avec cette fois seul le tableau A[2] rempli (puisque le "troisième" bit de n vaut 1 et les autres 0).

Ce qui fait qu'au final on utilise des tableaux de tailles différentes, c'est essentiellement pour des questions de complexité :
Ca ne me coûte pas plus cher de fusionner les tableaux A[0] à A[i-1] avec A[i], que de fusionner le résultat obtenu avec A[i+1].

Mais si tu veux y voir plus clair, rien ne vaut une bonne nuit de sommeil moi j'dis xD

c'est énorme comme système. Je suis fan ;) c'est impressionant comment tout colle.

Y'a beaucoup de gestion de bit, pour à peu près comprendre les mécanismes (masque, décalage, opérateurs que j'avais jamais vu genre les

const int masque = (1

je comprend pas ;p que font les deux

« JJ j'aime ta maniere de montrer aux orgas que tu trouve ça trop facile..... »
→ Bof, non, c'est surtout pour rigoler :)

« Mais as tu réellement poster un code de plaisantin pareille ? »
→ Oui \^\^ Attends, il y a 2 ans, j'ai posté un code avec des commentaires de partout du genre

} // Rien

void magique() { // Cette fonction, je ne sais pas ce qu'elle fait, c'est mon frère qui l'a codée…

// 4 = 2 + 2

« Ou est-ce juste pour faire le clown sur le forum ? »
→ Bah tant qu'à faire :) Mais j'ai effectivement soumis ça.

« PS : je me fiche de ta réponse vu que seul les orgas détiennent la vérité absolu et ne nous donnerons certainement jamais le fin mot de l'histoire.... »
→ Ah, tu ne me fais pas confiance ? :P

« Pas besoin des orgas. Bien sur qu'il l'a fait. Et tu vas rire, mais avec ça il arrive à se qualifier jusqu'en finale. Et il fait quoi à la finale ? Bah il joue à Tetrinet toute la journée. :D »
→ Sauf qu'il y a plusieurs journées à la finale :D Et puis j'avais quand même commencé à coder vers 23 h :P

« Ça ne sert à rien d'employer des mots compliqués si c'est pour se planter sur l'orthographe :P
Ça sert à rien d'employer des noms de variables si compliqués si c'est pour se planter sur son algo :P »
→ Rien à voir, mais j'aime bien ton analogie :P

« si on utilise une table de 2³⁰ éléments »
→ Ça ressemble plus à 2\^(3\^0) éléments ton truc :P Avec la police Verdana en tout cas.

« Ca ne me coûte pas plus cher de fusionner les tableaux A[0] à A[i-1] avec A[i], que de fusionner le résultat obtenu avec A[i+1]. »
→ Ça ne coûte pas plus cher de bien manger :D

--
Jill-Jênn, qui aime bien quand tout le monde écrit sur le forum :) Je viens de me rappeler que j'avais fait un script pour déterminer un classement des posteurs, il faudrait que je le relance :D

« Je viens de me rappeler que j'avais fait un script pour déterminer un classement des posteurs, il faudrait que je le relance :D »
→ Owiiii je veux !

«    « si on utilise une table de 2³⁰ éléments »
→ Ça ressemble plus à 2\^(3\^0) éléments ton truc :P Avec la police Verdana en tout cas.
»
→ Au début je pensais plus à 2\^{3_{0}} (syntaxe LaTeX).
Fallait écrire 2³º, le U+00BA MASCULINE ORDINAL INDICATOR marche bien ici.

Répondre au sujet

Vous devez vous enregistrer ou vous connecter pour poster des messages.