Page 1 sur 1

Au secour les mathématiciens...

Publié : dim. 24/sept./2006 12:20
par Kwai chang caine
Bonjour

J'ai besoin d'un petit code qui permet de retrouver un nombre qui a été multiplié par la somme de ses chiffres.

Je m'explique 534 * (5+3+4) = 534 * 12 = 6408
Bon, jusqu'a la, ça va.

**********************************************************

Maintenant, je ne connais que le 6408 et je veux que le pc me retourne 534.

Ayant arreté les math en 4e, c'est un peu fort pour moi.
Neanmoins, j'ai fait comme a la maternelle avec les patates et j'ai pondu ça :

Code : Tout sélectionner

a$ = "534"

For i = 1 To Len(a$)
 x + Val(Mid(a$,i,1))
 SommeChiffre$ = Str(x)
Next

b$ = Str(Val(SommeChiffre$) * Val(a$))
Debug b$

Debug "***********************"

a = 0
b = 0
c = 0
d = 0
e = 0
f = 0
g = 0
h = 0
i = 0
j = 0
k = 0
Nombre$ = Space(20)

Repeat

 x + 1
 PokeS(@Nombre$, "000000000" + Str(x), Len("000000000" + Str(x)))
 
 a = Val(Mid(Nombre$, Len(Nombre$), 1))
 b = Val(Mid(Nombre$, Len(Nombre$) - 1, 1))
 c = Val(Mid(Nombre$, Len(Nombre$) - 2, 1))
 d = Val(Mid(Nombre$, Len(Nombre$) - 3, 1))
 e = Val(Mid(Nombre$, Len(Nombre$) - 4, 1))
 f = Val(Mid(Nombre$, Len(Nombre$) - 5, 1))
 g = Val(Mid(Nombre$, Len(Nombre$) - 6, 1))
 h = Val(Mid(Nombre$, Len(Nombre$) - 7, 1))
 i = Val(Mid(Nombre$, Len(Nombre$) - 8, 1))
 j = Val(Mid(Nombre$, Len(Nombre$) - 9, 1))
 k = Val(Mid(Nombre$, Len(Nombre$) - 10, 1))
  
Until ((k*10000000000)+(j*1000000000)+(i*100000000)+(h*10000000)+(g*1000000)+(f*100000)+(e*10000)+(d*1000)+(c*100)+(b*10)+a) * (a+b+c+d+e+f+g+h+i) = Val(b$)


b$ = Str(Val(Str(k) +  Str(j) + Str(i) + Str(h) + Str(g) + Str(f) + Str(e) + Str(d) + Str(c) + Str(b) + Str(a)))

Debug b$ 
Ca marche, mais faut pas abuser du nombre a$, autrement il vaut mieux aller se coucher avant d'avoir la réponse ....

Est ce qu'un fana de math, pourrait améliorer mon code.

Merci d'avance
Bonne journée.

Publié : lun. 25/sept./2006 19:44
par SPH
EDIT : des nombres a 30 chiffres peuvent etre testé !

Code : Tout sélectionner

;SPH(2006) 
;teste tous les nombres qui, multiplié par la somme de ses propres chiffres, donne le nombre "NB" a tester 
;ce code affiche TOUTES les solutions 

Nb.q=360 ; nombre a tester (nombre de 1 a 30 chiffres !!!) EDIT : oops, de 1 a 62 bits; soit 18 chiffres maxi !!!!!!

marqueur.b=0 
old1.q=0 
old2.q=0 
test.q=2
Max = Len(StrQ(nb))*9


Repeat; For test=2 To max

