# import heapq as hq
# def solve(a, b):
# seen = set([(b, b)])
# q = [(-b * b, b, b)]
# hq.heapify(q)
# while q:
# p, x, y = hq.heappop(q)
# s = str(-p)
# if s == s[::-1]:
# return (-p, x, y)
# for u, v in ((x - 1, y + 1), (x + 1, y - 1), (x - 1, y), (x, y - 1)):
# if not (u, v) in seen and a <= u <= v <= b:
# hq.heappush(q, (-u * v, u, v))
# seen.add((u, v))
import math
def solve(a, b):
def largest_palindrome_leq(n):
"""Return the largest palindrome ≤ n, in O(digits) time."""
s = str(n)
d = len(s)
h = (d + 1) // 2 # controlling half-length = ⌈d/2⌉
fh = list(s[:h])
# Candidate: mirror the first half
if d % 2 == 0:
candidate = int(''.join(fh + fh[::-1]))
else:
candidate = int(''.join(fh + fh[-2::-1]))
if candidate <= n:
return candidate
# candidate > n: decrement the controlling half by 1
i = h - 1
while i >= 0 and fh[i] == '0':
fh[i] = '9'
i -= 1
if i < 0:
return 0
fh[i] = str(int(fh[i]) - 1)
if fh[0] == '0': # digit count shrank
return int('9' * (d - 1)) if d > 1 else 0
if d % 2 == 0:
return int(''.join(fh + fh[::-1]))
else:
return int(''.join(fh + fh[-2::-1]))
p = largest_palindrome_leq(b * b)
floor = a * a # no palindrome below a² can be a valid product
while p >= floor:
# Valid x must lie in [lo, hi] — often a very small range
lo = max(a, -(-p // b)) # max(a, ⌈p/b⌉) guarantees y = p/x ≤ b
hi = min(math.isqrt(p), p // a) # ⌊√p⌋ guarantees x ≤ y
# p//a guarantees y = p/x ≥ a
for x in range(lo, hi + 1):
if p % x == 0:
return (p, x, p // x) # all constraints met by construction
p = largest_palindrome_leq(p - 1)
return None
# --- tests ---
print(solve(545358, 546424)) # (297996699792, 545358, 546424)
print(solve(513241, 546574)) # (297996699792, 545358, 546424)
print(solve(100, 999)) # (906609, 913, 993) classic
a, b = 513241, 546574
r = solve(a, b)
print(r) # = > (297996699792, 545358, 546424)
To embed this program on your website, copy the following code and paste it into your website's HTML: