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

前端 未结 17 987
天涯浪人
天涯浪人 2021-02-02 04:27
package testing.project;

public class PalindromeThreeDigits {

    public static void main(String[] args) {
        int value = 0;
        for(int i = 100;i <=999;i+         


        
相关标签:
17条回答
  • 2021-02-02 05:12
    i did this my way , but m not sure if this is the most efficient way of doing this .
    
    package problems;
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    
      public class P_4 {
    
    /**
     * @param args
     * @throws IOException 
     */
    static int[] arry = new int[6];
    static int[] arry2 = new int[6];
    
    public static boolean chk()
    {
        for(int a=0;a<arry.length;a++)
            if(arry[a]!=arry2[a])
                return false;
    
    return true;
    
    }
    
    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
    
        InputStreamReader ir = new InputStreamReader(System.in);
        BufferedReader br = new BufferedReader(ir);
        int temp,z,i;
    
    for(int x=999;x>100;x--)
        for(int y=999;y>100;y--)
            {
            i=0;
                z=x*y;
                while(z>0)
                    {
                        temp=z%10;
                        z=z/10;
                        arry[i]=temp;
                        i++;
                    }
    
                for(int k = arry.length;k>0;k--)
                            arry2[arry.length- k]=arry[k-1];
    
        if(chk())
        {
            System.out.print("pelindrome = ");
    
    for(int l=0;l<arry2.length;l++)
    System.out.print(arry2[l]);
    System.out.println(x);
    System.out.println(y);
    }
    
        }
    }
    }
    
    0 讨论(0)
  • 2021-02-02 05:13

    Since we are not cycling down both iterators (num1 and num2) at the same time, the first palindrome number we find will be the largest. We don’t need to test to see if the palindrome we found is the largest. This significantly reduces the time it takes to calculate.

    package testing.project;
    public class PalindromeThreeDigits {
        public static void main(String[] args) {
    
        int limit = 99;
        int max = 999;
        int num1 = max, num2, prod;
    
        while(num1 > limit)
        {
            num2 = num1;
            while(num2 > limit)
            {
                total = num1 * num2;
                StringBuilder sb1 = new StringBuilder(""+prod);
                String sb2 = ""+prod;
                sb1.reverse();
                if( sb2.equals(sb1.toString()) ) {    //optimized here
                    //print and exit
                }
                num2--;
            }
            num1--;
        }
    
     }//end of main
     }//end of class PalindromeThreeDigits
    
    0 讨论(0)
  • 2021-02-02 05:15

    You can use the fact that 11 is a multiple of the palindrome to cut down on the search space. We can get this since we can assume the palindrome will be 6 digits and >= 111111.

    e.g. ( from projecteuler ;) )

    P= xyzzyx = 100000x + 10000y + 1000z + 100z + 10y +x
    P=100001x+10010y+1100z
    P=11(9091x+910y+100z)
    

    Check if i mod 11 != 0, then the j loop can be subtracted by 11 (starting at 990) since at least one of the two must be divisible by 11.

    0 讨论(0)
  • 2021-02-02 05:16

    We suppose the largest such palindrome will have six digits rather than five, because 143*777 = 111111 is a palindrome.

    As noted elsewhere, a 6-digit base-10 palindrome abccba is a multiple of 11. This is true because a*100001 + b*010010 + c*001100 is equal to 11*a*9091 + 11*b*910 + 11*c*100. So, in our inner loop we can decrease n by steps of 11 if m is not a multiple of 11.

    We are trying to find the largest palindrome under a million that is a product of two 3-digit numbers. To find a large result, we try large divisors first:

