tinylisp, 125 117117 109 bytes
(d QX(q((N I)(i(l N 1)(e N 0)(QX(s N I)(a I 2
(d S(q((I N)(i(e(a(Q(s NX I) 1)(QX(s IN 1I)1)2)1(i(l N I)0(S(a I 1)N))1
(q((N)(S 0 N
The last line is an anonymous function that takes a number and returns 1 if it is the sum of two squares, 0 otherwise. Try it online!Try it online!
First, we define a helper function QX
that determines whethertakes a number N
and determines if it is (not) a square. Since we only have builtins for addition and subtraction, we'll use the property of squares that they areA perfect square is the sum of consecutive odd numbers. In other wordsnumbers; therefore, subtracting the sum of the first several odd numbers from N
(for an appropriate value of "several") will result in 0 if N
is square. Thus, we recurse over increasingly large odd numbers (which we track as I
) and subtract each one from N
until N
equals 0 (in which case N
is square) or N
is less than 0 (in which case N
is not square):
(def not-square? ; Define not-square?
(lambda (N I) ; as a function of two arguments:
(if (less? N 1) ; If N is less than 1,
(equal? N 0) ; return 1N if(0 Nif equalssquare, 0negative andif 0not otherwisesquare)
(not-square? ; Else, recurse with these arguments:
(sub2 N I) ; New N is previous N minus current odd number
(add2 I 2))))) ; New I is the next odd number
Next, we'll define a function S
that determines whether a number N
is the sum of two squares. Our algorithm here is to recurse over integers I
starting at 0: if N
minus I
is not square, andor IN
is also square, thenminus NI
is the sum of two squares; otherwisenot square, try the next I
until N
is less than I
, at which point N
cannot be the sum of two squares. On the other hand, if I
and N
minus I
are both square, then N
is the sum of two squares.
(def sum-squares? ; Define sum-squares?
(lambda (I N) ; as a function of two arguments:
(if ; If
(add2 ; If the sum of
(equalnot-square? 2 ; 0 if
(sub2 N I) ; 2 equalsN minus I
(add2 1) ; ; is square, the< sum0 ofotherwise
(square? (sub2 N I) 1) ; test if N minus I is a square
; and
(not-square? I 1))) ; and test0 if I is a square
, < 0 otherwise
1 ; thenis returntruthy 1(nonzero), then:
(if (less? N I) ; Else, ifIf N is less than I
0 ; then return 0
(sum-squares? ; Else, recurse with these arguments:
(add2 I 1) ; New I is the next integer
N))))) ; Same N
1 ; Else (I Sameand N minus I are both square), return 1