egal.q=nb%test 
If egal=0 
autre.q=nb/test 
long1$=Str(test) 
long2$=Str(autre) 
long1=Len(long1$) 
long2=Len(long2$) 
add1=0 
add2=0 
For SPH=1 To long1 
add1 + Val(Mid(long1$,SPH,1)) 
Next 
For SPH=1 To long2 
add2 + Val(Mid(long2$,SPH,1)) 
Next 

  If test*add1=nb 
    If marqueur=0 
    marqueur+1 
    old1=test 
    old2=autre 
    Else 
    If test=old1 Or test=old2 Or autre=old1 Or autre=old2 
    Goto fini 
    EndIf    
    EndIf 
    Debug (Str(nb)+" = "+Str(test)+" fois la somme de ses chiffres ("+Str(add1)+")") 
  EndIf 
  If autre*add2=nb And test<>autre
    If marqueur=0 
    marqueur+1 
    old1=test 
    old2=autre 
    Else 
    If test=old1 Or test=old2 Or autre=old1 Or autre=old2 
    Goto fini 
    EndIf    
    EndIf 
    Debug (Str(nb)+" = "+Str(autre)+" fois la somme de ses chiffres ("+Str(add2)+")") 
  EndIf 

EndIf 

test+1:Until test>max;Next 


fini: 
If marqueur=0 
    Debug (Str(nb)+" : rien n'a été trouvé...") 
EndIf 


Publié : mar. 26/sept./2006 12:07
par Kwai chang caine
Genial.....merci beaucoup

Ton code c'est le jour et la nuit avec le miens, et encore tu n'a pas utilisé ta botte secrete de rapidité (ASM).

Pour le nombre 1495550980, avec mon code j'avais largement le temps d'aller pisser........... avec ton code j'ai meme pas pu toucher ma braguette. :lol:

J'avais essayé de passer par des strings pour ne pas etre limité en longueur de nombre, car je crois qu'au dessus de 16 chiffres un PC ne sais pas faire.
Comment ferais tu si tu voulais essayer un 15 chiffres par exemple ??
Est-ce possible ?????

Je te remercie de ton aide.

Re: Au secour les mathématiciens...

Publié : mar. 26/sept./2006 16:56
par Patrick88
Kwai chang caine a écrit :Bonjour

J'ai besoin d'un petit code qui permet de retrouver un nombre qui a été multiplié par la somme de ses chiffres.

Je m'explique 534 * (5+3+4) = 534 * 12 = 6408
Bon, jusqu'a la, ça va.

**********************************************************

Maintenant, je ne connais que le 6408 et je veux que le pc me retourne 534.
6408 / 12 = 534 ...

c'est pas de l'asm mais c'est court quand même ....

pat

Publié : mar. 26/sept./2006 20:12
par SPH
@Caine : j'ai modifié mon code pour accepter les grands nombres...

Publié : mar. 26/sept./2006 21:37
par Kwai chang caine
@SPH, je te remercie à nouveau de ta peine.
Alors la, avec ça je devrais m'en sortir.

Je le teste ce week-end et je te tiens au courant.

@Patrick, tu as raison, ça parait simple au premier abord, ta reponse m'a meme fait rire et mis le doute.
Le bleme c'est que l'on ne connais pas la somme des chiffres (12) puisque l'on ne connait pas le nombre qui est multiplié. Maintenant, il est vrai qu'avec 534 ça parait evident, mais avec un nombre de 12 à 15 chiffres ça rame un peu plus.

Ta logique est peut etre pas bete non plus, je pense que tu veut dire qu'en divisant par une variable que l'on incremente de 1 a chaque boucle, on devrait retrouver le nombre qui est egal a la variable en faisant l'addition de ses chiffres pour sortir de cette boucle.
A mediter, j'essaierais ce WE aussi.

Je n'ose à peine vous poster la reponse que j'ai eue sur un forum de mathématique.
Ils m'on parlé d'algorithme d'euclide (EAA) et de logaritme neperien et decimal.
Ayant arreté les math à la maternelle, j'ai trouvé la reponse plus compliquée que la question. :D

Je vous poste leur reponse, alors la vous allez rire parce que entre ta soluce et la leur ........y'a une galaxie.
Qui a raison ?????

