Palindrome Integer Composition in Java


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));   
    }
}