4.37 Exercise 4.37
Consider the two following procedures for computing Pythagorean triples with high and low bounds:
(define (a-pythagorean-triple-between low high) (let ((i (an-integer-between low high))) (let ((j (an-integer-between i high))) (let ((k (an-integer-between j high))) (require (= (+ (* i i) (* j j)) (* k k))) (list i j k)))))
(define (a-pythagorean-triple-between low high) (let ((i (an-integer-between low high)) (hsq (* high high))) (let ((j (an-integer-between i high))) (let ((ksq (+ (* i i) (* j j)))) (require (>= hsq ksq)) (let ((k (sqrt ksq))) (require (integer? k)) (list i j k))))))
The former method is naive and straightforward, iterating through all of the possibilities for i, j, and k and testing whether the equality holds. This is very inefficient, requiring on the order of O(n^3) operations.
The alternative solution is more clever. First, it acts on the fact that it isn’t necessary to test more than a single potential k value after i and j are fixed – there’s only one sum to their squares, and the square root of that is either an integer or not. Doing this cuts a power of n off of the time complexity.
However, in order for this to work, you need to know when to stop testing values. However, this is also easily done – we know that the maximum value of k cannot be greater than the square root of the high bound. Alternatively, as expressed in the algorithm above, k^2 cannot be greater than high^2. (My only complaint about the above is that I would calculate hsq before i). Then, all that needs to be done is checking whether the potential k^2 values are no greater than this upper bound.
We can see that the second algorithm does test every valid i and j, and that this means that all possible triples with i and j within bounds are checked. We can also see that no possible triples outside of the bounds will be considered – any value of k such that k^2 is greater than high^2 is not accepted. Therefore, we can trust that the second algorithm is correct, while also being significantly more efficient than the first.