It’s been a while since I’d worked on a problem, so I decided to pull one out. Figured that given how much time has passed since I last completed one, there’ll be a couple easy problems to tackle, this being one of them.
The trick here, that felt like it took me way to long to get to, is to only search through the square numbers. For some reason I was trying to search through all numbers below \(10^16\) which clearly won’t work. I also noticed that the splits in the numbers was always as close to the middle as possible, with the right side potentially getting the longer number. With those two pieces of knowledge, it was easy to loop through all squares, split them down the middle, and check the math.
Runs in less than 5 seconds with Pypy v3.10.13 on my macbook air.
def solve(n):
total = sqr = num = 0
while num < 10 ** n:
sqr += 1
num = sqr ** 2
snum = str(num)
alen = len(snum) // 2
if alen < 1:
continue
a = int(str(num)[:alen])
bstr = str(num)[alen:]
if bstr.startswith('0'):
continue
b = int(bstr)
if a + b == sqr:
total += num
return total
if __name__ == '__main__':
import sys
n = eval(sys.argv[1])
print(solve(n))
import pytest
from problem import solve
_test_solve = (
(4, 5131),
(5, 93340),
(6, 587549),
(7, 12971262),
(8, 176339975),
(9, 970971595),
(10, 13852403215),
)
@pytest.mark.parametrize('n,expect', _test_solve)
def test_solve(n, expect):
assert expect == solve(n)