Skip to content

Commit 84cd5f8

Browse files
Solve PE 932: 2025
1 parent 6c001d0 commit 84cd5f8

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,7 @@
55
</div>
66

77
# [Project Euler](https://projecteuler.net)
8+
9+
- [required] pdm <https://github.com/pdm-project/pdm>
10+
- `pdm install`
11+
- `pdm test`

project_euler/test_pe932_2025.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# <https://projecteuler.net/problem=932>
2+
# <p>For the year $2025$</p>
3+
# $$2025 = (20 + 25)^2$$
4+
# <p>Given positive integers $a$ and $b$, the concatenation $ab$ we call a $2025$-number if $ab = (a+b)^2$.<br>
5+
# Other examples are $3025$ and $81$.<br>
6+
# Note $9801$ is not a $2025$-number because the concatenation of $98$ and $1$ is $981$.</p>
7+
#
8+
# <p>
9+
# Let $T(n)$ be the sum of all $2025$-numbers with $n$ digits or less. You are given $T(4) = 5131$.</p>
10+
#
11+
# <p>
12+
# Find $T(16)$.</p>
13+
#
14+
# Notes:
15+
# - 0 does not count of b, 100 being (10 + 0)^2 is not included
16+
# - Iterating over the roots from 2 to 10**8 should work
17+
18+
# Fiddling with math
19+
# - Let x be the square number (eg: 2025)
20+
# - Let y be the root of a square y (eg: 45)
21+
# - Let a be the left hand side of the root sum (eg: 20)
22+
# - Let b be the right hand side of the root sum (eg: 25)
23+
# - Given x = y^2
24+
# - Given y = a + b
25+
# - Given $"($a)($b)" == $"($y)"
26+
# - The number of decimal digits in a number is floor(log b) + 1
27+
# - Let digit_count_of(n): floor(log n) + 1
28+
# - Then x = a*10^digit_count_of(b) + b
29+
# - So b = x - a*10^digit_count_of(b)
30+
# - Substituting gives y = a + x - a*10^digit_count_of(b)
31+
# - y - x = a - a*10^digit_count_of(b)
32+
# - x - y = a*10^digit_count_of(b) - a
33+
# - x - y = a(10^digit_count_of(b) - 1)
34+
# - a = (x - y) / (10^digit_count_of(b) - 1)
35+
# - Since the digit count of b must be a whole number, 10^digit_count_of(b) - 1 must be 1 less than a power of ten
36+
# - x - y must be divisible by 9 or 99 or 999 etc
37+
# - Therefore x - y must be divisible by 9
38+
39+
from math import isqrt
40+
41+
def sum_of_2025_numbers_with_digit_count_less_than_or_equal_to(digit_count):
42+
max = isqrt(10 ** digit_count)
43+
return sum(
44+
map(lambda tuple: tuple[2],
45+
filter(lambda tuple: tuple != None,
46+
map(extract_a_and_b,
47+
[root for root in range(2, max + 1)]))))
48+
49+
def test_sum_works_with_example():
50+
assert 5131 == sum_of_2025_numbers_with_digit_count_less_than_or_equal_to(4)
51+
# assert 587549 == sum_of_2025_numbers_with_digit_count_less_than_or_equal_to(6)
52+
# assert 176339975 == sum_of_2025_numbers_with_digit_count_less_than_or_equal_to(8)
53+
54+
@pytest.mark.skip(reason="lots of seconds to solve")
55+
def test_sum_works_with_real_number():
56+
assert 72673459417881349 == sum_of_2025_numbers_with_digit_count_less_than_or_equal_to(16)
57+
58+
def extract_a_and_b(root):
59+
square = root**2
60+
diff = square - root
61+
if diff % 9 != 0:
62+
return None
63+
str_square = str(square)
64+
for digits_in_b in range(1,9):
65+
base = 10 ** digits_in_b
66+
b = square % base
67+
if b == 0:
68+
continue
69+
a, a_remainder = divmod(diff, base - 1)
70+
if a_remainder == 0 and f'{a}{b}' == str_square:
71+
return a, b, square
72+
73+
def test_a_extracting_works():
74+
assert 8 == extract_a_and_b(9)[0]
75+
assert 20 == extract_a_and_b(45)[0]
76+
assert 30 == extract_a_and_b(55)[0]
77+
78+
def test_b_extracting_works():
79+
assert 1 == extract_a_and_b(9)[1]
80+
assert 25 == extract_a_and_b(45)[1]
81+
82+
def test_extracting_fails_when_diff_is_not_a_multiple_of_9():
83+
assert None == extract_a_and_b(8)
84+
85+
def test_extracting_fails_when_b_is_0():
86+
assert None == extract_a_and_b(10)
87+
assert None == extract_a_and_b(100)
88+
89+
def test_extracting_fails_when_b_requires_leading_zeros():
90+
assert None == extract_a_and_b(99)

0 commit comments

Comments
 (0)