Problem 2022. Find a Pythagorean triple


That's the question: Given four different positive numbers, a, b, c and d, provided in increasing order: a < b < c < d, find if any three of them comprise sides of a right-angled triangle. Return true if they do, otherwise return false .
I wrote this code but it doesn't pass test 7. I don't really understand why it isn't working. Can somebody help me?
function flag = isTherePythagoreanTriple(a, b, c, d)
a2=a^2
b2=b^2
c2=c^2
d2=d^2
format shortG
if a2+b2==c2
flag=true
else if a2+b2==d2
flag=true
else if a2+c2==d2
flag=true
else if c2+b2==d2
flag=true
else flag=false
end
end
end
end
end
John D'Errico
John D'Errico el 13 de Sept. de 2023
A simple enough solution...
isTherePythagoreanTriple(1,2,3,4)
ans = logical
0
isTherePythagoreanTriple(3,4,5,6)
ans = logical
1
isTherePythagoreanTriple(12,13,15,2)
Error using solution>isTherePythagoreanTriple
The sky is falling. Require 0<a<b<c<d
function flag = isTherePythagoreanTriple(a, b, c, d)
% tests to see if any set of 3 of the 4 numbers form a pythagorean
% triple. Presume they are integers, no larger than roughly 2^26, else
% overflow of a double will be an issue.
% test the numbers are strictly increasing
abcd = [a;b;c;d].^2;
if any(diff(abcd)<=0) || any(abcd<=0)
error('The sky is falling. Require 0<a<b<c<d')
end
if any(mod(abcd,1)~=0)
error('The sky is falling. Require purely integer inputs')
end
% returns true, if ANY of the set is a triple
% no tolerance is required, since all must be purely integer
flag = any([1 1 -1 0;1 1 0 -1;1 0 1 -1;0 1 1 -1]*abcd==0);
end
Bruno Luong
Bruno Luong el 13 de Sept. de 2023
abcd = [a;b;c;d].^2;
if ... || any(abcd<=0)
Do you mean testing positiveness on a, b, c, d, not their squared?
Dyuman Joshi
Dyuman Joshi el 13 de Sept. de 2023
While your solution works theoretically (and symbolically), numerically there's a good chance it will fail.
And there's a guarantee it will fail when there's an irrational number involved, which is the situation with test case #7 (a = 1, b = 2, c = sqrt(5), d = 6)
Why it will fail? Because we are using floating point numbers which have finite precision. Read more here - https://in.mathworks.com/matlabcentral/answers/57444-faq-why-is-0-3-0-2-0-1-not-equal-to-zero?s_tid=srchtitle
%Example
y = sqrt(3);
isequal(y^2,3)
ans = logical
0
Let's compare the value of sqrt(3) and its square, numerically and symbolically.
%Numerical
sprintf('y = %0.20f',y)
ans = 'y = 1.73205080756887719318'
%Symbolic
z=sqrt(sym(3));
vpa(z,20)
ans = 
1.7320508075688772935
%Numeric square
sprintf('y^2 = %0.20f', y^2)
ans = 'y^2 = 2.99999999999999955591'
%Symbolic square
vpa(z^2,20)
ans = 
3.0
You can see that the numerical values are not accurate.
> So, what to do now?
The solution (or workaround) is to use tolerance to compare numerical values (a.k.a floating point numbers) -
val = 0.3-0.2;
sol = 0.1;
tol = 1e-6;
%isequal does not work
isequal(val,sol)
ans = logical
0
%comparing against a tolerance
abs(val-sol)<tol
ans = logical
1
For your case it would be -
a2=a^2;
b2=b^2;
c2=c^2;
d2=d^2;
%define a tolerance
tol = ...;
if abs(a2+b2-c2)<tol
...
I leave it to you to do the same for the rest of the cases.
Additionally
format shortG
Changing the format only changes how a number is displayed, not how a number is stored.
%Let's check for y defined above
%Displayed value
y
y =
1.7321
%Stored value
sprintf('y = %0.42f', y)
ans = 'y = 1.732050807568877193176604123436845839023590'
Dyuman Joshi
Dyuman Joshi el 13 de Sept. de 2023
It is.
However, the title of the question is misleading.
Title - "Find a Pythagorean triple"
Problem description - "Given four different positive numbers, a, b, c and d, provided in increasing order: a < b < c < d, find if any three of them comprise sides of a right-angled triangle. Return true if they do, otherwise return false."
Bruno Luong
Bruno Luong el 13 de Sept. de 2023
Wasn't pythagoreal triple is a definition only for integers https://en.wikipedia.org/wiki/Pythagorean_triple ?
Bruno Luong
Bruno Luong el 13 de Sept. de 2023
"I wrote this code but it doesn't pass test 7"
What is test 7?
I read through and I don't see any major problem with your code. (Maybe I need to take a MATLAB training too.)
May be they require your function to check 0 < a < b < c < d ? May be they don't like your code formatting? or you use of nested if/else/end?
Matt J
Matt J el 13 de Sept. de 2023
function flag = isTherePythagoreanTriple(a, b, c, d)
X=[a,b,c,d];
X=X(nchoosek(1:4,3));
flag=any( X(:,1).^2 + X(:,2).^2 == X(:,3).^2 );
end
Matt J
Matt J el 13 de Sept. de 2023
function flag = isTherePythagoreanTriple(a, b, c, d)
a2=a^2;
b2=b^2;
c2=c^2;
d2=d^2;
if a2+b2==c2
flag=true;
elseif a2+b2==d2
flag=true;
elseif a2+c2==d2
flag=true;
elseif c2+b2==d2
flag=true;
else
flag=false;
end
end