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.  

Good luck!

This Kata is borrowed from [Project Euler #125](https://projecteuler.net/problem=125)

If you like this Kata, please try:

[Fixed length palindromes](https://www.codewars.com/kata/59f0ee47a5e12962cb0000bf)

[Divisor harmony](https://www.codewars.com/kata/59bf97cd4f98a8b1cd00007e)

Difficulty: introductory

Starter code:

def values(n):
	

Solutions:
l, m, p = [1], 10 ** 7, []
for n in range(2, int(m ** .5) + 1):
    l = [n*n + j for j in [0]+l]
    p += [int(k) for k in map(str, l[1:]) if k == k[::-1]]
p = sorted(set(p))

from bisect import bisect_left
def values(n): return bisect_left(p, n)

def values(n):
    pal = set()
    for i in range(1, int(n**0.5)):
        sos = i*i
        while sos < n:
            i += 1
            sos += i*i
            if str(sos)==str(sos)[::-1] and sos < n:
                pal.add(sos)
    return len(pal)

from bisect import bisect

is_pal = lambda s: s == s[::-1]

N, temp = 2500, set()
for x in range(1, N):
    val = x**2
    for y in range(x+1, N):
        val += y**2
        if val not in temp and is_pal(str(val)):
            temp.add(val)
result = sorted(temp)

def values(n):
    return bisect(result, n)

sumSquaresToN = lambda n: n*(n+1)*(2*n+1)//6

memo = set()

def values(n):
    lastMax = max(memo) if memo else 0
    if lastMax >= n:
        return sum( x < n for x in memo )
    
    top = int( (1 + (1+2*(n-1))**.5) // 2 )           # Value of the top number for a sum of two consecutive squares under n: (top-1)**2 + top**2 <= n    
    for a in range(top, 1, -1):
        va = sumSquaresToN(a)                         # sum of squares of 1, 2, 3, ..., a
        if va <= lastMax: break                       # va is greater than all the values generated with the inner loop, so if too small to generate new values, exit

        for b in range(a-2, -1, -1):
            v = va - sumSquaresToN(b)                 # current value
            if v >= n: break                          # going down with the values of b, v increase at each execution. Allow to exit the loop when generated values become to big (and useless for the current call)
            if v == int(str(v)[::-1]): memo.add(v)
            
    return len(memo)

found = set([5, 55, 77, 181, 313, 434, 505, 545, 595, 636, 818, 1001, 1111, 1441, 1771, 4334, 6446, 17371, 17871, 19691, 21712, 41214, 42924, 44444, 46564, 51015, 65756, 81818, 97679,
          99199, 108801, 127721, 137731, 138831, 139931, 148841, 161161, 166661, 171171, 188881, 191191, 363363, 435534, 444444, 485584, 494494, 525525, 554455, 554455, 629926, 635536,
          646646, 656656, 904409, 923329, 944449, 964469, 972279, 981189, 982289, 1077701, 1224221, 1365631, 1681861, 1690961, 1949491, 1972791, 1992991, 2176712, 2904092, 3015103, 3162613,
          3187813, 3242423, 3628263, 4211124, 4338334, 4424244, 4776774, 5090905, 5258525, 5276725, 5367635, 5479745, 5536355, 5588855, 5603065, 5718175, 5824285, 6106016, 6277726, 6523256,
          6546456, 6780876, 6831386, 6843486, 6844486, 7355537, 8424248, 9051509, 9072709, 9105019, 9313139, 9334339, 9343439, 9343439, 9435349, 9563659, 9793979, 9814189, 9838389, 9940499])

def values(n):
    return sum(i<n for i in found)



#this is how i achieved that :D
'''
#generate palindomre upto 10**digits quickly
def generate_palindromes(digits):
    batches = [None,
               [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
               [0, 11, 22, 33, 44, 55, 66, 77, 88, 99]]

    for n in range(3, digits + 1):
        batch = []
        mid = [batches[k] for k in range(1, len(batches)) if [not k & 1, k & 1][n & 1]]
        for side in range(1, 10):
            for p in mid:
                for inner in p:
                    number = str(side) + str(inner).center(n - 2, '0') + str(side)
                    batch.append(int(number))
        batches.append(batch[:])

    return sum(batches[1:], [])


x = generate_palindromes(7)
x = set(x[:10] + x[11:])

found = []
for i in range(1, 2000):
    sq = i * i
    for j in range(i + 1, 2000):
        sq += j * j
        if sq in x:
            found.append(sq)
'''

def values(high):
    s = set()
    num = 1
    while num * num < high:
        temp = num + 1
        total = num * num + temp * temp
        while total < high:
            if str(total) == str(total)[::-1]:
                s.add(total)
            temp += 1
            total += temp * temp
        num += 1
    return len(s)

found = set([5, 55, 77, 181, 313, 434, 505, 545, 595, 636, 818, 1001, 1111, 1441, 1771, 4334, 6446, 17371, 17871, 19691, 21712, 41214, 42924, 44444, 46564, 51015, 65756, 81818, 97679,
          99199, 108801, 127721, 137731, 138831, 139931, 148841, 161161, 166661, 171171, 188881, 191191, 363363, 435534, 444444, 485584, 494494, 525525, 554455, 554455, 629926, 635536,
          646646, 656656, 904409, 923329, 944449, 964469, 972279, 981189, 982289, 1077701, 1224221, 1365631, 1681861, 1690961, 1949491, 1972791, 1992991, 2176712, 2904092, 3015103, 3162613,
          3187813, 3242423, 3628263, 4211124, 4338334, 4424244, 4776774, 5090905, 5258525, 5276725, 5367635, 5479745, 5536355, 5588855, 5603065, 5718175, 5824285, 6106016, 6277726, 6523256,
          6546456, 6780876, 6831386, 6843486, 6844486, 7355537, 8424248, 9051509, 9072709, 9105019, 9313139, 9334339, 9343439, 9343439, 9435349, 9563659, 9793979, 9814189, 9838389, 9940499])

def values(n):
    return sum(i<n for i in found)

def values(limit):
    palindromes = set()
    for sequence_item in range(1, int(limit**0.5)):
        squares_sum = sequence_item**2
        while squares_sum < limit:
            sequence_item += 1
            squares_sum += sequence_item**2
            if str(squares_sum)==str(squares_sum)[::-1] and squares_sum < limit:
                palindromes.add(squares_sum)
    return len(palindromes)

def values(n):
    p = set()
    for i in range(1, int(n**0.5)):
        q = i*i
        while q < n:
            i=i+ 1
            q =q+ i*i
            if str(q)==str(q)[::-1] and q < n:
                p.add(q)
    return len(p)

def values(limit):
    def is_palindrome(n):
        n = str(n)
        if len(n) in [0, 1]:
            return True
        return n[0] == n[-1] and is_palindrome(n[1:-1])

    print("Limit: {}".format(limit))
    current = 2
    totals = [1]
    list_pal = []
    while True:
        number = current ** 2 + totals[-1]
        totals = [i for i in totals if number - i < limit]
        if len(totals) == 1 and totals != [1]:
            break
        for i in totals[:-1]:
            if is_palindrome(number - i) and not (number - i) in list_pal and limit > (number - i):
                list_pal.append(number - i)
        if is_palindrome(number) and not number in list_pal and limit > number:
            list_pal.append(number)
        totals.append(number)
        current += 1
    print("Number of Palindrome in list: {}".format(len(list_pal)))
    print("List of Palindrome: {}".format(list_pal))
    return len(list_pal)