Problem 2022. Find a Pythagorean triple
Mayla
on 13 Sep 2023
Latest activity Reply by Bruno Luong
on 13 Sep 2023
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
8 Comments
Time DescendingA simple enough solution...
isTherePythagoreanTriple(1,2,3,4)
isTherePythagoreanTriple(3,4,5,6)
isTherePythagoreanTriple(12,13,15,2)
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
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)
Let's compare the value of sqrt(3) and its square, numerically and symbolically.
%Numerical
sprintf('y = %0.20f',y)
%Symbolic
z=sqrt(sym(3));
vpa(z,20)
%Numeric square
sprintf('y^2 = %0.20f', y^2)
%Symbolic square
vpa(z^2,20)
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)
%comparing against a tolerance
abs(val-sol)<tol
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
%Stored value
sprintf('y = %0.42f', y)
"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?
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
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
Sign in to participate