Page 1 sur 1

Anagrames en utilisant un dico de mots [resolu]

Publié : ven. 29/févr./2008 14:59
par Ar-S
Ma solution en bas de page

-----------

Voilà un truc sur lequel je planche dans le cadre de challenge javascript, programmation, logique, sql et compagnie. (hackbbs.org)

L'épreuve sur laquelle j'en chie consiste à récupérer des "mots mélangés" d'une page web et de trouver leur correspondance dans un dictionnaire de mots (est considéré comme mot une suite caractères alphanumérique).
Chaque mot dans ce dico est sur une ligne, c'est un simple .txt, pas de colonnes.

ex : Global dicofile$=Path$+"wordlist.txt"
cacao
pistache
123456
broutille
pure
basic


le dico contient plus de 1200 mots

Maintenant j'ai une série de 10 mots générés par la page web.
je les récupère et j'arrive à traiter la source pour qu'elle l'affiche que les 10 mots de la même façon, 1 par ligne

ex : source$
caoca
tachpie
654132
epur
bsica


Vous l'avez remarqué, les mots proposés font partie du dictionnaire, mais sont dans le désordre !

Comme il y a 1200 mots, c'est pas évident de retrouver les bons mots sans y passer 3 plombes.

Voilà le défi.
Sachant que les 10 mots proposés changent toutes les 30 secondes, est-ce qu'un prog en PB est capable de retrouver les dix mots correspondant dans le dico en moins de 30 secondes ?

Voilà mon début de code qui permet déjà de lire le dico (un simple readfile) et de récupérer les mots de la page php.

Code : Tout sélectionner

; Remettre les mots dans l'ordre
; 

Global url$="http://hackbbs.org/miss/15/gene.php"
Global Path$=GetCurrentDirectory()
Global dicofile$=Path$+"wordlist.txt"

Procedure.s Affichentre(string.s, LString.s, RString.s)
	Protected Affichentre.s, lindex.l, RIndex.l
	lindex = FindString(string, LString, 0)
	RIndex = FindString(string, RString, lindex+Len(LString))
	If lindex And RIndex
		lindex  + Len(LString)
		Affichentre = Mid(string, lindex, RIndex-lindex)
	EndIf
	ProcedureReturn Affichentre
EndProcedure

