Find the largest palindrome made from the product of two 3-digit numbers - Javascript

前端 未结 21 1222
感情败类
感情败类 2020-12-28 17:16

Can anyone tell me what\'s wrong with the code. Find the largest palindrome made from the product of two 3-digit numbers.

function largestPalind         


        
相关标签:
21条回答
  • 2020-12-28 17:41

    Swift 3:

    // my approach is to make 6-digit palindrome first and then 
    // check if I can divide it by 3-digit number 
    // (you can see some visual listing at the end of the code)
    // execution time on my laptop is around: 2.75409698486328 sec
    
    import Foundation
    
    func maxPalindrom() -> Int {
    
        var result = 999999
        var i = 9
        var j = 9
        var k = 9
    
        while true {
            while true {
                while true {
                    print("in K loop: \(result) k = \(k)")
    
                    if isDivisible(number: result) {
                        return result
                    }
                    if k <= 0 {
                        k = 9
                        result += 9900
                        break
                    }
                    result -= 1100
                    k -= 1
                }
    
                print("in J loop: \(result)")
                if isDivisible(number: result) {
                    return result
                }
                if j < 0 {
                    j = 9
                    result += 90090
                    break
                }
                result -= 10010
                j -= 1
            }
    
            print("in I loop: \(result)")
            if isDivisible(number: result) {
                return result
            }
            if i < 0 {
                break
            }
            result -= 100001
            i -= 1
        }
    
        if result == 100001 {
            return -1
        }
    
        return -1
    }
    
    
    func isDivisible(number: Int) -> Bool {
        var i = 999
    
        while true {
    
            if number % i == 0 && number / i < 999 {
                return true
            }
    
            if i < 500 {
                return false
            }
    
            i -= 1
        }
    
    }
    
    
    let start = NSDate()
    print(maxPalindrom())       // 906609
    let end = NSDate()
    
    print("executio time: \(end.timeIntervalSince(start as Date)) sec") // ~ execution time: 2.75409698486328 sec
    
    //in K loop: 999999 k = 9
    //in K loop: 998899 k = 8
    //in K loop: 997799 k = 7
    //in K loop: 996699 k = 6
    //in K loop: 995599 k = 5
    //in K loop: 994499 k = 4
    //in K loop: 993399 k = 3
    //in K loop: 992299 k = 2
    //in K loop: 991199 k = 1
    //in K loop: 990099 k = 0
    //in J loop: 999999
    //in K loop: 989989 k = 9
    //in K loop: 988889 k = 8
    //in K loop: 987789 k = 7
    //in K loop: 986689 k = 6
    //in K loop: 985589 k = 5
    //in K loop: 984489 k = 4
    //in K loop: 983389 k = 3
    .....
    
    0 讨论(0)
  • 2020-12-28 17:42

    The above solution will work perfectly fine but we will have issue ONLY when we try to find-out what are those 2 numbers (i = 913 and j = 993)

    I will just modify the solution proposed by Azder

    int max = 0;
    int no1 = 0;
    int no2 = 0;
    
    // not using i >= 100 since 100*100 is not palindrome! :)
    for (var i = 999; i > 100; i--) {
        // because i * j === j * i, no need of both i and j
        // to count down from 999
        for (var j = i; j > 100; j--) {
            var mul = j * i;
            if (isPalin(mul)) {
                if ((i+j) > max) {
                   max = i+j;
                   no1 = i; no2 = j;
                }
            }
        }
    }
    
    //Now we can get the 2 numbers (no1=993 and no2=913)
    
    return (no1*no2);
    
    0 讨论(0)
  • 2020-12-28 17:44

    I believe this should be optimal

    #include <functional>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    template <typename T>
    bool IsPalindrome(const T num) {
        T reverse = 0;
        T n = num;
        while (n > 0) {
            reverse = (reverse * 10) + n % 10;
            n /= 10;
        }
        return reverse == num;
    }
    
    
    template <typename T = long long int>
    T LongestPalindromeFromProductOfNDigitNums(int n) {
        T result = 0, val = 0, max_n_digit_num = std::pow(10, n)-1,
        least_n_digit_num = std::pow(10, n-1);
        int n_checks = 0;
        for (T i = max_n_digit_num; i >= least_n_digit_num; --i) {
            if ((i*i) < result) {//found the highest palindrome
                break;
            }
            for (T j = i; j >= least_n_digit_num; --j) {
                val = i*j;
                ++n_checks;
                if (val < result) // any product i*j for the value of 'j' after this will be less than result
                    break;
                if (IsPalindrome(val)) {
                    if (val > result)
                        result = val;
                    break;  // whenever a palindrome is found break since we only need highest one
                }
            }
        }
        std::cout << " Total num of checks = " << n_checks << std::endl;
        return result;
    }
    
    int main() {
        int n = 3;
        std::cout << " LongestPalindromeFromProductOfNDigitNums for n = "
        << n << " is " << LongestPalindromeFromProductOfNDigitNums(n) << std::endl;
        n = 4;
        std::cout << " LongestPalindromeFromProductOfNDigitNums for n = "
        << n << " is " << LongestPalindromeFromProductOfNDigitNums(n) << std::endl;
        return 0;
    }
    

    http://ideone.com/WoNSJP

    0 讨论(0)
  • 2020-12-28 17:45

    As explained in @VisioN's comment:

    995*583 = 580085 is a palindrome.

    993*913 = 906609 is also a (larger) palindrome.

    Your code checks 995*583 before 993*913 and exits at the first palindrome found, so it doesn't return the largest palindrome.

    Solution: get the largest palindromes starting from 999*999 = 998001 downwards and check if they can be written as xyz*abc.

    Or simply use the accepted solution from the question you linked :). Your solution, but instead of returning when you find the first palindrome, check if it is larger than the largest one already found, in which case you need to replace it. You can stop as soon as the largest palindrome is larger than i*999.

    0 讨论(0)
  • 2020-12-28 17:46

    I think if you apply maths to the problem you can decrease the guesswork really significantly.

    I will write the three digit numbers as 1000 - a and 1000 - b which means the palindrome is 1 000 000 - 1000(a+b) + ab.

    First, let's find solutions where ab < 1000. Then the three leftmost digits are 1000 - (a+b) and the three rightmost digits are ab.

    Then I will say this is a palindrome with digits x,y,z:

    100x+10y+z=ab
    100z+10y+x=1000-a-b
    

    thus

    99x-99z = ab+a+b-1000
    x-z = 1/99(ab+a+b-10)-10
    

    So then (ab+a+b-10) is divisible by 99 and we also know that x and z being digits the left side is between -9 and 0 (the whole shebang is symmetrical so we can presume x <= z) so then 1/99(ab+a+b-10) is between 1 and 9. We can rewrite ab+a+b-10 as ab+a+b+1-11=99p so (a+1)(b+1)=99p+11=11*(9p+1) where p runs between 1 and 9. That's really easy:

    for ($p = 1; $p <= 9; $p++) {
      $n = 9 * $p + 1;
      // This could be vastly optimized further.
      for ($j = 1; $j <= $n; $j++) {
        if ($n % $j === 0) {
          $a = 1001 - $n / $j;
          $b = 1001 - 11 * $j;
          $test = $a * $b;
          if (strrev($test) === (string) $test) {
            print "$a $b " . $a * $b . "\n";
          }
        }
      }
    }
    

    Now this prints only one solution which is the correct one.

    Now we know 906609 is a solution so then is there a solution where ab > 1000 and 1000(a+b) - ab < 93391 ? There is not :)

    0 讨论(0)
  • 2020-12-28 17:48

    Readable option:

    function maxPalindrome(num) {
      let maxPalindrome = 1;
    
      for (let i = num; i > 0; i--) {
        for (let j = num; j > 0; j--) {
          const product = i * j;
    
          if (
            product.toString() === product.toString().split("").reverse().join("")
            && product > maxPalindrome
          ) {
            maxPalindrome = product;
          }
        }
      }
    
      return maxPalindrome;
    }
    
    console.log(maxPalindrome(999));
    
    0 讨论(0)
提交回复
热议问题