The Sum Of Two Squares
January 5, 2010
If you like to program math puzzles, you probably know about Project Euler; in fact, it was that site that inspired Programming Praxis. We don’t usually do math puzzles here, because Project Euler does them better, but the occasional math puzzle can be entertaining, and lead to some fun programming. Hence, today’s exercise.
Your task is to write a function that, given a number n, finds all pairs of numbers x and y, with x ≥ y ≥ 0, such that x² + y² = n; for instance, 50 = 7² + 1² = 5² + 5², 48612265 = 6972² + 59² = 6971² + 132² = …, and 999 has no solutions. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.
I am not going to code a solution.. (It is five hours past my bedtime.)
Instead, I’ll observe that x^2 + y^2 = n is the equation for a circle, and Bresenham’s circle algorithm is a pretty quick way to iterate through the possible solutions. It’s not entirely straightforward because n = r^2 and r will generally not be an integer. I think Bresenham’s assumes r is an integer.
I’ve implemented a somehow brute force approach, but it’s surprisingly fast…
[…] Praxis – The Sum Of Two Squares By Remco Niemeijer In today’s Programming Praxis exercise we have to find all the ways a given number can be written as the sum […]
My Haskell solution (see http://bonsaicode.wordpress.com/2010/01/05/programming-praxis-the-sum-of-two-squares/ for a version with comments):
Here’s my simple niave Haskell solution using two list comprehensions :-
Sorry it’s the first time I’ve posted here so I don’t know how to get the nice formatted source listing.
Here’s one which constructs a list of pairs (x, n-x*x) for x <- [0..sqrt(n/2)] and then filters out the elements in which n-x*x is not an integer.
Hey, why didn’t sourcecode lang=”css” work?
Andrew: see http://en.support.wordpress.com/code/posting-source-code/
Jamie: I think it should be language, not lang.
A solution in Clojure. It works fine (but slowly) for large values. I’m sure there are more elegant ways of doing it.
Andrew, Jaime: I fixed your comments so the source code is properly formatted.
Here’s mine in C++…it’s somewhat bruteforce. If there are no solutions it wont give any output. Please, gimme some feedback! I’m a student that’s trying to practice/learn and get a better feel of C++. I wanna make it my goto language :D
#include
#include
using namespace std;
int main(void)
{
int n, i=0;
cout <> n;
double temp_frac, a, b;
do
{
a = pow(i,2);
b = sqrt(n-a);
if( a > n )
break;
else if( i > b )
break;
else if( modf(b, &temp_frac) == 0 )
cout << i << " , " << b << endl;
++i;
}
while(1);
return 0;
}
OH CRAP I’m so sorry for being a noob. I JUST read the “Posting Source Code” page. So sorry!!
Oh, I see. It should be “language” and not “lang”. But the HOWTO page says “lang”:
Please fix, as I’ll probably forget this by the time I go to post source code again. Thanks!
I’ve tried to pay extra attention to the boundaries of both while loops, to avoid any unnecessary iteration. I’m not convinced it’s optimal, though: I don’t particularly like the “if (y > x) break;”.
Here is a solution that only uses adds and multiply by 2 (could use a shift).
Because x >= y, decrementing x always causes a bigger change in the sum than incrementing y. So the loop in the my routine above can be shortened to:
def sumofsquares(n):
”’Generate (x,y) pairs, where x*x + y*y == n and x >= y >= 0.
Find max x, such that x*x <= n. Then loop, comparing y*y + x*x to n.
If the sum is too small, increment y; if too big, decrement x.
"sos" is the sum of the squares.
'''
x, y, sos = 0, 0, 0
while sos = y:
while sos < n:
sos += 2*y + 1
y += 1
if sos == n:
yield x,y
sos -= 2*x – 1
x -= 1
Hey guys. Was looking at this code for an example. Ended up moving on but not before porting one of the functions over to PHP. Hope someone can use eventually.
At the end of the chapter Dijkstra includes this: “Note. Obvious improvements, such as testing whether r mod 4 =3, and exploiting
the recurrence relation (x+1)^2 = x^2 + (2x +1) are left as exercises.”