Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1550 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  [Concours] Recherche de doublons dans une séquence

 


 Mot :   Pseudo :  
 
 Page :   1  2  3
Page Précédente
Auteur Sujet :

[Concours] Recherche de doublons dans une séquence

n°708222
el muchach​o
Comfortably Numb
Posté le 25-04-2004 à 23:50:13  profilanswer
 

J'ai vu que certains aimaient bien les petits problèmes.
 
Alors voilà, je me lance donc en espérant que celui-là ne fera pas un bide complet. :D  
 
Le problème est simple : on a une séquence de 5 millions de chiffres aléatoires dans un tableau.
 
1er problème : (facile) trouver toutes les répétitions de n chiffres successifs dans le tableau. Les écrire dans un fichier txt, ainsi que leurs positions. On fera cette recherche pour toutes les séquences où : 7 <= n <= 15
 
2e problème : (moins facile) trouver la séquence de chiffres la plus longue qui est répétée au moins une fois.
 
Les meilleures solutions sont les plus rapides.
 
 
Ex. de sortie du premier programme :
 

Citation :


Séquences à 7 chiffres :
 
1542871 trouvé 8 fois [8520, 12555, 47520, 255356, 1352255, 1753256, 2751356, 4256752]  
0472123 trouvé 6 fois [154321, 788543, 853156, 1108256, 1332560, 1752212]  
etc
 
Séquences à 8 chiffres :
 
32845769 trouvé 11 fois [...]
 
etc
 
 
Total :  
1749 séquences à 7 chiffres
832 séquences à 8 chiffres
...
3 séquences à 15 chiffres
 
Durée : 74.245 s


 
 
NB : pour ceux que le challenge intéresse, il faut avoir tous la même séquence aléatoire. Je propose le générateur congruentiel suivant (Knuth) :
 
Graine : r = 17
itérations : r = (1664525 * r + 1013904223) modulo 2^32
 
Les 5 millions de chiffres de la séquences seront générés 5 par 5 en prenant les 5 premiers chiffres de r à chaque fois, donc seulement si r>9999.  
L'opération étant itérée un million de fois (partie non chronométrée).
 
Ouala, bonne cogitation !


Message édité par el muchacho le 26-04-2004 à 23:26:56
mood
Publicité
Posté le 25-04-2004 à 23:50:13  profilanswer
 

n°708225
christophe​_d13
L'efficacité à tout prix.
Posté le 25-04-2004 à 23:57:10  profilanswer
 

Donc, aucune restriction...
 
Le résultat du concours t'interresse-t-il ? (le code)


Message édité par christophe_d13 le 25-04-2004 à 23:58:07
n°708226
el muchach​o
Comfortably Numb
Posté le 25-04-2004 à 23:59:02  profilanswer
 

christophe_d13 a écrit :

Donc, aucune restriction...


 
Euh sur quoi ? Sur la mémoire ?
Disons que des solutions "raisonnables" devraient être envisagées, mais les algos intéressants sont tjrs acceptés.
 
Disons 100 Mo de RAM maxi.
 
edit : plutôt 128 Mo...


Message édité par el muchacho le 29-04-2004 à 22:58:42
n°708227
el muchach​o
Comfortably Numb
Posté le 26-04-2004 à 00:00:54  profilanswer
 

christophe_d13 a écrit :

Donc, aucune restriction...
 
Le résultat du concours t'interresse-t-il ? (le code)


 
Bien sûr, si ça vous intéresse d'essayer. Un petit concours d'optimisation est tjrs amusant (m^me si c'est du C, mais là, je risque de m'en prendre plein la tête... :heink: ).

n°708228
christophe​_d13
L'efficacité à tout prix.
Posté le 26-04-2004 à 00:01:27  profilanswer
 

Y a pas que la mémoire... Le code également :
- code-morphing
- dynamic-code
- FPU ? MMX ? SSE ? SSE2 ? 3DNow ?
...


Message édité par christophe_d13 le 26-04-2004 à 00:01:59
n°708230
el muchach​o
Comfortably Numb
Posté le 26-04-2004 à 00:02:43  profilanswer
 

christophe_d13 a écrit :

