CodeWars: Pythagorean Theorem Challenge

ofilispeaks
5 min readApr 18, 2021

--

This article goes over one of the coding challenges I faced during a General Assembly closed-book quiz.

I picked this challenge because in a way I accidentally got the answer. But in reality, I got the answer, because I followed a system when coding. And I want to share that system with you today.

The Challenge: The Pythagorean theorem describes the relationship between side lengths of right triangles, where the square of the hypotenuse is equal to the sum of the squared lengths of the other two sides. More commonly, this formula is written as 𝑎^2+𝑏^2 = 𝑐^2, for triangle side lengths

a, b, and hypotenuse c. Any three positive integers that satisfy this property is known as a Pythagorean triple.

Write a function called right_triangle that takes in a list of positive integers and returns a list of Pythagorean triples that exist within the given list of integers.

Some examples of Pythagorean triples:

  • [3, 4, 5], since 3^2+4^2=5^2
  • [5, 12, 13], since 5^2+12^2=13^2
  • [6, 8, 10], since 6^2+8^2=10^2

So for example:

right_triangle([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])

should return:

[[3, 4, 5], [5, 12, 13], [6, 8, 10]]

The Solution: Progressively think through the solution in words, and then pseudo-code, and then inefficient code with the partial answer, and then even more inefficient code with the correct answer, and then optimize.

  1. I want to go through a list of numbers like [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], and find 2 numbers that when squared and summed together, the square root of the result would give a number contained within my list.
  2. So perhaps, I will go through every single element in my list and test against every other element. For example, I will pick [1] and then test it against every element in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] as below…
    Is (1^2 + 1^2 )**(1/2) in any element in the string? 1.414 is not
    Is (1^2 + 2^2 )**(1/2) in any element in the string? 2.23 is not
    Is (1^2 + 3^2 )**(1/2) in any element in the string? 3.16 is not
    :
    Is (1^2 + 14^2 )**(1/2) in any element in the string? 14.035 is not
  3. Per the above none of them work, so we move to the next number [2] and test against every element. For the sake of time, none of it works for [2]. So we move to [3] …
    Is (3^2 + 1^2 )**(1/2) in any element in the string? 3.16 is not
    Is (3^2 + 2^2 )**(1/2) in any element in the string? 3.60 is not
    Is (3^2 + 3^2 )**(1/2) in any element in the string? 4.24 is not
    Is (3^2 + 4^2 )**(1/2) in any element in the string? 5 is an integer and is in the element! We need to now store these integers
  4. So from the above, we know what we need to do, the question now is can we make python do it as well? Let’s focus on the highlighted segments above.
  5. I will go through every single element in my list and test against every other element. This can be done with a classic for loop:
for i in list: # This picks one element in the list [1]
for j in list: # This then runs through all elements [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

6. Is (3^2 + 4^2 )**(1/2) in any element in the string? This can be done with an if statement. if (i**2+j**2)**(0.5) in list then append i,j and (i**2+j**2)**(0.5) to a list and return.

7. With this, we are practically done. If you can see how we arrived at this solution. We took our code in words and then started breaking it into code. This type of methodology can help you solve tough coding challenges. In fact for me personally, I cannot solve a coding challenge if I cannot first describe what I want to do with it, in words.

8. So now let’s inspect the code I provided during the quiz (which got the answer partially), and then we will look at how to make it even better. Looking at the code below, we can see several elements of what we discussed above. The answer we get for right_triangle([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]) is however [[3, 4, 5], [4, 3, 5], [5, 12, 13], [6, 8, 10], [8, 6, 10], [12, 5, 13]] versus [[3, 4, 5], [5, 12, 13], [6, 8, 10]]. Using all we have learned, can we write a word statement (forget code) to fix this problem?

def right_triangle (list_nums):    empty2 = []    num = len(list_nums)+1    listy = list(range(1,num))    for i in listy:        for j in listy:            if (i**2+j**2)**(0.5) in listy:                empty = []                y = (i**2+j**2)**(0.5)                y = round(y)                empty.append(i)                empty.append(j)                empty.append(y)                empty2.append(empty)    return empty2

9. So we can see the error, [3, 4, 5], [4, 3, 5], is repeating itself. It is essentially the same thing but re-arranged differently. So just using words, what can we do to improve our code output?

10. This is what I would say in my head “I see that the numbers are chronological. So perhaps, I could put in another condition to the if statement that forces a chronology?” Basically, i should always be less than j, if not don’t return anything. Soif (i**2+j**2)**(0.5) in listy: becomes if (i**2+j**2)**(0.5) in listy and i<j, so the new code is:

def right_triangle (list_nums):    empty2 = []    num = len(list_nums)+1    listy = list(range(1,num))    for i in listy:        for j in listy:            if (i**2+j**2)**(0.5) in listy and i<j:                 empty = []                     y = (i**2+j**2)**(0.5)                     y = round(y)                     empty.append(i)                     empty.append(j)                     empty.append(y)                     empty2.append(empty)    return empty2

11. From the above, we can see how to think through a problem by thinking about our code in words before actually coding. Hopefully you can use these tips to help you get better at coding challenges.

--

--

ofilispeaks
ofilispeaks

Written by ofilispeaks

Questioning everything since 1981...Founder of @okadabooks, author, engineer, ninja and blogger who blogs at http://ofilispeaks.com

No responses yet