Skip to content

Commit d8ddb07

Browse files
BEASTSHRIRAMalxkm
andauthored
Added Sum of Squares Lagrange's Four Square algorithm implementation (#6583)
* Add Sum of Squares algorithm implementation * Format code and add Wikipedia URL for Lagrange's theorem * Fixed clang-format issues --------- Co-authored-by: Oleksandr Klymenko <[email protected]>
1 parent 15695c6 commit d8ddb07

File tree

2 files changed

+121
-0
lines changed

2 files changed

+121
-0
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.thealgorithms.maths;
2+
3+
/**
4+
* Implementation of Lagrange's Four Square Theorem
5+
* Find minimum number of perfect squares that sum to given number
6+
*
7+
* @see <a href="https://en.wikipedia.org/wiki/Lagrange%27s_four-square_theorem">Lagrange's Four Square Theorem</a>
8+
* @author BEASTSHRIRAM
9+
*/
10+
public final class SumOfSquares {
11+
12+
private SumOfSquares() {
13+
// Utility class
14+
}
15+
16+
/**
17+
* Find minimum number of perfect squares that sum to n
18+
*
19+
* @param n the target number
20+
* @return minimum number of squares needed
21+
*/
22+
public static int minSquares(int n) {
23+
if (isPerfectSquare(n)) {
24+
return 1;
25+
}
26+
27+
for (int i = 1; i * i <= n; i++) {
28+
int remaining = n - i * i;
29+
if (isPerfectSquare(remaining)) {
30+
return 2;
31+
}
32+
}
33+
34+
// Legendre's three-square theorem
35+
int temp = n;
36+
while (temp % 4 == 0) {
37+
temp /= 4;
38+
}
39+
if (temp % 8 == 7) {
40+
return 4;
41+
}
42+
43+
return 3;
44+
}
45+
46+
private static boolean isPerfectSquare(int n) {
47+
if (n < 0) {
48+
return false;
49+
}
50+
int root = (int) Math.sqrt(n);
51+
return root * root == n;
52+
}
53+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package com.thealgorithms.maths;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
5+
import org.junit.jupiter.api.Test;
6+
7+
/**
8+
* Test class for SumOfSquares
9+
*
10+
* @author BEASTSHRIRAM
11+
*/
12+
class SumOfSquaresTest {
13+
14+
@Test
15+
void testPerfectSquares() {
16+
// Perfect squares should return 1
17+
assertEquals(1, SumOfSquares.minSquares(1)); // 1^2
18+
assertEquals(1, SumOfSquares.minSquares(4)); // 2^2
19+
assertEquals(1, SumOfSquares.minSquares(9)); // 3^2
20+
assertEquals(1, SumOfSquares.minSquares(16)); // 4^2
21+
assertEquals(1, SumOfSquares.minSquares(25)); // 5^2
22+
}
23+
24+
@Test
25+
void testTwoSquares() {
26+
// Numbers that can be expressed as sum of two squares
27+
assertEquals(2, SumOfSquares.minSquares(2)); // 1^2 + 1^2
28+
assertEquals(2, SumOfSquares.minSquares(5)); // 1^2 + 2^2
29+
assertEquals(2, SumOfSquares.minSquares(8)); // 2^2 + 2^2
30+
assertEquals(2, SumOfSquares.minSquares(10)); // 1^2 + 3^2
31+
assertEquals(2, SumOfSquares.minSquares(13)); // 2^2 + 3^2
32+
}
33+
34+
@Test
35+
void testThreeSquares() {
36+
// Numbers that require exactly three squares
37+
assertEquals(3, SumOfSquares.minSquares(3)); // 1^2 + 1^2 + 1^2
38+
assertEquals(3, SumOfSquares.minSquares(6)); // 1^2 + 1^2 + 2^2
39+
assertEquals(3, SumOfSquares.minSquares(11)); // 1^2 + 1^2 + 3^2
40+
assertEquals(3, SumOfSquares.minSquares(12)); // 2^2 + 2^2 + 2^2
41+
assertEquals(3, SumOfSquares.minSquares(14)); // 1^2 + 2^2 + 3^2
42+
}
43+
44+
@Test
45+
void testFourSquares() {
46+
// Numbers that require exactly four squares (form 4^a * (8b + 7))
47+
assertEquals(4, SumOfSquares.minSquares(7)); // 1^2 + 1^2 + 1^2 + 2^2
48+
assertEquals(4, SumOfSquares.minSquares(15)); // 1^2 + 1^2 + 2^2 + 3^2
49+
assertEquals(4, SumOfSquares.minSquares(23)); // 1^2 + 1^2 + 3^2 + 3^2
50+
assertEquals(4, SumOfSquares.minSquares(28)); // 4 * 7, so needs 4 squares
51+
assertEquals(4, SumOfSquares.minSquares(31)); // 1^2 + 2^2 + 3^2 + 3^2
52+
}
53+
54+
@Test
55+
void testLargerNumbers() {
56+
// Test some larger numbers
57+
assertEquals(1, SumOfSquares.minSquares(100)); // 10^2
58+
assertEquals(2, SumOfSquares.minSquares(65)); // 1^2 + 8^2
59+
assertEquals(3, SumOfSquares.minSquares(19)); // 1^2 + 3^2 + 3^2
60+
assertEquals(4, SumOfSquares.minSquares(60)); // 4 * 15, and 15 = 8*1 + 7
61+
}
62+
63+
@Test
64+
void testEdgeCases() {
65+
// Test edge case
66+
assertEquals(1, SumOfSquares.minSquares(0)); // 0^2
67+
}
68+
}

0 commit comments

Comments
 (0)