    • We step m downwards from 999, by 1's;
    • Run n down from 999 by 1's (if 11 divides m, or 9% of the time) or from 990 by 11's (if 11 doesn't divide m, or 91% of the time).

    We keep track of the largest palindrome found so far in variable q. Suppose q = r·s with r <= s. We usually have m < r <= s. We require m·n > q or n >= q/m. As larger palindromes are found, the range of n gets more restricted, for two reasons: q gets larger, m gets smaller.

    The inner loop of attached program executes only 506 times, vs the ~ 810000 times the naive program used.

    #include <stdlib.h>
    #include <stdio.h>
    int main(void) {
      enum { A=100000, B=10000, C=1000, c=100, b=10, a=1, T=10 };
      int m, n, p, q=111111, r=143, s=777;
      int nDel, nLo, nHi, inner=0, n11=(999/11)*11;
    
      for (m=999; m>99; --m) {
        nHi = n11;  nDel = 11;
        if (m%11==0) {
          nHi = 999;  nDel = 1;
        }
        nLo = q/m-1;
        if (nLo < m) nLo = m-1;
    
        for (n=nHi; n>nLo; n -= nDel) {
          ++inner;
          // Check if p = product is a palindrome
          p = m * n;
          if (p%T==p/A && (p/B)%T==(p/b)%T && (p/C)%T==(p/c)%T) {
            q=p; r=m; s=n;
            printf ("%d at %d * %d\n", q, r, s);
            break;      // We're done with this value of m
          }
        }
      }
      printf ("Final result:  %d at %d * %d   inner=%d\n", q, r, s, inner);
      return 0;
    }
    

    Note, the program is in C but same techniques will work in Java.

    0 讨论(0)
  • 2021-02-02 05:16

    I believe there is a simpler approach: Examine palindromes descending from the largest product of two three digit numbers, selecting the first palindrome with two three digit factors.

    Here is the Ruby code:

    require './palindrome_range'
    require './prime'
    
    def get_3_digit_factors(n)
      prime_factors = Prime.factors(n)
    
      rf = [prime_factors.pop]
      rf << prime_factors.shift while rf.inject(:*) < 100 || prime_factors.inject(:*) > 999
    
      lf = prime_factors.inject(:*)
      rf = rf.inject(:*)
    
      lf < 100 || lf > 999 || rf < 100 || rf > 999 ? [] : [lf, rf]
    end
    
    def has_3_digit_factors(n)
      return !get_3_digit_factors(n).empty?
    end
    
    pr = PalindromeRange.new(0, 999 * 999)
    n = pr.downto.find {|n| has_3_digit_factors(n)}
    puts "Found #{n} - Factors #{get_3_digit_factors(n).inspect}, #{Prime.factors(n).inspect}"
    

    prime.rb:

    class Prime
    
      class<<self
    
        # Collect all prime factors
        # -- Primes greater than 3 follow the form of (6n +/- 1)
        #    Being of the form 6n +/- 1 does not mean it is prime, but all primes have that form
        #    See http://primes.utm.edu/notes/faq/six.html
        # -- The algorithm works because, while it will attempt non-prime values (e.g., (6 *4) + 1 == 25),
        #    they will fail since the earlier repeated division (e.g., by 5) means the non-prime will fail.
        #    Put another way, after repeatedly dividing by a known prime, the remainder is itself a prime
        #    factor or a multiple of a prime factor not yet tried (e.g., greater than 5).
        def factors(n)
          square_root = Math.sqrt(n).ceil
          factors = []
    
          while n % 2 == 0
            factors << 2
            n /= 2
          end
    
          while n % 3 == 0
            factors << 3
            n /= 3
          end
    
          i = 6
          while i < square_root
            [(i - 1), (i + 1)].each do |f|
              while n % f == 0
                factors << f
                n /= f
              end
            end
    
            i += 6
          end
    
          factors << n unless n == 1
          factors
        end
    
      end
    
    end
    

    palindrome_range.rb:

    class PalindromeRange
    
      FIXNUM_MAX = (2**(0.size * 8 -2) -1)
    
      def initialize(min = 0, max = FIXNUM_MAX)
        @min = min
        @max = max
      end
    
      def downto
        return enum_for(:downto) unless block_given?
    
        n = @max
        while n >= @min
          yield n if is_palindrome(n)
          n -= 1
        end
        nil
      end
    
      def each
        return upto
      end
    
      def upto
        return enum_for(:downto) unless block_given?
    
        n = @min
        while n <= @max
          yield n if is_palindrome(n)
          n += 1
        end
        nil
      end
    
      private
    
      def is_palindrome(n)
        s = n.to_s
        i = 0
        j = s.length - 1
        while i <= j
          break if s[i] != s[j]
          i += 1
          j -= 1
        end
        i > j
      end
    
    end
    
    0 讨论(0)
  • 2021-02-02 05:18

    You can actually do it with Python, it's easy just take a look:

    actualProduct = 0
    highestPalindrome = 0
    
    # Setting the numbers. In case it's two digit 10 and 99, in case is three digit 100 and 999, etc.
    num1 = 100
    num2 = 999
    
    def isPalindrome(number):
            number = str(number)
            reversed = number[::-1]
            if number==reversed:
                    return True
            else:
                    return False
    
    a = 0
    b = 0
    
    for i in range(num1,num2+1):
            for j in range(num1,num2+1):
                    actualProduct = i * j
                    if (isPalindrome(actualProduct) and (highestPalindrome < actualProduct)):
                            highestPalindrome = actualProduct
                            a = i
                            b = j
    
    
    print "Largest palindrome made from the product of two %d-digit numbers is [ %d ] made of %d * %d" % (len(str(num1)), highestPalindrome, a, b)
    
    0 讨论(0)
提交回复
热议问题