ProcedureDLL.s Url2Text2(Url.s, OpenType.b,ProxyAndPort.s)
	;/ Author : Pille
	isLoop.b=1
	INET_RELOAD.l = $80000000
	hInet.l=0
	hURL.l=0
	Bytes.l=0
	Buffer.s= Space (2048 )
	RES.s= ""
	hInet = InternetOpen_ ( "" , OpenType, ProxyAndPort, "" , 0)
	hURL = InternetOpenUrl_ (hInet, Url, #Null , 0, INET_RELOAD, 0)
	Repeat
		InternetReadFile_ (hURL,@Buffer, Len (Buffer), @Bytes)
		If Bytes = 0
			isLoop=0
		Else
			RES = RES + Left (Buffer, Bytes)
		EndIf
	Until isLoop=0
	InternetCloseHandle_ (hURL)
	InternetCloseHandle_ (hInet)
	ProcedureReturn RES
EndProcedure

ProcedureDLL.s Url2Text(Url.s)
	ProcedureReturn Url2Text2(Url,1, "" )
EndProcedure 

; On y va

Source$=Url2Text(url$) ; Je récupe la source entière
Source$=Affichentre(Source$,"<td><li>","</li></td> </tr>                 </table>") ; j'affiche la liste de mot contenant encore des caractères html
Source$=ReplaceString(Source$,"</li></td> </tr><td><li>","*") ; je remplace les caracteres html par un *
Source$=Source$+"*"
MessageRequester("test","Mots de la page web"+Chr(10)+Source$) ;-TEST  J'affiche les 10 mots pour être sûr que ça fonctionne

pos=1
	Position = FindString(Source$, "*", pos)
	URLmot1$=Left(Source$,Position)
	Source$=RemoveString(Source$,URLmot1$)
	Position = FindString(Source$, "*", pos)
	URLmot2$=Left(Source$,Position)
	Source$=RemoveString(Source$,URLmot2$)
	Position = FindString(Source$, "*", pos)
	URLmot3$=Left(Source$,Position)
	Source$=RemoveString(Source$,URLmot3$)
	Position = FindString(Source$, "*", pos)
	URLmot4$=Left(Source$,Position)
	Source$=RemoveString(Source$,URLmot4$)
	Position = FindString(Source$, "*", pos)
	URLmot5$=Left(Source$,Position)
	Source$=RemoveString(Source$,URLmot5$)
	Position = FindString(Source$, "*", pos)
	URLmot6$=Left(Source$,Position)
	Source$=RemoveString(Source$,URLmot6$)
	Position = FindString(Source$, "*", pos)
	URLmot7$=Left(Source$,Position)
	Source$=RemoveString(Source$,URLmot7$)
	Position = FindString(Source$, "*", pos)
	URLmot8$=Left(Source$,Position)
	Source$=RemoveString(Source$,URLmot8$)
	Position = FindString(Source$, "*", pos)
	URLmot9$=Left(Source$,Position)
	Source$=RemoveString(Source$,URLmot9$)
	Position = FindString(Source$, "*", pos)
	URLmot10$=Left(Source$,Position)
	Source$=RemoveString(Source$,URLmot10$)

	MessageRequester("test2","Les 10 mots reconnus par PB"+Chr(10)+URLmot1$+URLmot2$+URLmot3$+URLmot4$+URLmot5$+URLmot6$+URLmot7$+URLmot8$+URLmot9$+URLmot10$) 
; J'affiche les 10 mots pour être sûr que ça fonctionne

End

;--test affichage du dico
; If ReadFile(0, dicofile$)  
    ; While Eof(0) = 0  
		; Debug ReadString(0)
	; Wend
    ; CloseFile(0)
; Else
    ; MessageRequester("Information","Impossible d'ouvrir le fichier!")
; EndIf

J'ai maintenant besoin de votre aide pour la suite.
Pouvez vous me montrer comment PB peut lire chaque ligne (mot) du dico et tester l'ordre des caractères afin de les comparer à URLmot1$, URLmot2$, URLmot3$... URLmot10$.

; notez que
len_mot1=len(URLmot1$)
URLmot1$=left(URLmot1$,len_mot1-1)


etc... ceci afin de ne pas prendre en compte l'astérix pour la comparaison

Merci pour votre aide.

Le dico est téléchargeable ici : http://arsworld.free.fr/pb/wordlist.txt

Publié : ven. 29/févr./2008 15:51
par Backup
..........

Publié : ven. 29/févr./2008 15:53
par Anonyme

Code : Tout sélectionner

Procedure.b CompareWord(A$,B$)

NewList A.s()
NewList B.s()

If Len(A$)<>Len(B$) : ProcedureReturn #False : EndIf 

; On rempli les 2 liste chainées...
For i = 1 To Len(A$)
  AddElement(A()) : A() = Mid(A$,i,1)
  AddElement(B()) : B() = Mid(B$,i,1)
Next 

; On compare chaque lettre de A() a B() , si A==B alors B=$
ForEach A()
  ForEach B()
   If A() = B()
        B() ="$"
   EndIf 
  Next 
Next 

; Si  ...B()=$ alors on a trouvé le bon mots 
ForEach B()
If B()<>"$"
ProcedureReturn #False
EndIf 
Next 
ProcedureReturn #True
EndProcedure



A$ = "pistache"
B$ = "tachpies"
Debug CompareWord(A$,B$)  ; <--Renvois 1 , C'est le même mot

A$ = "purebasic"
B$ = "darkbasic"
Debug CompareWord(A$,B$)  ; <--Renvois 0 , un torchon est dans le lot :D
A toi maintenant de bien utilisé cette proc :D

Publié : ven. 29/févr./2008 16:10
par Ar-S
anagramme !

voilà le mot que je cherchais depuis deux heures :)

Merci les gars je vais essayer de voir si je peux adapter l'un de vos codes à ma source. :P

Publié : ven. 29/févr./2008 17:49
par Anonyme
J'ai télécharger ton dico , puis pris une liste de 10 mots à trouvé.
j'ai pas implémenté la récup de page via le net, j'ai codé en "dur" ,
ton problème est résolu en 26ms avec 80 lignes de codes :D

Code : Tout sélectionner

Procedure.b CompareWord(A$,B$)

NewList A.s()
NewList B.s()

If Len(A$)<>Len(B$) : ProcedureReturn #False : EndIf 

; On rempli les 2 liste chainées...
For i = 1 To Len(A$)
  AddElement(A()) : A() = Mid(A$,i,1)
  AddElement(B()) : B() = Mid(B$,i,1)
Next 

; On compare chaque lettre de A() a B() , si A==B alors B=$
ForEach A()
  ForEach B()
   If A() = B()
        B() ="$"
   EndIf 
  Next 
Next 

; Si  ...B()=$ alors on a trouvé le bon mots 
ForEach B()
If B()<>"$"
ProcedureReturn #False
EndIf 
Next 
ProcedureReturn #True
EndProcedure

Global NewList Dico.s()
Global Dim Compare.s(9)

; A remplaçer par une proc pour lire du html
If ReadFile(0,"wordlist.txt")
PrintN("Ouverture du dico...")
While Eof(0)=0
  AddElement(Dico())
  Dico() = ReadString(0)
Wend 
EndIf 
PrintN("Nombre d'element dans le dico : "+Str(CountList(Dico())))
; Le dico est en place , Lecture des éléments 
; Idem que plus haut