Quoi qu'il en soit, je remercie aussi ces personnes de la peine qu'elles se sont donnée à tenter de m'expliquer. :oops:

Bonne lecture, comprenne qui le peux. (Heureusement je leur est demandé d'y aller doucement)

Code : Tout sélectionner

Jusqu'où veux-tu aller ? Si cela reste raisonnable, disons, des nombres de quinze chiffres maximum, je pense que tu peux t'en tirer avec une fonction que tu ne connais probablement pas vu que tu as arrêté les maths en quatrième et qu'on apprend cette fonction en terminale ! Il s'agit de la fonction logarithme, souvent notée log ou ln. Cependant, en tant qu'informaticien, tu as accès à cette fonction dans de nombreux logiciels de programmation. Et rien ne t'empêche d'utiliser cette fonction log même si tu ne la connais pas. 

Le nombre P de chiffres d'un nombre N est donné par la formule :

P = 1 + E( Log(N) / Log(10 )

(E(x) est la partie entière de x, c'est-à-dire le nombre n tel que )

n <= x < n + 1

Par exemple, si N = 1234567890123, avec ton ordinateur, tu peux calculer log(N) : tu trouves 27,8417..., puis log(10) : tu trouves 2,30258.... En divisant le premier par le deuxième, tu trouves 12,091... Tu en prends la partie entière : 12, et tu ajoutes 1, ça fait 13 ! Donc N a 13 chiffres.

À présent, si tu as le produit P du nombre N et de la somme de ses chiffres S, tu es certain que, puisque S est au moins égal à 1 (les chiffres ne peuvent pas être tous 0 !), que N est au plus égal à P : il ne peut pas être plus grand que P ! Si donc tu calcules, comme je viens de te montrer, le nombre de chiffres de P, tu es certain que le nombre de chiffres de N est au maximum égal au nombre de chiffres de P. Par conséquent, puisque par ailleurs tu es certain que chaque chiffre est au maximum égal à 9, en multipliant le nombre de chiffres de P par 9 tu es certain que S ne peut en aucun cas être plus grand que le résultat trouvé.

Or, cette procédure te donne un maximum pour S, qui sera toujours très petit ! Par exemple, en reprenant l'exemple du nombre 1234567890123 ci dessus, qui est déjà très grand, son nombre de chiffres est 13, et si 1234567890123 est le produit de la somme S des chiffres d'un nombre N, avec N, tu sais que S ne peut pas être plus grand que 9*13 soit 117. 

Le nombre d'essais que tu dois donc faire est extrêmement réduit. En prenant sans réfléchir davantage tous les nombres de 2 à 117 et en essayant de diviser 1234567890123 par chacun de ces nombres, tu détecte très rapidement ceux d'entre eux pour lesquels ça tombe juste et tu n'as plus qu'à chercher si la somme des chiffres du quotient est bien égal au nombre testé !

A mon avis, tu n'as pas le temps d'aller te coucher...Tu fais trois pas vers ton lit, et c'est fini !

Bien sûr, si comme l'envisage Flodelarab, tu veux faire ça pour des nombres immenses, genre des nombres de plusieurs centaines de chiffres, c'est plus difficile car il te faut des modules qui peuvent calculer sur de grands nombres. A priori, la plupart des ordinateurs travaillent sur des nombres ayant au maximum 15 à 16 chiffres de précision : pour une plus grande précision, tu as besoin de programmes spéciaux.

Mais même dans ce cas-là, le temps de calcul sera à mon avis très court ! Avec un nombre de 300 chiffres, le S que l'on cherche est limité par 2700 (ben oui ! 9*300 !) ce qui reste encore très peu pour un ordinateur : il faudra quand même trouver un moyen de calculer sur de grands nombres...
Deuxieme reponse, un peu plus simple :

Code : Tout sélectionner

L'algorithme d'Euclide permet de décomposer un nombre en produit de nombres premiers mais cette décomposition ne suffira pas ici, il faut ensuite savoir dans la décomposition quels facteurs correspondent à la somme des chiffres et quels facteurs correspondent au nombre lui même.
J'aurais révé etre mathématicien .......

Merci à tous.

Publié : mar. 26/sept./2006 23:05
par comtois
En applicant l'explication ci dessus. J'ai pas trop testé, mais ça fonctionne au moins pour l'exemple que tu donnes :)

Et ça sort toutes les solutions possibles.

Code : Tout sélectionner

P.q = 3940827136
L = Len(StrQ(P)) : MaxS = L * 9

S = 2 : Trouve = #False
While S <= MaxS
  N.q = P / S
  If N * S = P 
    a$ = StrQ(N) : Somme = 0
    For i = 1 To Len(a$)
      Somme + Val(Mid(a$, i, 1)) 
    Next i
    If Somme = S
      Debug StrQ(P) + " = " + StrQ(N) + " * " + StrQ(S)
      Trouve = #True
    EndIf
  EndIf
  S + 1   
Wend

If Trouve = #False : Debug "rien trouvé" : EndIf
[EDIT]
J'ai supprimé la procédure du code, c'est encore un peu plus court comme ça.

Publié : mer. 27/sept./2006 7:15
par SPH
Bravo, ton code est plus court !

Publié : mer. 27/sept./2006 13:48
par Kwai chang caine
Bonjour à vous deux.

ça progresse, ça progresse de plus en plus petit .....genial :P

Apparement le code de comtois est plus petit et aussi plus costaud, puisque j'ai pu calculer avec ce chiffre de depart, si on en rajoute 1 ça plante :

Code : Tout sélectionner

a.q = 33333333333333333 ; 17 chiffres

For i = 1 To Len(StrQ(a.q)) 
 x.q + Val(Mid(StrQ(a.q),i,1)) 
Next 

p.q = x.q * a.q
Debug p.q 

Debug "***********************" 
Pour celui de SPH, si on en rajoute 1 ça plante :

Code : Tout sélectionner

a.q = 333333333 ; 9 chiffres

For i = 1 To Len(StrQ(a.q)) 
 x.q + Val(Mid(StrQ(a.q),i,1)) 
Next 

Nb.q = x.q * a.q
Debug Nb.q 

Debug "***********************" 
J'ai pris exemple sur votre code pour declarer les variables etc ...
J'ai une question, ça plante à cause de mon code que j'ai mis au dessus du votre, (celui qui multiplie la somme des chiffres du nombre) ou bien on depasse les capacités des variables avec le votre ????
Car comme SPH avait dit que l'on pouvait aller jusqu'a 30.........

C'est juste pour comprendre, car 17 chiffres au depart, ça me suffit largement.

En tout cas, je vous remercie grandement tous les deux, MAITRES

Que la journée vous apporte une infime partie du bonheur que m'a procuré cette conversation avec vous.

Petit scarabé ...

Publié : mer. 27/sept./2006 14:44
par SPH
Heu, pardon, on peux utiliser jusqu'a 19 chiffres mais 18 est plus sûr...

Publié : jeu. 28/sept./2006 11:56
par Kwai chang caine
Bonjour

C'est pas grave 18 c'est deja top, la question etait juste pour faire avancer le schmiblick ......

Je vous remercie encore beaucoup de votre aide à tous les deux.
Je vais avoir du boulot ce WE.

@SPH, je ne sais pas si tu as eu le temps de plancher sur le complement de ton code de la mort en ASM, qui convertissait un fichier en hexa ...

J'aurais besoin de exactement l'inverse de celui que tu as fait.

Code : Tout sélectionner

; Code programmé par SPH
#src=0 
#dst=1 
Lecture.l 
Byte.b 
Hexa.l 
;;;;;;;; 
source$=OpenFileRequester("Fichier à convertir","*.*","*.*",1) 
destin$=SaveFileRequester("Sauver sous","SPH.doc","*.*",1) 

;;;;;;;; 
If ReadFile(#src, source$) 
lg = Lof(#src) 
Else 
MessageRequester("Erreur", "Fichier impossible à lire...") 
End 
EndIf 
;;;;;;;; 
If lg=0 
MessageRequester("Inutilité", "Votre fichier est vide !") 
End 
EndIf 
;;;;;;;; 
If CreateFile(#dst, destin$) 
Else 
MessageRequester("Erreur", "Fichier impossible à créer...") 
End 
EndIf 
;;;;;;;; 

temps = GetTickCount_() 

;;;;;;;; 
reste = lg%4 
paquet = lg/4 
;;;;;;;; 
While paquet>0 
Lecture.l = ReadLong(#src) 
!MOV  eax,[v_Lecture] 
!BSWAP  eax 
!MOV [v_Hexa],eax 
Hexa$ = RSet(Hex(Hexa.l), 8, "0") 
WriteString(#dst, Hexa$) 
paquet-1 
Wend 
;;;;;;;; 
While reste>0 
Byte.b = ReadByte(#src) 
Hexa$ = RSet(Hex(Byte.b), 2, "0") 
WriteString(#dst, Hexa$) 
reste-1 
Wend 
;;;;;;;; 
CloseFile(#src) 
CloseFile(#dst) 
;;;;;;;; 

MessageRequester("Etat du programme", "Conversion finie " +Str( GetTickCount_()-temps )+" ms") 
Si tu pouvais m'aider tu serais un "ange" ....

Je te remercie beaucoup de ta patience.
Y'en faut avec les BB programmeurs .....

Bonne journée

Publié : jeu. 28/sept./2006 15:39
par SPH
Quel est ton projet exact qui utilisera la transformation en hexa et surtout la recherche des nombres qui se multiplient avec la somme de leur chiffres ?????

Publié : jeu. 28/sept./2006 17:46
par Kwai chang caine
Bonjour SPH

Tu m'a déja posé cette question, sur le post Hexa/text, mais je portais un autre PSEUDO, je ne sais pas si tu as fait attention ?? (Voir le bas de ma signature)
SPH a écrit :Tiens, je vais aussi essayer d'en faire un...

A propos, quel est son interet ?? celui de passer un logiciel par l'intermediaire de texte ????
andrebernard a écrit :Bonjour et encore merci a tous de vous pencher sur mon berceau de bb programmeur.

Pour repondre à la curiosité de SPH, l'utilité que j'ai trouvé à ce transfert, c'est de coder des fichiers simplement en y ajoutant une valeur ASCII ou autre pour chacun des chiffres et lettre obtenu dans le texte.

J'essaye de réaliser un décodeur de page internet, c'est a dire de mettre sur un site des pages TRES PERSONNELLES accessible dans le monde entier mais lisible que par mon logiciel.

Je les codes avant de les deposer sur le site ou en meme temps, puis à la lecture si c'est une page HTML ou au telechargement si c'est un autre fichier (ZIP, MP3 etc ...) je les decode avant qu'il n' arrivent sur le DD.

C'est vrai cela va beaucoup ralentir la lecture, mais la confidentialité n'a pas de prix.C'est la raison pour laquelle la rapidité a beaucoup d'importance pour mon projet.

C'est un peu pour remplacer une cle USB quand on l'a oublié chez soi avec la seule limite de la capacité du serveur .

Vala, vala.

Excelente journée à tous et au plaisir de vous lire.
C'est surtout ds un premier temps pour proteger des telechargements des fichiers sur le FTP. Comme ça meme si on me pique mes fichiers, j'espere que le voleur sera moins doué que vous pour les decoder.
Pour les page HTML, je verrais apres comment je vais les coder.

Je voudrais donc coder d'une autre maniere le fichier hexa car DOBRO m'a dit que ma combine etait super connue, mais comme je ne comprend que l'ASCII, j'aurais voulu faire un codage que je comprenne moi-meme :lol:

Quand au 2e code, c'est que une fois le fichier codé, je le decoupe en plusieurs morceaux que je nomme aleatoirement et relié a un fichier lien qui contient le nom de ces portions de fichiers ainsi que le nom du fichier d'origine (Ce fichier lien est bien evidement codé aussi)

Exemple : Photo.jpg deviens 132 + 978 (sans extention) + fichier lien ou dedant il y a ecrit (en codé) 132=978=Photo.jpg.
Evidement les noms des portions de fichiers auront de 10 a 15 chiffres(D'ou ma question pour en avoir 18)

Le nom du fichier lien est donc le resultat du produit de la somme de ses chiffres.

Je sais c'est pas simple, je m'y perd un peu aussi, mais ça marche la seule chose, c'est que ça laboure pour calculer le fameux nombre du fichier lien.

Voila, tu as raison moi aussi j'aime bien savoir pourquoi je bosse.

Je te remercie de ton interet.

Publié : jeu. 28/sept./2006 17:46
par Kwai chang caine
Bonjour SPH

Tu m'a déja posé cette question, sur le post Hexa/text, mais je portais un autre PSEUDO, je ne sais pas si tu as fait attention ?? (Voir le bas de ma signature)
SPH a écrit :Tiens, je vais aussi essayer d'en faire un...

A propos, quel est son interet ?? celui de passer un logiciel par l'intermediaire de texte ????
andrebernard a écrit :Bonjour et encore merci a tous de vous pencher sur mon berceau de bb programmeur.

Pour repondre à la curiosité de SPH, l'utilité que j'ai trouvé à ce transfert, c'est de coder des fichiers simplement en y ajoutant une valeur ASCII ou autre pour chacun des chiffres et lettre obtenu dans le texte.

J'essaye de réaliser un décodeur de page internet, c'est a dire de mettre sur un site des pages TRES PERSONNELLES accessible dans le monde entier mais lisible que par mon logiciel.

Je les codes avant de les deposer sur le site ou en meme temps, puis à la lecture si c'est une page HTML ou au telechargement si c'est un autre fichier (ZIP, MP3 etc ...) je les decode avant qu'il n' arrivent sur le DD.

C'est vrai cela va beaucoup ralentir la lecture, mais la confidentialité n'a pas de prix.C'est la raison pour laquelle la rapidité a beaucoup d'importance pour mon projet.

C'est un peu pour remplacer une cle USB quand on l'a oublié chez soi avec la seule limite de la capacité du serveur .

Vala, vala.

Excelente journée à tous et au plaisir de vous lire.
C'est surtout ds un premier temps pour proteger des telechargements des fichiers sur le FTP. Comme ça meme si on me pique mes fichiers, j'espere que le voleur sera moins doué que vous pour les decoder.
Pour les page HTML, je verrais apres comment je vais les coder.

Je voudrais donc coder d'une autre maniere le fichier hexa car DOBRO m'a dit que ma combine etait super connue, mais comme je ne comprend que l'ASCII, j'aurais voulu faire un codage que je comprenne moi-meme :lol:

Quand au 2e code, c'est que une fois le fichier codé, je le decoupe en plusieurs morceaux que je nomme aleatoirement et relié a un fichier lien qui contient le nom de ces portions de fichiers ainsi que le nom du fichier d'origine (Ce fichier lien est bien evidement codé aussi)

Exemple : Photo.jpg deviens 132 + 978 (sans extention) + fichier lien ou dedant il y a ecrit (en codé) 132=978=Photo.jpg.
Evidement les noms des portions de fichiers auront de 10 a 15 chiffres(D'ou ma question pour en avoir 18)

Le nom du fichier lien est donc le resultat du produit de la somme de ses chiffres.

Je sais c'est pas simple, je m'y perd un peu aussi, mais ça marche la seule chose, c'est que ça laboure pour calculer le fameux nombre du fichier lien.

Voila, tu as raison moi aussi j'aime bien savoir pourquoi je bosse.

Je te remercie de ton interet.