Y a pas que la mémoire... Le code également :
- code-morphing
- dynamic-code
- FPU ? MMX ? SSE ? SSE2 ? 3DNow ?
...


 
Non, pas d'asm, juste du C/C++ ou autre langage portable.  
 
Edit : Sauf si ça intéresse certains, mais je crains que sur un forum C++...


Message édité par el muchacho le 26-04-2004 à 00:03:50
n°708232
christophe​_d13
L'efficacité à tout prix.
Posté le 26-04-2004 à 00:04:23  profilanswer
 

Faut bien définir les rêgles...
- C/C++ pur sans les fonctions externes (sauf pour l'affichage) ?

n°708234
el muchach​o
Comfortably Numb
Posté le 26-04-2004 à 00:06:33  profilanswer
 

christophe_d13 a écrit :

Faut bien définir les rêgles...
- C/C++ pur sans les fonctions externes (sauf pour l'affichage) ?


 
Ok : C/C++ pur, on a le droit aux librairies standard, c'est tout.

n°709084
el muchach​o
Comfortably Numb
Posté le 26-04-2004 à 20:30:01  profilanswer
 

Ben ce problème n'a pas l'air de soulever l'enthousiasme... :ange:  

n°711451
el muchach​o
Comfortably Numb
Posté le 29-04-2004 à 01:15:23  profilanswer
 

Et zou, histoire que ce problème ne tombe pas tout de suite aux oubliettes. :bounce:  
 
Allez, à première vue, ça ressemble à du O(N^2), mais il y a clairement une solution simple en O(N*Log(N)), et même une en O(N) pour des petites séquences.

mood
Publicité
Posté le 29-04-2004 à 01:15:23  profilanswer
 

n°711452
Taz
bisounours-codeur
Posté le 29-04-2004 à 01:19:24  profilanswer
 

O(N) ? si tu tries que tu parcoures à la recherche de doublon, ça fait du N*Log(N) + N

n°711453
Jubijub
Parce que je le VD bien
Posté le 29-04-2004 à 01:25:16  profilanswer
 

Squattage newbie : un cours simple sur les calculs de complexité vous auriez ?


---------------
Jubi Photos : Flickr - 500px
n°711464
Taz
bisounours-codeur
Posté le 29-04-2004 à 02:45:19  profilanswer
 

Citation :

Les 5 millions de chiffres de la séquences seront générés 5 par 5 en prenant les 5 premiers chiffres de r à chaque fois, donc seulement si r>9999.  
L'opération étant itérée un million de fois (partie non chronométrée).


 
 
j'avais pas vu ça ... non mais ces quoi ces conneires ? tu te rends compte que c'est peut être la partie qui prends le plus de temps ? rien que cette fonction elle fait chier :o
 
à ce petit jeu là, t'as plus vite fait de distribuer le fichier avec la séquence :o

n°711466
Taz
bisounours-codeur
Posté le 29-04-2004 à 02:56:01  profilanswer
 

ouais donne la liste, parce que là je commence à péter un plomb j'i bite rien à ta fonction de génération de merde, apprends à t'exprimer

n°711469
jagstang
Pa Capona ಠ_ಠ
Posté le 29-04-2004 à 03:00:50  profilanswer
 

[:drapo] je relirais demain --> [:dodo]

n°711471
Taz
bisounours-codeur
Posté le 29-04-2004 à 03:12:08  profilanswer
 

moi je laisse tomber, je me suis assez pris la tête sur des bêtises tout ça parce que l'énoncé est pas clair
 
« seront générés 5 par 5 »
alors la franchement je vois pas. à jamais

n°711473
xterminhat​e
Si vis pacem, para bellum.
Posté le 29-04-2004 à 04:22:16  profilanswer
 

Une petite question concernant la génération : tu peux préciser ou se trouve le LSB et le MSB pour 'r' et pour la 'séquence'. Histoire que tout le monde construise la séquence de la même facon.
 
Moi je trouve cette sequence :
 
10422197381276214297921856697316293946912835318827........


Message édité par xterminhate le 29-04-2004 à 04:31:08

---------------
Cordialement, Xterm-in'Hate...
n°711475
xterminhat​e
Si vis pacem, para bellum.
Posté le 29-04-2004 à 04:40:16  profilanswer
 

el muchacho a écrit :


L'opération étant itérée un million de fois (partie non chronométrée).


 
Si je repete l'opération 1.000.000 de fois, j'obtiens les 2/3 des chiffres demandés. En fait certains résultats de r sont fortement réduits par le modulo (moins de 5 chiffres significatifs).
 
Compte-t-on alors les zéro en position MSB ? Je pense que non mais c'est pas super clair...


---------------
Cordialement, Xterm-in'Hate...
n°711476
xterminhat​e
Si vis pacem, para bellum.
Posté le 29-04-2004 à 05:14:43  profilanswer
 

1542871 trouve 0 fois [  ].
0472123 trouve 3 fois [ 977257, 2767231, 3366731 ].
32845769 trouve 0 fois [  ].


 
Ma séquence est pas bonne ! :pt1cable: Elle est ennuyante ta formule à coder en C++ !


Message édité par xterminhate le 29-04-2004 à 20:38:03

---------------
Cordialement, Xterm-in'Hate...
n°712324
el muchach​o
Comfortably Numb
Posté le 29-04-2004 à 22:11:20  profilanswer
 

ATTENTION !!! SOLUTION !!!
Ne lisez pas ce qu'il y a en-dessous si vous voulez chercher encore !
 

Taz a écrit :

O(N) ? si tu tries que tu parcoures à la recherche de doublon, ça fait du N*Log(N) + N


 
Oui, c'est ça ma solution en O(N log (N)) (le +O(N) n'a pas besoin d'être précisé, je crois). Mais en commençant à la coder, je me pose une question : le tri a besoin d'une fonction de comparaison, or je me demande si la comparaison des séquences ne va pas tout faire tomber par terre. J'ai bien l'impression que si.
Par ailleurs, ça bouffe quand même pas mal de mémoire : au moins n*N pour des séquences de taille n, plus un buffer en Log(N) supplémentaire pour le quicksort.
Mon autre solution (en fait celle d'un pote) est impraticable pour des séquences de plus de 8 ou 9 chiffres car elle prend 10^n en mémoire. Par contre, je doute qu'on puisse faire plus rapide : il suffit de faire un tableau de tous les nombres possibles avec n chiffres (donc 10^n chiffes), et d'y stocker les listes des index à chaque apparition. Super simple, super rapide mais super dispendieux en RAM.


Message édité par el muchacho le 30-04-2004 à 00:05:33
n°712332
el muchach​o
Comfortably Numb
Posté le 29-04-2004 à 22:22:20  profilanswer
 

Taz a écrit :

Citation :

Les 5 millions de chiffres de la séquences seront générés 5 par 5 en prenant les 5 premiers chiffres de r à chaque fois, donc seulement si r>9999.  
L'opération étant itérée un million de fois (partie non chronométrée).


 
 
j'avais pas vu ça ... non mais ces quoi ces conneires ? tu te rends compte que c'est peut être la partie qui prends le plus de temps ? rien que cette fonction elle fait chier :o
 
à ce petit jeu là, t'as plus vite fait de distribuer le fichier avec la séquence :o


 
Je sais. Le problème est de remplir le tableau avec des chiffres aléatoires.  
Et puis bon, si c'est ça qui t'empêche de dormir :
 

Code :
  1. #include <stdio.h>
  2. #include <vector>
  3. using namespace std;
  4. const int              N = 5000000;
  5. const unsigned long SEED = 17L;
  6. inline void alea(unsigned long &rand){
  7.   static unsigned long r;            // edit : bug : il faut initialiser r = SEED
  8.   rand = r = 1664525UL * r + 1013904223UL;
  9. }
  10. int remplit_v(vector<char> &v, const int n)
  11. {
  12.   unsigned long r = SEED;
  13.   char buf[5] = "";
  14.   vector<char> tmp;
  15.  
  16.   v.reserve(n);
  17.   for (int i = 0; i < n; i+= 5)
  18.     {
  19.       do alea(r); while (r < 10000L);
  20.       sprintf(buf, "%u:5", r);
  21.       tmp.assign(buf, &buf[sizeof(buf)]);  // faute de mieux
  22.       copy(tmp.begin(), tmp.end(), back_inserter(v));
  23.     }
  24.   return v.size();
  25. }


 
(ps : je sais, l'utilisation du sprintf n'est pas heureuse, mais c'est encore la fonction dont je me souviens le mieux. Enfin bon, on s'en fout, là n'est pas le plus important)


Message édité par el muchacho le 01-05-2004 à 07:51:23
n°712341
el muchach​o
Comfortably Numb
Posté le 29-04-2004 à 22:39:59  profilanswer
 

xterminhate a écrit :

Si je repete l'opération 1.000.000 de fois, j'obtiens les 2/3 des chiffres demandés. En fait certains résultats de r sont fortement réduits par le modulo (moins de 5 chiffres significatifs).
 
Compte-t-on alors les zéro en position MSB ? Je pense que non mais c'est pas super clair...


 
C'est pour cela que j'ai précisé "pour r > 9999" dans l'énoncé, donc pour les nombres à 5 chiffres minimum...
 
Mais je suis d'accord, cette partie de l'énoncé est la moins intéressante et la plus rebutante. Le plus simple est que tout le monde parte sur le code que je donne (j'espère qu'il n'y a pas de bug).
 
Pour info, il me donne (N=5000000): (!! FAUX !!)
40 premiers : 1013911964351982868416495267061476227489
40 derniers : 3125048398216972947012249492535033240745


Message édité par el muchacho le 01-05-2004 à 07:49:59
n°712363
el muchach​o
Comfortably Numb
Posté le 29-04-2004 à 23:02:36  profilanswer
 

xterminhate a écrit :

1542871 trouve 0 fois [  ].
0472123 trouve 3 fois [ 977257, 2767231, 3366731 ].
32845769 trouve 0 fois [  ].


 
Ma séquence est pas bonne ! :pt1cable: Elle est ennuyante ta formule à coder en C++ !


 
Ben oui, c'est bien pour ça que je la proposais.  :sol:  
 
C'est un bon exercice d'utilisation des conteneurs STL (c'est aussi un bon exercice pour les codeurs en C). Si je suis pas trop paresseux, je m'en ferai peut-être une version des algos en Ocaml aussi (à moins que ça intéresse Joelf ou nraynaud). Une petite comparaison des perfs pourrait être intéressante (je n'ai aucune idée de ce que ça peut donner).
 
Ce problème n'est pas complètement gratuit, il a je pense des connexions (lointaines) avec le problème de séquençage de l'ADN, ou avec l'indexation de grands textes.

n°712434
Taz
bisounours-codeur
Posté le 30-04-2004 à 01:07:17  profilanswer
 

sprintf(buf, "%u:5", r);  
 
skoi ça ?

n°712436
Taz
bisounours-codeur
Posté le 30-04-2004 à 01:10:26  profilanswer
 

char buf[5] = "\0";  
 
en plus t'es un malin toi
 
 
pas standard
#include <stdio.h>
 
 
 
  const int              N = 5000000;
  const unsigned long SEED = 17L;
   
  void alea(unsigned long &rand){
      static unsigned long r;
      rand = r = 1664525L * r + 1013904223L;
  }  
 
à mettre dans namespace, à inliner
 
 
 
vector<char> &v
 
la je comprends pas le prototype, on parle pas d'entier ?

n°712473
xterminhat​e
Si vis pacem, para bellum.
Posté le 30-04-2004 à 07:11:19  profilanswer
 

:wahoo: Bon c'est n'importe quoi la :)
 
J'ai un code similaire et mon premier nombre est 1042201148. Alors je vois pas comment tu extrais 10139 de ce premier nombre. J'ai vérifié à la main mes premiers nombres ....
 
Pour info, voila mon code de génération :
 

Code :
  1. std::string generation()
  2. {
  3. std::string alea;
  4. std::string::size_type taille_sequence( alea.size() );
  5. const unsigned long multiplier( 1664525UL );
  6. const unsigned long addend( 1013904223UL );
  7. unsigned long valeur( 17UL );
  8. while( taille_sequence < 1000000 )
  9. {                       
  10. if( ( valeur =  ( multiplier * valeur + addend ) ) > 9999UL )
  11. {
  12. std::ostringstream str;
  13. str << valeur;
  14. alea += str.str().substr(0,5);
  15. taille_sequence++;
  16. }
  17. }
  18. return alea;
  19. }


 
Ce qui m'etonne, c'est qu'en C++ la valeur de ton masque ne passe pas. Donc, tu n'appliques pas vraiment la bonne formule (ce qui est mon cas aussi bien sur) donnée dans l'ennoncé ! Je me trompe ?
 
En fait, on calcule ca :
 

newseed = ( seed * multiplier ) % 2^32 + ( adder ) % 2^32


 
En C, on aurait accès au __int64 mais pas en C++, d'ou ma remarque precedente. [:airforceone]


Message édité par xterminhate le 30-04-2004 à 23:42:50

---------------
Cordialement, Xterm-in'Hate...
n°712475
skelter
Posté le 30-04-2004 à 07:22:36  profilanswer
 

tu trouve pas ca un peu lourd de specifier a chaque fois std::, tu fais jamais de using... ? surtout que la tu utilise un seul namespace

n°712478
xterminhat​e
Si vis pacem, para bellum.
Posté le 30-04-2004 à 07:29:25  profilanswer
 

Oui, je sais... ca rend le code un peu moins lisible, désolé.


---------------
Cordialement, Xterm-in'Hate...
n°712480
el muchach​o
Comfortably Numb
Posté le 30-04-2004 à 07:57:19  profilanswer
 

Taz a écrit :

char buf[5] = "\0";  
 
en plus t'es un malin toi
 
 
pas standard
#include <stdio.h>
 
 
 
  const int              N = 5000000;
  const unsigned long SEED = 17L;
   
  void alea(unsigned long &rand){
      static unsigned long r;
      rand = r = 1664525L * r + 1013904223L;
  }  
 
à mettre dans namespace, à inliner
 
 
 
vector<char> &v
 
la je comprends pas le prototype, on parle pas d'entier ?


 
Ah, je sens qu'on est sur les rails, là. :)  
Dans le reste de mon code, j'inline, mais tu as raison.
Pour le printf, si tu peux me rappeler la version strstream, je changerai volontiers ma petite fonction de génération pour la rendre plus C++.
 
edit : pas la peine, xterminhate me la donne...
 
En fait, mon problème s'applique plutôt à un tableau de caractères (mais il peut se généraliser à toute collection d'objets finie ordonnée). Le fait que je dise que ces caractères soient des chiffres, c'est que je l'ai imaginé comme ça. Donc pour ce problème, ce sont des chiffres. Tu peux utiliser un vector<int> si tu préfères, tant que tu obtiens les mêmes valeurs dans ton tableau.

n°712481
el muchach​o
Comfortably Numb
Posté le 30-04-2004 à 08:00:07  profilanswer
 

xterminhate a écrit :

:wahoo: Bon c'est n'importe quoi la :)
 
J'ai un code similaire et mon premier nombre est 1042201148. Alors je vois pas comment tu extrais 10139 de ce premier nombre. J'ai vérifié à la main mes premiers nombres ....
 
Pour info, voila mon code de génération :
 

Code :
  1. std::string generation()
  2. {
  3. std::string alea;
  4. std::string::size_type taille_sequence( alea.size() );
  5. const unsigned long multiplier( 1664525UL );
  6. const unsigned long addend( 1013904223UL );
  7. // const unsigned long mask( 4294967295UL );
  8. unsigned long valeur( 17UL );
  9. while( taille_sequence < 1000000 )
  10. {                       
  11. if( ( valeur =  ( multiplier * valeur + addend ) ) > 9999UL )
  12. {
  13. std::ostringstream str;
  14. str << valeur;
  15. alea += str.str().substr(0,5);
  16. taille_sequence++;
  17. }
  18. }
  19. return alea;
  20. }


 
Ce qui m'etonne, c'est qu'en C++ la valeur de ton masque ne passe pas. Donc, tu n'appliques pas vraiment la bonne formule (ce qui est mon cas aussi bien sur) donnée dans l'ennoncé ! Je me trompe ?
 
En fait, on calcule ca :
 

newseed = ( seed * multiplier ) % 2^32 + ( adder ) % 2^32


 
En C, on aurait accès au __int64 mais pas en C++, d'ou ma remarque precedente. [:airforceone]


 
Effectivement, tu as corrigé toi-même. J'ai vu le pb quand j'ai compilé. Le plus simple (ce que j'ai fait dans ma fonction), c'est de virer carrément la partie modulo.

n°712484
Taz
bisounours-codeur
Posté le 30-04-2004 à 08:03:56  profilanswer
 

cai juste qu'il me semble pas que cette syntax de format de printf soit standard.
 
char buf[5] = "\0"; t'as réalisé ce que tu as écris là ?

n°712489
el muchach​o
Comfortably Numb
Posté le 30-04-2004 à 08:11:53  profilanswer
 

Taz a écrit :

cai juste qu'il me semble pas que cette syntax de format de printf soit standard.
 
char buf[5] = "\0"; t'as réalisé ce que tu as écris là ?


 
Quel est le pb ?
(bon cassos boulot)


Message édité par el muchacho le 30-04-2004 à 08:14:22
n°712501
jagstang
Pa Capona ಠ_ಠ
Posté le 30-04-2004 à 08:30:30  profilanswer
 

el muchacho a écrit :

Quel est le pb ?
(bon cassos boulot)


 
char buf[5] ;
buf[4] = '\0' ;
 
?

n°712509
skelter
Posté le 30-04-2004 à 08:41:55  profilanswer
 

Citation :

char buf[5] ;  
buf[4] = '\0' ;


 
ca sert a koi ?  :D  
 

n°712528
jagstang
Pa Capona ಠ_ಠ
Posté le 30-04-2004 à 09:12:05  profilanswer
 

skelter a écrit :

Citation :

char buf[5] ;  
buf[4] = '\0' ;


 
ca sert a koi ?  :D


à rien ! j'espère de comprendre ce qu'il a voulu faire..

n°712576
Taz
bisounours-codeur
Posté le 30-04-2004 à 09:55:02  profilanswer
 

"" fais exactement ce qu'il faut.

n°713200
xterminhat​e
Si vis pacem, para bellum.
Posté le 30-04-2004 à 20:53:24  profilanswer
 

Bon, revennons à nos moutons !... le concours :p
 
El much -> tu as vérifié ton code parce que pour le moment, on a vraiment pas la meme sequence de départ !


---------------
Cordialement, Xterm-in'Hate...
n°713206
Taz
bisounours-codeur
Posté le 30-04-2004 à 21:00:09  profilanswer
 

el muchacho : distribue un fichier avec la séquence, chaque élément séparé par un espace, le tout compréssé (et pas en zip/rar hein)

n°713239
el muchach​o
Comfortably Numb
Posté le 30-04-2004 à 22:20:20  profilanswer
 

JagStang a écrit :

char buf[5] ;
buf[4] = '\0' ;
 
?


 
Ouais, la grosse honte... :D  
J'ai vu la bourde quand j'y ai pensé dans le bus.  
En fait, je pensais plutôt à une initialisation du genre :
 
char buf[5] = "";
 
De toute façon, ça n'a pas d'incidence ici.


Message édité par el muchacho le 30-04-2004 à 22:21:18
n°713256
el muchach​o
Comfortably Numb
Posté le 30-04-2004 à 22:40:12  profilanswer
 

xterminhate a écrit :

Bon, revennons à nos moutons !... le concours :p
 
El much -> tu as vérifié ton code parce que pour le moment, on a vraiment pas la meme sequence de départ !


 
Bon je revois mon code...


Message édité par el muchacho le 30-04-2004 à 22:49:41
mood
Publicité
Posté le   profilanswer
 

 Page :   1  2  3
Page Précédente

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  [Concours] Recherche de doublons dans une séquence

 

Sujets relatifs
Recherche de chaineRecherche d'imprimantes réseau en PHP
Recherche cours et didacticiels: JSP/Servlet/JavaBeans - Struts - MVC2[Java WebStart]Recherche d'un tutorial
[C++] recherche tutorial COMPLET et SERIEUX sur DLL win32Comment passer d'une séquence d'images BMP à une video ?
Recherche APIfonction de recherche de fichier en C [LINUX]
éviter les doublons[Access97] Recherche avec l'option "tous" (zone de liste modifiable)
Plus de sujets relatifs à : [Concours] Recherche de doublons dans une séquence


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR