# Problem 2022. Find a Pythagorean triple

Mayla
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

A 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