# 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)

Embed on website

To embed this program on your website, copy the following code and paste it into your website's HTML: