« Mathématiques avec Python et Ruby/Freudenthal sous Ruby » : différence entre les versions

Contenu supprimé Contenu ajouté
Aucun résumé des modifications
DannyS712 (discussion | contributions)
m <source> -> <syntaxhighlight> (phab:T237267)
 
Ligne 21 :
Si on avait confié un [[w:Nombre premier|nombre premier]] à Polly, elle n'aurait pas avoué son impuissance lors de sa première affirmation. Bien que ce ne soit nullement nécessaire pour résoudre ce problème, ''Ruby'' sait depuis la version 1.9 manipuler des nombres premiers. Avec
 
<sourcesyntaxhighlight lang="ruby">
puts(Prime.prime?(p))
</sourcesyntaxhighlight>
 
on peut savoir si ''p'' est premier, et avec
 
<sourcesyntaxhighlight lang="ruby">
puts(Prime.prime_division(n))
</sourcesyntaxhighlight>
 
on décompose ''n'' en facteurs premiers.
Ligne 37 :
Plutôt que de manipuler des couples d'entiers ''x'' et ''y'' possibles, on va, comme dans [[Mathématiques_avec_Python_et_Ruby/Freudenthal_en_Python|la version Python]], manipuler l'ensemble des produits possibles. Donc on aura besoin de l'outil permettant, à partir d'une somme ''s'' donnée à Sam, d'obtenir la liste ''prod(s)'' des produits donnés à Polly qui correspondent aux mêmes ''x'' et ''y'':
 
<sourcesyntaxhighlight lang="ruby">
def prod(n)
t=[]
Ligne 43 :
return t.uniq
end
</syntaxhighlight>
</source>
 
On peut décrire l'algorithme ci-dessus ainsi:
Ligne 57 :
On ramasse les ''y'' entre 3 et 100; pour chacun d'entre eux on ramasse (''collect'') les ''x'' entre 2 et ''y-1''; si la somme ''x+y'' est inférieure ou égale à 100, on rajoute le produit dans le tableau ''produit''. Ensuite on constitue pour chaque ''p'' de ce tableau, l'ensemble des ''k'' égaux à ''p'' dans le tableau. Si cet ensemble contient un seul élément, on l'enlève (''reject'') du tableau des produits:
 
<sourcesyntaxhighlight lang="ruby">
produits=[]
(3..100).collect{|y| (2..y-1).collect{|x| if x+y<=100 then produits.push(x*y) end}}
Ligne 64 :
polly=produits.reject{|p| (produits.select{|k| k==p}).size<2}
puts(polly.size)
</syntaxhighlight>
</source>
 
Ah oui! Il y en a beaucoup qui restent!
Ligne 72 :
Si Sam sait que Polly ne sait pas, c'est parce que quelle que soit la décomposition en somme d'entiers de celui qu'on lui a dicté, le produit correspondant est dans la liste précédente. Sinon elle eût pu savoir qui sont ''x'' et ''y'', pour ce que Sam en sait! Sam ne va donc garder que les sommes n pour lesquelles la liste prod(n) calculée avec la fonction ci-dessus ne contient que des éléments de la liste ''polly'', donc si leur intersection est égale à ''prod(n)'' (en effet <math>A \subset B \Leftrightarrow A \cap B =A</math> dans [[w:Algèbre de Boole (structure)|l'algèbre de Boole]] des ensembles):
 
<sourcesyntaxhighlight lang="ruby">
sam=(4..100).select{|s| prod(s)&polly==prod(s)}
puts(sam)
</syntaxhighlight>
</source>
 
Il reste plutôt peu de sommes possibles:
Ligne 92 :
Si Polly sait maintenant quels sont ''x'' et ''y'', c'est que parmi les sommes ci-dessus, il n'y a pas que des doublons (produits communs à plusieurs sommes). Il y a un produit propre à une des sommes de Sam ci-dessus. Pour en savoir plus, Polly va constituer pour chacun des 10 nombres ''s'' ci-dessus, la liste de ses produits ''prod(s)'', puis chercher tous les nombres communs à au moins deux de ces 10 listes (les doublons). ''Ruby'' peut en faire de même, mais après avoir aplati le tableau des ''prod(s)'' (qui est un tableau à deux dimensions), et en plaçant dans la liste des doublons, tous les nombres qui apparaissent plus d'une fois dans le tableau des produits:
 
<sourcesyntaxhighlight lang="ruby">
produits=sam.map{|s| prod(s)}
listeprods=produits.flatten
 
doublons=listeprods.select{|p| (listeprods.select{|k| k==p}).size>1}
</syntaxhighlight>
</source>
 
Ensuite Polly enlève à chaque liste de produits des sommes de ''sam'', les doublons (par une soustraction d'ensembles), et en comptant le nombre d'éléments de chacun des ensembles obtenus,
 
<sourcesyntaxhighlight lang="ruby">
produits.each{|p| puts((p-doublons).size)}
</syntaxhighlight>
</source>
 
 
Ligne 119 :
Puisque Sam sait aussi sa somme, on sait que sa somme est 17 et le produit de Polly, 52:
 
<sourcesyntaxhighlight lang="ruby">
puts(sam[1])
puts(prod(17)-doublons)
</sourcesyntaxhighlight>
 
==À la recherche des x et y perdus==
Ligne 128 :
Maintenant qu'on connaît la somme et le produit de ''x'' et ''y'', il reste à déterminer ceux-ci, ce qui peut se faire en résolvant l'équation du second degré <math>x^2-17x+52=0</math> ou par une double boucle:
 
<sourcesyntaxhighlight lang="ruby">
(3..100).collect{|y| (2..y-1).collect{|x| if x+y==17 and x*y==52 then puts(x,y) end}}
</syntaxhighlight>
</source>
 
Les inconnues ''x'' et ''y'' sont maintenant connues!