Un triplet de Pythagore est un ensemble de trois nombres naturels, a <b <c, pour lesquels, A2 + b2 = c2
Par exemple, 32 + 42 = 9 + 16 = 25 = 52.
Il existe exactement un triplet de Pythagore pour lequel a + b + c = 1000 . Trouver le produit abc.
Source: http://projecteuler.net/index.php?section=problems&id=9
J'ai essayé mais je ne savais pas où mon code s'était mal passé. Voici mon code en C:
#include <math.h>
#include <stdio.h>
#include <conio.h>
void main()
{
int a=0, b=0, c=0;
int i;
for (a = 0; a<=1000; a++)
{
for (b = 0; b<=1000; b++)
{
for (c = 0; c<=1000; c++)
{
if ((a^(2) + b^(2) == c^(2)) && ((a+b+c) ==1000)))
printf("a=%d, b=%d, c=%d",a,b,c);
}
}
}
getch();
}
#include <math.h>
#include <stdio.h>
int main()
{
const int sum = 1000;
int a;
for (a = 1; a <= sum/3; a++)
{
int b;
for (b = a + 1; b <= sum/2; b++)
{
int c = sum - a - b;
if ( a*a + b*b == c*c )
printf("a=%d, b=%d, c=%d\n",a,b,c);
}
}
return 0;
}
explication:
J'ai bien peur que ^
ne fasse pas ce que vous pensez qu'il fait en C. Votre meilleur choix est d'utiliser a*a
pour les carrés entiers.
Voici une solution utilisant la formule d'Euclid ( link ).
Faisons quelques maths: En général, chaque solution aura la forme
a=k(x²-y²)
b=2kxy
c=k(x²+y²)
où k, x et y sont des entiers positifs, y <x et gcd (x, y) = 1 (nous ignorerons cette condition, ce qui conduira à des solutions supplémentaires. Celles-ci pourront être ignorées par la suite)
Maintenant, a + b + c = kx²-ky² + 2kxy + kx² + ky² = 2kx² + 2kxy = 2kx (x + y) = 1000
Diviser par 2: kx (x + y) = 500
Maintenant nous définissons s = x + y: kxs = 500
Nous cherchons maintenant des solutions de kxs = 500, où k, x et s sont des entiers et x < s < 2x
. Tous divisant par 500, ils ne peuvent prendre que les valeurs 1, 2, 4, 5, 10, 20, 25, 50, 100, 125, 250, 500. Quelques pseudocodes pour le faire pour n arbitraire (cela peut être fait à la main facilement pour n = 1000)
If n is odd
return "no solution"
else
L = List of divisors of n/2
for x in L
for s in L
if x< s <2*x and n/2 is divisible by x*s
y=s-x
k=((n/2)/x)/s
add (k*(x*x-y*y),2*k*x*y,k*(x*x+y*y)) to list of solutions
sort the triples in the list of solutions
delete solutions appearing twice
return list of solutions
Vous pouvez toujours améliorer ceci:
Pour n = 1000, le programme doit vérifier six valeurs pour x et en fonction des détails de la mise en œuvre, jusqu'à une valeur pour y. Cela se terminera avant que vous relâchiez le bouton.
Comme mentionné ci-dessus, ^ est au niveau du bit xor, pas du pouvoir.
Vous pouvez également supprimer la troisième boucle et utiliser plutôt c = 1000-a-b;
et l'optimiser un peu.
Pseudocode
for a in 1..1000
for b in a+1..1000
c=1000-a-b
print a, b, c if a*a+b*b=c*c
Il existe une solution assez sale mais rapide à ce problème. Étant donné les deux équations
a * a + b * b = c * c
a + b + c = 1000.
Vous pouvez en déduire la relation suivante
a = (1000 * 1000-2000 * b)/(2000-2b)
ou après deux transformations mathématiques simples, vous obtenez:
a = 1000 * (500-b)/(1000 - b)
puisque a doit être un nombre naturel. Par conséquent, vous pouvez:
for b in range(1, 500):
if 1000*(500-b) % (1000-b) == 0:
print b, 1000*(500-b) / (1000-b)
Obtenu les résultats 200 et 375.
Bonne chance
#include <stdio.h>
int main() // main always returns int!
{
int a, b, c;
for (a = 0; a<=1000; a++)
{
for (b = a + 1; b<=1000; b++) // no point starting from 0, otherwise you'll just try the same solution more than once. The condition says a < b < c.
{
for (c = b + 1; c<=1000; c++) // same, this ensures a < b < c.
{
if (((a*a + b*b == c*c) && ((a+b+c) ==1000))) // ^ is the bitwise xor operator, use multiplication for squaring
printf("a=%d, b=%d, c=%d",a,b,c);
}
}
}
return 0;
}
Je n'ai pas testé cela, mais cela devrait vous mettre sur la bonne voie.
De man pow
:
POW(3) Linux Programmer's Manual POW(3)
NAME
pow, powf, powl - power functions
SYNOPSIS
#include <math.h>
double pow(double x, double y);
float powf(float x, float y);
long double powl(long double x, long double y);
Link with -lm.
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
powf(), powl(): _BSD_SOURCE || _SVID_SOURCE || _XOPEN_SOURCE >= 600 || _ISOC99_SOURCE; or cc -std=c99
DESCRIPTION
The pow() function returns the value of x raised to the power of y.
RETURN VALUE
On success, these functions return the value of x to the power of y.
If x is a finite value less than 0, and y is a finite non-integer, a domain error occurs, and a NaN is
returned.
If the result overflows, a range error occurs, and the functions return HUGE_VAL, HUGE_VALF, or HUGE_VALL,
comme vous le voyez, pow
utilise une arithmétique en virgule flottante, ce qui ne vous donnera probablement pas le résultat exact (même si dans ce cas devrait être OK, car les entiers relativement petits ont une représentation exacte; ne vous fiez pas à cela pour les cas généraux). .. utilisez n*n
pour faire cadrer les nombres en arithmétique entière (également, dans les CPU modernes avec de puissantes unités à virgule flottante, le débit peut être encore plus élevé en virgule flottante, mais la conversion d'entier en virgule flottante a un coût très élevé en nombre de cycles de CPU, donc si vous avez affaire à des nombres entiers, essayez de vous en tenir à l’arithmétique des nombres entiers).
un pseudocode pour vous aider à optimiser un peu votre algorithme:
for a from 1 to 998:
for b from 1 to 999-a:
c = 1000 - a - b
if a*a + b*b == c*c:
print a, b, c
En C, l'opérateur ^ calcule xor au niveau du bit, pas la puissance. Utilisez x*x
à la place.
Je sais que cette question est assez ancienne et que tout le monde a publié des solutions avec 3 boucles pour, ce qui n'est pas nécessaire. Je l'ai résolu en O (n), par **equating the formulas**; **a+b+c=1000 and a^2 + b^2 = c^2**
Donc, en résolvant plus loin nous obtenons;
a+b = 1000-c
(a+b)^2 = (1000-c)^2
Si nous résolvons plus loin nous en déduisons à;
a = ((50000- (1000 * b))/(1000-b)) . Nous bouclons pour "b" et trouvons "a".
Une fois que nous avons "a" et "b", nous obtenons "c".
public long pythagorasTriplet(){
long a = 0, b=0 , c=0;
for(long divisor=1; divisor<1000; divisor++){
if( ((500000-(1000*divisor))%(1000-divisor)) ==0){
a = (500000 - (1000*divisor))/(1000-divisor);
b = divisor;
c = (long)Math.sqrt(a*a + b*b);
System.out.println("a is " + a + " b is: " + b + " c is : " + c);
break;
}
}
return a*b*c;
}
Comme d'autres l'ont déjà mentionné, vous devez comprendre l'opérateur ^ ..____ De plus, votre algorithme produira plusieurs réponses équivalentes avec les paramètres a, b et c dans des ordres différents.
Tandis que autant de personnes ont fait remarquer que votre code fonctionnera correctement une fois que vous passerez à pow
. Si vous êtes intéressé à apprendre un peu de théorie mathématique telle qu’elle s’applique à CS, je vous recommanderais d’implémenter une version plus efficace en utilisant "la formule d’Euclide" pour générer des triples de Pythagore ( link ).
La méthode euclide donne le périmètre à m (m + n) = p/2 où m> n et les côtés sont m ^ 2 + n ^ 2 est l'hypoténuse et les jambes sont 2mn et m ^ 2-n ^ 2. m (m + n) = 500 donne rapidement m = 20 et n = 5. Les côtés sont 200, 375 et 425. Utilisez Euclid pour résoudre toutes les questions primitives pythoriennes.
Comme il existe deux équations (a+b+c = 1000
&& aˆ2 + bˆ2 = cˆ2
) avec trois variables, nous pouvons le résoudre en temps linéaire en parcourant simplement toutes les valeurs possibles d’une variable, puis nous pouvons résoudre les deux autres variables en temps constant.
A partir de la première formule, nous obtenons b=1000-a-c
, et si nous remplaçons b dans la 2ème formule par ceci, nous obtenons c^2 = aˆ2 + (1000-a-c)ˆ2
, ce qui simplifie à c=(aˆ2 + 500000 - 1000a)/(1000-a)
.
Ensuite, nous parcourons toutes les valeurs possibles de a, résolvons c et b avec les formules ci-dessus et, si les conditions sont remplies, nous avons trouvé notre triplet.
int n = 1000;
for (int a = 1; a < n; a++) {
int c = (a*a + 500000 - 1000*a) / (1000 - a);
int b = (1000 - a - c);
if (b > a && c > b && (a * a + b * b) == c * c) {
return a * b * c;
}
}
func maxProd(sum:Int)->Int{
var prod = 0
// var b = 0
var c = 0
let bMin:Int = (sum/4)+1 //b can not be less than sum/4+1 as (a+b) must be greater than c as there will be no triangle if this condition is false and any pythagorus numbers can be represented by a triangle.
for b in bMin..<sum/2 {
for a in ((sum/2) - b + 1)..<sum/3{ //as (a+b)>c for a valid triangle
c = sum - a - b
let csquare = Int(pow(Double(a), 2) + pow(Double(b), 2))
if(c*c == csquare){
let newProd = a*b*c
if(newProd > prod){
prod = newProd
print(a,b,c)
}
}
}
}
//
return prod
}
Les réponses ci-dessus sont suffisantes, mais il manque un élément d'information important a + b> c . ;)
Plus de détails seront fournis à ceux qui le demandent.
for a in range(1,334):
for b in range(500, a, -1):
if a + b < 500:
break
c = 1000 - a - b
if a**2 + b**2 == c**2:
print(a,b,c)
Optimisation plus poussée à partir de la réponse d'Oleg ... Un des côtés ne peut pas être supérieur à la somme des deux autres ... Donc, a + b ne peut être inférieur à 500
Je pense que la meilleure approche est la suivante:
int n = 1000;
unsigned long long b =0;
unsigned long long c =0;
for(int a =1;a<n/3;a++){
b=((a*a)- (a-n)*(a-n)) /(2*(a-n));
c=n-a-b;
if(a*a+b*b==c*c)
cout<<a<<' '<<b<<' '<<c<<endl;
}
explication: Nous nous référerons à la constante N et A pour ne pas avoir à utiliser deux boucles . Nous pouvons le faire car c=n-a-b
et b = (a^2-(a-n)^2)/(2(a-n))
J'ai obtenu ces formules en résolvant un système d'équations:
a+b+c=n
, a^2+b^2=c^2