Skip to content

Commit 5983259

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

File tree

2 files changed

+95
-0
lines changed

2 files changed

+95
-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: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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+
import pytest
40+
from math import isqrt
41+
42+
def sum_of_2025_numbers_with_digit_count_less_than_or_equal_to(digit_count):
43+
max = isqrt(10 ** digit_count)
44+
return sum(
45+
map(lambda tuple: tuple[2],
46+
filter(lambda tuple: tuple != None,
47+
map(extract_a_and_b,
48+
[root for root in range(2, max + 1)]))))
49+
50+
def test_sum_works_with_example():
51+
assert 5131 == sum_of_2025_numbers_with_digit_count_less_than_or_equal_to(4)
52+
# assert 587549 == sum_of_2025_numbers_with_digit_count_less_than_or_equal_to(6)
53+
# assert 176339975 == sum_of_2025_numbers_with_digit_count_less_than_or_equal_to(8)
54+
55+
@pytest.mark.skip(reason="lots of seconds to solve")
56+
def test_sum_works_with_real_number():
57+
assert 72673459417881349 == sum_of_2025_numbers_with_digit_count_less_than_or_equal_to(16)
58+
59+
def extract_a_and_b(root):
60+
square = root**2
61+
diff = square - root
62+
if diff % 9 != 0:
63+
return None
64+
str_square = str(square)
65+
for digits_in_b in range(1,9):
66+
base = 10 ** digits_in_b
67+
b = square % base
68+
if b == 0:
69+
continue
70+
a, a_remainder = divmod(diff, base - 1)
71+
if a_remainder == 0 and f'{a}{b}' == str_square:
72+
return a, b, square
73+
74+
def test_a_extracting_works():
75+
assert 8 == extract_a_and_b(9)[0]
76+
assert 20 == extract_a_and_b(45)[0]
77+
assert 30 == extract_a_and_b(55)[0]
78+
79+
def test_b_extracting_works():
80+
assert 1 == extract_a_and_b(9)[1]
81+
assert 25 == extract_a_and_b(45)[1]
82+
83+
def test_extracting_fails_when_diff_is_not_a_multiple_of_9():
84+
assert None == extract_a_and_b(8)
85+
86+
def test_extracting_fails_when_b_is_0():
87+
assert None == extract_a_and_b(10)
88+
assert None == extract_a_and_b(100)
89+
90+
def test_extracting_fails_when_b_requires_leading_zeros():
91+
assert None == extract_a_and_b(99)

0 commit comments

Comments
 (0)