Compare(0) = "ichcoga"
Compare(1) = "hoeoit"
Compare(2) = "sbaluot"
Compare(3) = "eblesat"
Compare(4) = "lopola"
Compare(5) = "nitnti"
Compare(6) = "13425a"
Compare(7) = "bosroet"
Compare(8) = "htaram"
Compare(9) = "uibtufea"

OpenConsole()
CurrentWord = 0
PrintN("")
StartTime.l = ElapsedMilliseconds()
ForEach Dico()
  If Len(Dico()) = Len(Compare(CurrentWord))
   Result = CompareWord(Dico(),Compare(CurrentWord))
   If Result = 1
    PrintN("MOT TROUVER = "+Compare(CurrentWord)+"="+Dico())
    CurrentWord + 1 
    ResetList(Dico())
   EndIf 
  EndIf 
  
  If CurrentWord>9
   EndTime.l = ElapsedMilliseconds()
   Time.l = EndTime - StartTime
   PrintN("Tout les mots ont ete trouve en "+Str(Time)+" ms.  :D ")
   Break 1
  EndIf 
Next 

Input()

Publié : ven. 29/févr./2008 22:25
par Anonyme
Voila une màj du code plus haut :

Code : Tout sélectionner

OpenConsole()


Declare.b CompareWord(A$,B$)
Declare.s Url2Text2(Url.s, OpenType.b,ProxyAndPort.s)






Global NewList Dico.s()
Global Dim Compare.s(9)



