def number2digits(long n) {
def result = []
for(/**/; n > 0; n /= 10) {
result.add(0, n % 10)
}
return (result) ? result : [0]
}
assert number2digits
(123) == [1, 2, 3]
def digits2number(digits) {
return digits.inject(0l) { a, b -> a*10 + b }
}
assert digits2number
([1, 2, 3]) == 123
def createPalindrome(long palindromeBeginning, boolean doubleDigitInMiddle) {
def palindromeBeginningDigits = number2digits(palindromeBeginning)
def palindromeEndingDigits = palindromeBeginningDigits.reverse()
if (!doubleDigitInMiddle) {
palindromeEndingDigits = palindromeEndingDigits.tail()
}
return digits2number(palindromeBeginningDigits + palindromeEndingDigits)
}
assert createPalindrome
(123, false) == 12321 assert createPalindrome
(123, true) == 123321
COUNTER = 0
def findNDigitsDivisorPair(long x, int N) {
int MAX_DIVISOR = 10**N - 1
int MIN_DIVISOR = 10**(N-1)
int squareRoot
= Math.
sqrt(x
) if (MIN_DIVISOR <= squareRoot && squareRoot <= MAX_DIVISOR) {
int lowerDivisorBound = Math.max(x / MAX_DIVISOR as int, MIN_DIVISOR);
for (int i = lowerDivisorBound; i <= squareRoot; ++i) {
double quotient = (x as double) / i
++COUNTER
//println "$x / $i = $quotient"
if (quotient % 1 == 0) return [i, quotient as int]
}
}
return null
}
assert findNDigitsDivisorPair
(143, 2) == [11, 13]
def findBiggestDivisiblePalindrome(digitsCount) {
for (int begin = 10**digitsCount - 1; begin >= 10**(digitsCount-1); --begin) {
long palindrome = createPalindrome(begin, true)
def solution = findNDigitsDivisorPair(palindrome, digitsCount)
if (solution) {
println "Number of checks = " + COUNTER
println "$palindrome = ${solution[0]} * ${solution[1]}"
return palindrome
}
}
}
//assert findBiggestDivisiblePalindrome(9) = 999996100001699999
def start = new Date().getTime()
findBiggestDivisiblePalindrome(3)
println "Execution time: ${new Date().getTime() - start} ms"
ZGVmIG51bWJlcjJkaWdpdHMobG9uZyBuKSB7CiAgICBkZWYgcmVzdWx0ID0gW10KICAgIGZvcigvKiovOyBuID4gMDsgbiAvPSAxMCkgewogICAgICAgIHJlc3VsdC5hZGQoMCwgbiAlIDEwKQogICAgfQogICAgcmV0dXJuIChyZXN1bHQpID8gcmVzdWx0IDogWzBdCn0KYXNzZXJ0IG51bWJlcjJkaWdpdHMoMTIzKSA9PSBbMSwgMiwgM10KCmRlZiBkaWdpdHMybnVtYmVyKGRpZ2l0cykgewogICAgcmV0dXJuIGRpZ2l0cy5pbmplY3QoMGwpIHsgYSwgYiAtPiBhKjEwICsgYiB9Cn0KYXNzZXJ0IGRpZ2l0czJudW1iZXIoWzEsIDIsIDNdKSA9PSAxMjMKCmRlZiBjcmVhdGVQYWxpbmRyb21lKGxvbmcgcGFsaW5kcm9tZUJlZ2lubmluZywgYm9vbGVhbiBkb3VibGVEaWdpdEluTWlkZGxlKSB7CiAgICBkZWYgcGFsaW5kcm9tZUJlZ2lubmluZ0RpZ2l0cyA9IG51bWJlcjJkaWdpdHMocGFsaW5kcm9tZUJlZ2lubmluZykKICAgIGRlZiBwYWxpbmRyb21lRW5kaW5nRGlnaXRzID0gcGFsaW5kcm9tZUJlZ2lubmluZ0RpZ2l0cy5yZXZlcnNlKCkKICAgIGlmICghZG91YmxlRGlnaXRJbk1pZGRsZSkgewogICAgICAgIHBhbGluZHJvbWVFbmRpbmdEaWdpdHMgPSBwYWxpbmRyb21lRW5kaW5nRGlnaXRzLnRhaWwoKQogICAgfQogICAgcmV0dXJuIGRpZ2l0czJudW1iZXIocGFsaW5kcm9tZUJlZ2lubmluZ0RpZ2l0cyArIHBhbGluZHJvbWVFbmRpbmdEaWdpdHMpCn0KYXNzZXJ0IGNyZWF0ZVBhbGluZHJvbWUoMTIzLCBmYWxzZSkgPT0gMTIzMjEKYXNzZXJ0IGNyZWF0ZVBhbGluZHJvbWUoMTIzLCB0cnVlKSA9PSAxMjMzMjEKCkNPVU5URVIgPSAwCgpkZWYgZmluZE5EaWdpdHNEaXZpc29yUGFpcihsb25nIHgsIGludCBOKSB7CiAgICBpbnQgTUFYX0RJVklTT1IgPSAxMCoqTiAtIDEKICAgIGludCBNSU5fRElWSVNPUiA9IDEwKiooTi0xKQogICAgaW50IHNxdWFyZVJvb3QgPSBNYXRoLnNxcnQoeCkKICAgIGlmIChNSU5fRElWSVNPUiA8PSBzcXVhcmVSb290ICYmIHNxdWFyZVJvb3QgPD0gTUFYX0RJVklTT1IpIHsKICAgICAgICBpbnQgbG93ZXJEaXZpc29yQm91bmQgPSBNYXRoLm1heCh4IC8gTUFYX0RJVklTT1IgYXMgaW50LCBNSU5fRElWSVNPUik7CiAgICAgICAgZm9yIChpbnQgaSA9IGxvd2VyRGl2aXNvckJvdW5kOyBpIDw9IHNxdWFyZVJvb3Q7ICsraSkgewogICAgICAgICAgICBkb3VibGUgcXVvdGllbnQgPSAoeCBhcyBkb3VibGUpIC8gaQogICAgICAgICAgICArK0NPVU5URVIKICAgICAgICAgICAgLy9wcmludGxuICIkeCAvICRpID0gJHF1b3RpZW50IgogICAgICAgICAgICBpZiAocXVvdGllbnQgJSAxID09IDApIHJldHVybiBbaSwgcXVvdGllbnQgYXMgaW50XQogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBudWxsCn0KYXNzZXJ0IGZpbmRORGlnaXRzRGl2aXNvclBhaXIoMTQzLCAyKSA9PSBbMTEsIDEzXQoKZGVmIGZpbmRCaWdnZXN0RGl2aXNpYmxlUGFsaW5kcm9tZShkaWdpdHNDb3VudCkgewogICAgZm9yIChpbnQgYmVnaW4gPSAxMCoqZGlnaXRzQ291bnQgLSAxOyBiZWdpbiA+PSAxMCoqKGRpZ2l0c0NvdW50LTEpOyAtLWJlZ2luKSB7CiAgICAgICAgbG9uZyBwYWxpbmRyb21lID0gY3JlYXRlUGFsaW5kcm9tZShiZWdpbiwgdHJ1ZSkKICAgICAgICBkZWYgc29sdXRpb24gPSBmaW5kTkRpZ2l0c0Rpdmlzb3JQYWlyKHBhbGluZHJvbWUsIGRpZ2l0c0NvdW50KQogICAgICAgIGlmIChzb2x1dGlvbikgewogICAgICAgICAgICBwcmludGxuICJOdW1iZXIgb2YgY2hlY2tzID0gIiArIENPVU5URVIKICAgICAgICAgICAgcHJpbnRsbiAiJHBhbGluZHJvbWUgPSAke3NvbHV0aW9uWzBdfSAqICR7c29sdXRpb25bMV19IgogICAgICAgICAgICByZXR1cm4gcGFsaW5kcm9tZQogICAgICAgIH0KICAgIH0gICAgCn0KLy9hc3NlcnQgZmluZEJpZ2dlc3REaXZpc2libGVQYWxpbmRyb21lKDkpID0gOTk5OTk2MTAwMDAxNjk5OTk5CgpkZWYgc3RhcnQgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKQpmaW5kQmlnZ2VzdERpdmlzaWJsZVBhbGluZHJvbWUoMykKcHJpbnRsbiAiRXhlY3V0aW9uIHRpbWU6ICR7bmV3IERhdGUoKS5nZXRUaW1lKCkgLSBzdGFydH0gbXMiCg==