The challenge
The palindromic number 595
is interesting because it can be written as the sum of consecutive squares: 6^2 + 7^2 + 8^2 + 9^2 + 10^2 + 11^2 + 12^2 = 595
.
There are exactly eleven palindromes below one-thousand that can be written as consecutive square sums. Note that 1 = 0^2 + 1^2
has not been included as this problem is concerned with the squares of positive integers.
Given an input n
, find the count of all the numbers less than n
that are both palindromic and can be written as the sum of consecutive squares.
For instance: values(1000) = 11
. See test examples for more cases.
The solution in Java code
Option 1:
import java.util.*;
class Solution{
public static int values (int n){
Set<Integer> palindroms = new HashSet<Integer>();
for(int i = 1; isTwoPowResult(i, n); i++) {
int sum = (i * i);
for(int j = i + 1; ; j++) {
sum += (j * j);
if(sum >= n) break;
StringBuilder builder = new StringBuilder(Integer.toString(sum));
if(new String(builder).equals(new String(builder.reverse()))) {
palindroms.add(sum);
}
}
}
return palindroms.size();
}
public static boolean isTwoPowResult(int index, int n) {
return ((int) Math.pow(index, 2) + ((int) Math.pow(++index, 2))) <= n;
}
}
Option 2:
import java.util.ArrayList;
import java.util.HashSet;
class Solution{
public static int values (int n){
ArrayList<Integer> arrSq = new ArrayList<>();
HashSet<Integer> set = new HashSet<>();
arrSq.add(1);
for (int sq = 2; arrSq.get(arrSq.size()-1)+arrSq.get(arrSq.size()-1) < n; sq++) {
arrSq.add(sq * sq);
}
for (int i = 0; i != arrSq.size(); i++){
int sum = arrSq.get(i);
for(int j = i+1; j != arrSq.size(); j++){
sum = sum + arrSq.get(j);
if (String.valueOf(sum).equals(String.valueOf(new StringBuilder(String.valueOf(sum)).reverse())) && sum < n){
set.add(sum);
}
}
}
return set.size();
}
}
Option 3:
import java.util.*;
import java.util.stream.*;
class Solution{
public static int values (int n){
var arrSq = IntStream.rangeClosed(1, ((int)(Math.sqrt(n))))
.map(i->i*i)
.toArray();
long tmp = 0;
Set<Long> set = new HashSet<>();
for(int i = 0; i < arrSq.length; i++){
tmp = arrSq[i];
for(int j = i+1; j < arrSq.length; j++){
tmp += arrSq[j];
if(tmp >= n)
continue;
if(isPalindrome(tmp)){
set.add(tmp);
}
}
}
return set.size();
}
private static boolean isPalindrome(long n) {
if(n / 10 == 0) return true;
var a = String.valueOf(n).getBytes();
for(int i = 0; i < a.length / 2; i++){
if(a[i] != a[(a.length-1)-i])
return false;
}
return true;
}
}
Test cases to validate our solution
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.junit.runners.JUnit4;
public class SolutionTest{
@Test
public void basicTests(){
assertEquals(3, Solution.values(100));
assertEquals(4, Solution.values(200));
assertEquals(4, Solution.values(300));
assertEquals(5, Solution.values(400));
assertEquals(11, Solution.values(1000));
}
}