;-On télécharge le dico...
DICO_BRUT$ = Url2Text2("http://arsworld.free.fr/pb/wordlist.txt",1,"")
#EOL = Chr(10)
For i = 1 To CountString(DICO_BRUT$,#EOL )
  AddElement(Dico())
  Dico() =  StringField(DICO_BRUT$,i,#EOL)
Next


;-On télécharge et on parse la source
FINDWORDS$ = Url2Text2("http://hackbbs.org/miss/15/gene.php",1,"")
;Extraction entre les balise <table> </table>
PosA=FindString(FINDWORDS$,"<table>",0)
PosB=FindString(FINDWORDS$,"</table>",0)
FINDWORDS$ = Mid(FINDWORDS$,PosA,PosB-PosA);-Len("</table>"))
;Extraction des 10 mots entre les balises <li></li> <tr></tr> etc...
FINDWORDS$ = RemoveString(FINDWORDS$,"<tr>")
FINDWORDS$ = RemoveString(FINDWORDS$,"<td>")
FINDWORDS$ = RemoveString(FINDWORDS$,"</tr>")
FINDWORDS$ = RemoveString(FINDWORDS$,"</td>")
First = FindString(FINDWORDS$,"<li>",0)
FINDWORDS$ = Right(FINDWORDS$,Len(FINDWORDS$)-First+1)
FINDWORDS$ = RemoveString(FINDWORDS$,"<li>")
FINDWORDS$ = ReplaceString(FINDWORDS$,"</li>","|")

For i = 0 To 9
  Compare(i) = Trim(StringField(FINDWORDS$,i+1,"|"))
  Debug Compare(i)
Next




PrintN("Nombre d'element dans le dico : "+Str(CountList(Dico())))



CurrentWord = 0
PrintN("")
StartTime.l = ElapsedMilliseconds()
ForEach Dico()

  If Len(Dico()) = Len(Compare(CurrentWord))
    Result = CompareWord(Dico(),Compare(CurrentWord))
    If Result = 1
      PrintN("MOT TROUVER = "+Compare(CurrentWord)+"="+Dico())
      CurrentWord + 1
      Final$ + Dico()+","
      ResetList(Dico())
    EndIf
  EndIf
  
  If CurrentWord>9
    EndTime.l = ElapsedMilliseconds()
    time.l = EndTime - StartTime
    PrintN("Tout les mots ont ete trouve en "+Str(time)+" ms.  :D ")
    PrintN(Left(Final$,Len(Final$)-1))
     SetClipboardText(Final$)
    Break 1
  EndIf
Next

Input()


ProcedureDLL.s Url2Text2(Url.s, OpenType.b,ProxyAndPort.s)
  ;/ Author : Pille
  isLoop.b=1
  INET_RELOAD.l = $80000000
  hInet.l=0
  hURL.l=0
  Bytes.l=0
  Buffer.s= Space (2048 )
  RES.s= ""
  hInet = InternetOpen_ ( "" , OpenType, ProxyAndPort, "" , 0)
  hURL = InternetOpenUrl_ (hInet, Url, #Null , 0, INET_RELOAD, 0)
  Repeat
    InternetReadFile_ (hURL,@Buffer, Len (Buffer), @Bytes)
    If Bytes = 0
      isLoop=0
    Else
      RES = RES + Left (Buffer, Bytes)
    EndIf
  Until isLoop=0
  InternetCloseHandle_ (hURL)
  InternetCloseHandle_ (hInet)
  ProcedureReturn RES
EndProcedure 

Procedure.b CompareWord(A$,B$)
  
  NewList A.s()
  NewList B.s()
  
  If Len(A$)<>Len(B$) : ProcedureReturn #False : EndIf
  
  ; On rempli les 2 liste chainées...
  For i = 1 To Len(A$)
    AddElement(A()) : A() = Mid(A$,i,1)
    AddElement(B()) : B() = Mid(B$,i,1)
  Next
  
  ; On compare chaque lettre de A() a B() , si A==B alors B=$
  ForEach A()
    ForEach B()
      If A() = B()
        B() ="$"
      EndIf
    Next
  Next
  
  ; Si  ...B()=$ alors on a trouvé le bon mots
  ForEach B()
    If B()<>"$"
      ProcedureReturn #False
    EndIf
  Next
  ProcedureReturn #True
EndProcedure

Bon , j'arrête là , sinon je vais te faire tout les challenges ( j'ai commençer à codé le suivant... :? )
a toi maintenant de trouver comment posté le resultat du code :D

Publié : ven. 29/févr./2008 23:42
par nico
Je vous propose une autre façon de faire, chaque lettre représente un chiffre, donc un mot représente une valeur, elle reste la même quelque soit son ordre, pour que ça marche il faut que chaque lettre soit une puissance différente de 2.

Code : Tout sélectionner

Global chaine.s
chaine.s="0123456789abcdefghijklmnopqrstuvwxyz"

Procedure.l Valeur(Mot.s)
  Protected q.q=1,valeur.q=0
  For a =1 To Len(Mot)
      lettre.s=Mid(Mot,a,1)
      pos=FindString(chaine,lettre,1)
      pos=pos-1 ;on est obliger de retrancher ici, sinon ça bug
      valeur.q=valeur+ q<<pos ;(bug si on met q<<(pos-1)
  Next a
  Debug valeur
  ProcedureReturn valeur
EndProcedure

dico.s="maman"
MotaTrouve.s="mmnaa"

If Len(dico)=Len(MotaTrouve)
  Valeur1.q= Valeur(dico)
  Valeur2.q= Valeur(MotaTrouve)
  If Valeur1=Valeur2
      Debug "C'est un Anagramme!"
  EndIf 
EndIf 
[Edit]je viens de me rendre compte que pour que ça marche, il faut vérifier que les mots soit de la même longueur avant de tester (Tant mieux ça ira encore plus vite!), code mis à jour!

Publié : sam. 01/mars/2008 11:41
par Ar-S
Et bien les amis c'est superbes.
Pour le moment j'ai adapté celui de Cpl.Bator et j'arrive à utiliser le tout.
Maintenant il faut que je fasse en sorte qu'il renvoi la série de 10 anagrammes du dico sous la forme mot1, mot2, mot3, etc à une page php eb POST
J'ai eu croisé ce genre de code dans un topic mais faut que je me prépare pour aller bosser la. Je reprendrai demain.

Nico j'examine ton code des que je peux.

Merci à vous.

Publié : lun. 10/mars/2008 14:15
par Frenchy Pilou
Justement je suis passé par là par hasard ;)
http://www.barbery.net/

Re: retrouver des mots mélangés dans un dico

Publié : sam. 23/juil./2011 15:12
par Ar-S
Je reviens pour ce sujet bien sympa (j'avais mis de coté par manque de temps)
Je suis en train d'en faire un autre du même genre mais avec seulement des numéros dans le dico, du coup la technique de Nico n'est plus viable.
Voilà le liens du dico

J'ai donc repris le code de G-ROM en l'adaptant et en optant pour les expressions régulières pour "parser" la source afin de récupérer les 7 suites de nombres.

Mon soucis vient de la comparaison, les résultats trouvés sont parfois bon, parfois mauvais et je ne vois pas pourquoi.


P.S :
J'ai imposé un FINDWORDS$ extrait de la source de la page du test car pour la récupérer il me faut appeler le serveur avec mes infos de session et je ne trouve plus le topic (me semble que LSI ou G-ROM avaient fait un truc du genre)

Voilà le code.

Code : Tout sélectionner


Declare.b CompareWord(A$,B$)
Declare.s Url2Text2(Url.s, OpenType.b,ProxyAndPort.s)

Global.l EndTime,StartTime
Global.l NbrTrouve
Global NewList Dico.s()


;{- PROCEDURES
ProcedureDLL.s Url2Text2(Url.s, OpenType.b,ProxyAndPort.s)
	;/ Author : Pille
	isLoop.b=1
	INET_RELOAD.l = $80000000
	hInet.l=0
	hURL.l=0
	Bytes.l=0
	Buffer.s= Space (2048 )
	RES.s= ""
	hInet = InternetOpen_ ( "" , OpenType, ProxyAndPort, "" , 0)
	hURL = InternetOpenUrl_ (hInet, Url, #Null , 0, INET_RELOAD, 0)
	Repeat
		InternetReadFile_ (hURL,@Buffer, Len (Buffer), @Bytes)
		If Bytes = 0
			isLoop=0
    Else
			RES = RES + Left (Buffer, Bytes)
    EndIf
  Until isLoop=0
	InternetCloseHandle_ (hURL)
	InternetCloseHandle_ (hInet)
	ProcedureReturn RES
EndProcedure 

Procedure.b CompareWord(A$,B$)
	
	NewList A.s()
	NewList B.s()
	
	If Len(A$)<>Len(B$) : ProcedureReturn #False : EndIf
	
	; On rempli les 2 liste chainées...
	For i = 1 To Len(A$)
		AddElement(A()) : A() = Mid(A$,i,1)
		AddElement(B()) : B() = Mid(B$,i,1)
  Next
	
	; On compare chaque lettre de A() a B() , si A==B alors B=$
	ForEach A()
		ForEach B()
			If A() = B()
				B() ="$"
      EndIf
    Next
  Next
	
	; Si  ...B()=$ alors on a trouvé le bon mots
	ForEach B()
		If B()<>"$"
			ProcedureReturn #False
    EndIf
  Next
	ProcedureReturn #True
EndProcedure
;}-






;- PROGRAMME

StartTime = ElapsedMilliseconds()

;-On télécharge le dico...

If ReadFile(0, "dico.txt")  ; Dico de 500 lignes ou http://www.newbiecontest.org/epreuves/prog/frok-fichus_nb/anag.txt
  While Eof(0) = 0   
    AddElement(Dico())
    Dico() = ReadString(0)
    ; Debug Dico()
  Wend
  CloseFile(0)
  
Else
  MessageRequester("Information","Impossible d'ouvrir le fichier!")
EndIf


;-On télécharge et on parse la source
;FINDWORDS$ = Url2Text2("http://www.newbiecontest.org/epreuves/prog/frok-fichus_nb/prog_1.php",1,"")

FINDWORDS$=">Bienvenue!</strong><br/><br/>Les sept anagrammes dans l'ordre sont:  998466&2755829;1898873&971926#8775637#2223645x4413999<br/><br/>Renvoyez les ré"
expr$ = "([0-9]){6}[0-9]*" 

If CreateRegularExpression(0,expr$)
  Debug "expression créée"
  Dim Acomparer$(0)
  
  NbrTrouve = ExtractRegularExpression(0, FINDWORDS$ , Acomparer$()) ;Extrait les résultat dans Acomparer$()
  
  For i = 0 To NbrTrouve-1
    Debug "A comparer : "+Acomparer$(i)
  Next i  
  
Else
  
  Debug "Rien a extraire de la source"

EndIf 

;- COMPARAISON
  
Final$=""
CurrentWord = 0 

ResetList(Dico()) 
While NextElement(Dico())

	If Len(Dico()) = Len(Acomparer$(CurrentWord))
    
		Result = CompareWord(Dico(),Acomparer$(CurrentWord))
		If Result = 1
			Debug "MOT TROUVER = "+Acomparer$(CurrentWord)+"="+Dico()
			CurrentWord + 1
			Final$ + Dico()+","
			ResetList(Dico())
    EndIf
  EndIf
	
	If CurrentWord>6
    ; Delay (200) ; ajouté si vous n'obtenez pas de ms du fait un proce trop véloce
		EndTime = ElapsedMilliseconds()
		time.l = EndTime - StartTime
		MessageRequester("OK","Tous les mots ont ete trouvé en "+Str(time)+" ms.  :D"+Chr(10)+Left(Final$,Len(Final$)-1))
    SetClipboardText(Final$)
		Break 1
  EndIf
Wend


Re:

Publié : sam. 23/juil./2011 16:32
par lepiaf31
nico a écrit :Je vous propose une autre façon de faire, chaque lettre représente un chiffre, donc un mot représente une valeur, elle reste la même quelque soit son ordre
La technique de hashage me parait etre une bonne idée, c'est efficace pour éviter d'avoir à tester les lettres une par une =)

Re: Anagrames en utilisant un dico de mots

Publié : dim. 24/juil./2011 21:43
par Ar-S
J'ai finalement recréer la fonction CompareWord(), surement pas de façon très pro mais le résultat est là.
Pour le dico, le programme va maintenant directement le récupe en ligne.

P.S :
J'ai imposé un FINDWORDS$ extrait de la source de la page du test car pour la récupérer il me faut appeler le serveur avec mes infos de session et je ne trouve plus le topic (me semble que LSI ou G-ROM avaient fait un truc du genre). Vous pouvez utiliser 2 tests. Test1$ et test2$

Voilà le code au complet :

Code : Tout sélectionner


Declare.b CompareWord(A$,B$)
Declare.s Url2Text2(Url.s, OpenType.b,ProxyAndPort.s)

Global.l EndTime,StartTime
Global.l NbrTrouve
Global.l Anag_A_Trouver = 7

Global NewList Acomparer6.s()
Global NewList Acomparer7.s()
Global NewList Dico6.s()
Global NewList Dico7.s()
Global Final$

Test1$ = "<strong>Bienvenue!</strong><br/><br/>Les sept anagrammes dans L'ordre sont:  7638591°4663579+5673322'3266689.3918047;0648842&8451018<br/><br/>Renvoyez les réponses en moins d'une seconde à l"
Test2$ = "<strong>Bienvenue!</strong><br/><br/>Les sept anagrammes dans L'ordre sont:  5993418;6136323;223995'8767375x1650008+6530517-7492753<br/><br/>Renvoyez Les réponses en moins d'une seconde à l'aide du formulaire"

;{-// PROCEDURES
ProcedureDLL.s Url2Text2(Url.s, OpenType.b,ProxyAndPort.s)
	;/ Author : Pille
	isLoop.b=1
	INET_RELOAD.l = $80000000
	hInet.l=0
	hURL.l=0
	Bytes.l=0
	Buffer.s= Space (2048 )
	RES.s= ""
	hInet = InternetOpen_ ( "" , OpenType, ProxyAndPort, "" , 0)
	hURL = InternetOpenUrl_ (hInet, Url, #Null , 0, INET_RELOAD, 0)
	Repeat
		InternetReadFile_ (hURL,@Buffer, Len (Buffer), @Bytes)
		If Bytes = 0
			isLoop=0
    Else
			RES = RES + Left (Buffer, Bytes)
    EndIf
  Until isLoop=0
	InternetCloseHandle_ (hURL)
	InternetCloseHandle_ (hInet)
	ProcedureReturn RES
EndProcedure 


Procedure.b CompareWord(A$,B$)
    
    A_Nbr_de_0 = CountString(A$,"0")
    A_Nbr_de_1 = CountString(A$,"1")
    A_Nbr_de_2 = CountString(A$,"2")
    A_Nbr_de_3 = CountString(A$,"3")
    A_Nbr_de_4 = CountString(A$,"4")
    A_Nbr_de_5 = CountString(A$,"5")
    A_Nbr_de_6 = CountString(A$,"6")
    A_Nbr_de_7 = CountString(A$,"7")
    A_Nbr_de_8 = CountString(A$,"8")
    A_Nbr_de_9 = CountString(A$,"9")
    
    B_Nbr_de_0 = CountString(B$,"0")
    B_Nbr_de_1 = CountString(B$,"1")
    B_Nbr_de_2 = CountString(B$,"2")
    B_Nbr_de_3 = CountString(B$,"3")
    B_Nbr_de_4 = CountString(B$,"4")
    B_Nbr_de_5 = CountString(B$,"5")
    B_Nbr_de_6 = CountString(B$,"6")
    B_Nbr_de_7 = CountString(B$,"7")
    B_Nbr_de_8 = CountString(B$,"8")
    B_Nbr_de_9 = CountString(B$,"9")
    
    If A_Nbr_de_0 = B_Nbr_de_0 And A_Nbr_de_1 = B_Nbr_de_1 And A_Nbr_de_2 = B_Nbr_de_2 And A_Nbr_de_3 = B_Nbr_de_3 And A_Nbr_de_4 = B_Nbr_de_4 And A_Nbr_de_5 = B_Nbr_de_5 And A_Nbr_de_6 = B_Nbr_de_6 And A_Nbr_de_7 = B_Nbr_de_7 And A_Nbr_de_8 = B_Nbr_de_8 And A_Nbr_de_9 = B_Nbr_de_9
      ProcedureReturn #True
    Else 
      ProcedureReturn #False
    EndIf  

EndProcedure
  ;}-



;-// PROGRAMME

StartTime = ElapsedMilliseconds()

;---- On télécharge et on parse la source pour retrouver les anagrammes
  ;FINDWORDS$ = Url2Text2("http://www.newbiecontest.org/epreuves/prog/frok-fichus_nb/prog_1.php",1,"")
  
FINDWORDS$=Test2$
expr$ = "([0-9]){6}[0-9]*" ; L'epression régulière
  
Dim Acomparer$(0)

If CreateRegularExpression(0,expr$)
  
  NbrTrouve = ExtractRegularExpression(0, FINDWORDS$ , Acomparer$()) ;Extrait les résultat dans Acomparer$()
  
  NbrACOMP6 = 0 : NbrACOMP7 = 0
  
  For i = 0 To NbrTrouve-1
    LongAcomp.l = Len(Acomparer$(i))
    
    If LongAcomp = 6
      AddElement(Acomparer6())
      Acomparer6() = Acomparer$(i)
      NbrACOMP6 + 1
      
    ElseIf LongAcomp = 7
      AddElement(Acomparer7())
      Acomparer7() = Acomparer$(i)
      NbrACOMP7 + 1
      
    Else  
      Debug  "*** Erreur Anagrammes : "+Acomparer$(i)+" contient "+Str(Len(Acomparer$(i)))+" chiffres"
    EndIf 
  Next i
  
  ;---- Vérification que les 7 anagrammes ont été extraits
  
  If NbrTrouve = Anag_A_Trouver And (NbrACOMP7+NbrACOMP6) = NbrTrouve
    Debug "il y a "+ Str(NbrACOMP6) + " suites de 6 chiffres et " + Str(NbrACOMP7) + " suites de 7 chiffres" 
    Debug "pour un total de "+Str(NbrACOMP7+NbrACOMP6)+ "anagrammes à trouver" 
    
  Else
    
    MessageRequester("Erreur","Seulement "+Str(NbrTrouve)+" anagrammes ont pu être extraits")
    End
    
  EndIf
  
Else
  
  Debug "*** Erreur, rien a extraire de la source"
  
EndIf 

Dim Acomparer$(0) ; On libère la mémoire car plus besoin du tableau 

;---- On télécharge le dico...
;-et on créé 2 listes, une avec les suites de 6 chiffres, une avec suites de 7 chiffres

Nbr6 = 0 : Nbr7 = 0

Source$=Url2Text2("http://www.newbiecontest.org/epreuves/prog/frok-fichus_nb/anag.txt",1,"")
expr$ = "([0-9]){6}[0-9]*" ; L'epression régulière
  
Dim Dico$(0)

If CreateRegularExpression(0,expr$)
  
  NbrMotDico = ExtractRegularExpression(0, Source$ , Dico$()) ;Extrait les résultat dans Dico$()
  For i = 0 To NbrMotDico - 1
    Element$ = Dico$(i)
    LongElem.l = Len(Element$)
    
    If LongElem = 6
      
      AddElement(Dico6())
      Dico6() = Element$
      Nbr6 + 1
      
    ElseIf LongElem = 7
      
      AddElement(Dico7())
      Dico7() = Element$
      Nbr7 + 1
      
    EndIf  
   
  Next 

  
Else
  MessageRequester("Information","Impossible de lire l'URL")
EndIf
  
Dim Dico$(0) ; On vide le tableau pour récupérer la mémoire.



  
;---- Comparaison et Recherche des anagrammes
  
Final$="Anagramme  : "
   
ResetList(Dico6())
ResetList(Acomparer6())

While NextElement(Dico6()) 
  
  ForEach Acomparer6()
    
    Result = CompareWord(Acomparer6(),Dico6())
    If Result = 1
      Debug Acomparer6()+" est l'anagramme de "+Dico6()
      Final$ + Dico6()+","
    EndIf
    
  Next
  
Wend


ResetList(Dico7())
ResetList(Acomparer7())


While NextElement(Dico7()) 
  
  ForEach Acomparer7()
    
    Result = CompareWord(Acomparer7(),Dico7())
    
    If Result = 1
      Debug Acomparer7()+" est l'anagramme de "+Dico7()
      Final$ + Dico7()+","
    EndIf
    
  Next
  
Wend

;- Affichage des résultats

EndTime = ElapsedMilliseconds()
time.l = EndTime - StartTime
MessageRequester("OK","Tous les mots ont ete trouvé en "+Str(time)+" ms.  :D"+Chr(10)+Left(Final$,Len(Final$)-1))
SetClipboardText(Final$)


Re: Anagrames en utilisant un dico de mots

Publié : lun. 25/juil./2011 0:01
par Ar-S
J'ai finalement créé une procédure IsAnagram() qui renvoie 1 ou 0

Je suis content, cette méthode ne marchera pas que pour cet exercice comme ma 1ere méthode.

voilà le résultat :

Code : Tout sélectionner


Declare.s Url2Text2(Url.s, OpenType.b,ProxyAndPort.s)

Global.l EndTime,StartTime
Global.l NbrTrouve
Global.l Anag_A_Trouver = 7

Global NewList Acomparer.s()
Global NewList Dico.s()


Test1$ = "<strong>Bienvenue!</strong><br/><br/>Les sept anagrammes dans L'ordre sont:  7638591°4663579+5673322'3266689.3918047;0648842&8451018<br/><br/>Renvoyez les réponses en moins d'une seconde à l"
Test2$ = "<strong>Bienvenue!</strong><br/><br/>Les sept anagrammes dans L'ordre sont:  5993418;6136323;223995'8767375x1650008+6530517-7492753<br/><br/>Renvoyez Les réponses en moins d'une seconde à l'aide du formulaire"

;{-// PROCEDURES
ProcedureDLL.s Url2Text2(Url.s, OpenType.b,ProxyAndPort.s)
	;/ Author : Pille
	isLoop.b=1
	INET_RELOAD.l = $80000000
	hInet.l=0
	hURL.l=0
	Bytes.l=0
	Buffer.s= Space (2048 )
	RES.s= ""
	hInet = InternetOpen_ ( "" , OpenType, ProxyAndPort, "" , 0)
	hURL = InternetOpenUrl_ (hInet, Url, #Null , 0, INET_RELOAD, 0)
	Repeat
		InternetReadFile_ (hURL,@Buffer, Len (Buffer), @Bytes)
		If Bytes = 0
			isLoop=0
    Else
			RES = RES + Left (Buffer, Bytes)
    EndIf
  Until isLoop=0
	InternetCloseHandle_ (hURL)
	InternetCloseHandle_ (hInet)
	ProcedureReturn RES
EndProcedure 


Procedure.b IsAnagram(SourceString.s,DicoString.s)
  ; Libs ANAGRAMMES by Ar-S / 2011
  
  Protected.l NbrCarSource,NbrCarString,Trouve,cherche
  Protected.s LettreSource
  
  NbrCarSource = Len(SourceString)
  NbrCarDico = Len(DicoString)
  Trouve = 0
  
  If NbrCarSource <> NbrCarDico
    ProcedureReturn #False
    
  Else  
    
    For i = 1 To NbrCarSource
      LettreSource = Mid(SourceString,i,1)

      cherche = FindString(DicoString,LettreSource,1)
      If cherche = 0
        ProcedureReturn #False
      Else  
        
        Trouve + 1
        If Trouve = NbrCarSource
          ProcedureReturn #True
        Else
          DicoString = RemoveString(DicoString, LettreSource, 0, 1, 1) ; On retire UNE FOIS le string ciblé
        EndIf
        
      EndIf
      
    Next i
  EndIf
  
EndProcedure
  ;}-


;-// PROGRAMME

StartTime = ElapsedMilliseconds()

;---- On télécharge et on parse la source pour retrouver les anagrammes
  ;FINDWORDS$ = Url2Text2("http://www.newbiecontest.org/epreuves/prog/frok-fichus_nb/prog_1.php",1,"")
  
FINDWORDS$=Test2$
expr$ = "([0-9]){6}[0-9]*" ; L'epression régulière
  
Dim Acomparer$(0)

If CreateRegularExpression(0,expr$)
  NbrTrouve = ExtractRegularExpression(0, FINDWORDS$ , Acomparer$()) ;Extrait les résultat dans Acomparer$()
  
  For i = 0 To NbrTrouve-1
      AddElement(Acomparer())
      Acomparer() = Acomparer$(i)
  Next i
  
  ;---- Vérification que les 7 anagrammes ont été extraits
  
  If NbrTrouve = Anag_A_Trouver 
    Debug "Il y a "+Str(NbrTrouve)+" anagrammes à trouver" 
    
  Else
    
    MessageRequester("Erreur","Seulement "+Str(NbrTrouve)+" anagrammes ont pu être extraits")
    End
    
  EndIf

  
Else
  
  Debug "*** Erreur, rien a extraire de la source"
  
EndIf 

Dim Acomparer$(0) ; On libère la mémoire car plus besoin du tableau 

;---- On télécharge le dico...
;-et on créé 2 listes, une avec les suites de 6 chiffres, une avec suites de 7 chiffres

Source$=Url2Text2("http://www.newbiecontest.org/epreuves/prog/frok-fichus_nb/anag.txt",1,"")
expr$ = "([0-9]){6}[0-9]*" ; L'epression régulière
  
Dim Dico$(0)

If CreateRegularExpression(0,expr$)
  
  NbrMotDico = ExtractRegularExpression(0, Source$ , Dico$()) ;Extrait les résultat dans Dico$()
  For i = 0 To NbrMotDico - 1
    Element$ = Dico$(i)
     
      AddElement(Dico())
      Dico() = Element$ 
  Next 
  
  
Else
  MessageRequester("Information","Impossible de lire l'URL")
EndIf
  
Dim Dico$(0) ; On vide le tableau pour récupérer la mémoire.



  
;---- Comparaison et Recherche des anagrammes
  
Final$="Anagramme  : "
   
ResetList(Dico())
ResetList(Acomparer())

While NextElement(Dico()) 
  
  ForEach Acomparer()
    
    Result = IsAnagram(Acomparer(),Dico())
    If Result = 1
      Debug Acomparer()+" est l'anagramme de "+Dico()
      Final$ + Dico()+","
    EndIf
    
  Next
  
Wend


;- Affichage des résultats

EndTime = ElapsedMilliseconds()
time.l = EndTime - StartTime
MessageRequester("OK","Tous les mots ont ete trouvé en "+Str(time)+" ms.  :D"+Chr(10)+Left(Final$,Len(Final$)-1))
SetClipboardText(Final$)

Ce topic est résolu Image