Palindrome from the product of two 3-digit numbers

走远了吗. 提交于 2019-12-18 07:25:32

问题


I want to find the largest palindrome that can be obtained through the multiplication of two 3-digit numbers.

I started off with a and b both being 999, and to decrement a and b with every multiplication that occurred.

a = 999 #Defining Variables
b = 999

for i in range (1000): 
    c= a*b                          #multiply a to b
    if int(str(c)[::-1]) == c:
        print c
    a = a-1                         #decrement the value of a
    c=a*b                           #multiply a by the decremented a
    if int(str(c)[::-1]) == c:
        print c

    b = b-1                         #decrement b so that both a and b have been decremented

The result has turned up 698896, 289982, 94249, 69696... with 698896 being the first number. Currently I'm still trying to figure out what I'm missing.


回答1:


You cannot decrement a and b in an alternating fashion, because you're missing value pairs like a = 999 and b = 997 that way.

Try nested looping instead, starting from 999 and counting backwards.

Something like

def is_pal(c):
    return int(str(c)[::-1]) == c

maxpal = 0
for a in range(999, 99, -1):
    for b in range(a, 99, -1):
        prod = a * b
        if is_pal(prod) and prod > maxpal:
            maxpal = prod

print maxpal

EDIT: Modified lower bounds after Paul's comment.




回答2:


You algorithm is wrong. You will need to test all values of a to all values of b, which can be solved by using two loops (the outer for a and the inner for b). I also suggest that you use a and b as loop indices, which simplifies the logic (makes it easier to keep in head).

Consider moving the palindrome check to it's own function as well, to make the code easier to understand.


I'm no Python programmer, but here's my solution in PHP:

function palindrome($x) {
  $x = (string) $x;  //Cast $x to string
  $len = strlen($x); //Length of $x

  //Different splitting depending on even or odd length
  if($len % 2 == 0) {
    list($pre, $suf) = str_split($x, $len/2);
  }else{
    $pre = substr($x, 0, $len/2);
    $suf = substr($x, $len/2+1);
  }

  return $pre == strrev($suf);
}

$max = array(0, 0, 0);

//Loop $a from 999 to 100, inclusive.
//Do the same over $b for EVERY $a
for($a = 999; $a >= 100; $a--) {
  for($b = 999; $b >= 100; $b--) {
    $x = $a*$b;

    if(palindrome($x)) {
      echo $a, '*', $b, ' = ', $x, "\n";
      if($x > $max[2]) {
        $max = array($a, $b, $x);
      }
    }
  }
}
echo "\nLargest result: ", $max[0], '*', $max[1], ' = ', $max[2];



回答3:


The fastest method is to cicle down from the biggest polindrome before maximum value 999x999=998001. 997799,996699,.. and check each if it can be divided into A and B in range 100..999. My code took 2200 cycles. Your code will take about 4K to 8K cycles.

Sub method3a()
iterations = 0
For a = 997 To 0 Step -1
    R = a * 1000 + Val(StrReverse(a))
    b = 999      ' R=b*s
    s = Int(R / b)
    While b >= s
        iterations = iterations + 1
        If R = b * s Then
            Debug.Print "Result=" & R & " iterations=" & iterations
            Exit Sub
        End If
        b = b - 1
        s = Int(R / b)
    Wend
Next

End Sub




回答4:


i = 1000000
test = 0
while test == 0:
    i += -1
    str_i = str(i)
    if str_i[0:3] == str_i[3:][::-1]:
        for j in range(100, 1000):
            if i % j == 0:
                if i/j < 1000 and i/j > 100:
                    print('Largest Palindrome: %s = %s * %s' % (i, j, i//j))
                    test = 1
                    break



回答5:


In C# - solution in gist - https://gist.github.com/4496303

public class worker { public worker(){

    }
    public void start()
    {
        int MAX_NUMBER = 999;
        for (int Number = MAX_NUMBER; Number >= 0; Number--)
        {
            string SNumberLeft = Number.ToString();
            string SNumberRight = Reverse(Number.ToString());
            int palindromic = Convert.ToInt32(SNumberLeft + SNumberRight);

            for (int i = MAX_NUMBER; i >= 1; i--)
            {
                for (int l = MAX_NUMBER; l >= 1; l--)
                {
                    if ((i * l) - palindromic == 0)
                    {
                        System.Diagnostics.Debug.WriteLine("Result :" + palindromic);
                        return;
                    }
                }
            }

           // System.Diagnostics.Debug.WriteLine( palindromic); 
        }           

    }

    public string Reverse(String s)
    {
        char[] arr = s.ToCharArray();
        Array.Reverse(arr);
        return new string(arr);
    }



}



回答6:


I did it and have optimized and reduced the number of steps for search

time 0.03525909700010743

palindrome = 906609

count = 3748

i = 913

j = 993

from timeit import timeit

def palindrome(number):
    return str(number) == str(number)[::-1] # chek number is polindrome

def largest():
    max_num = 0
    count = 0
    ccount = 0
    ii = 0
    jj = 0
    for i in range(999, 99, -1): # from largest to smallest
        for j in range(999,  i - 1, -1): # exclude implementation j * i
            mult = i * j # multiplication
            count += 1
            if mult > max_num and palindrome(mult): # chek conditions
                max_num = mult #remember largest
                ii = i
                jj = j
                ccount = count
    return "\npalindrome = {0}\ncount = {1}\ni = {2}\nj = {3}".format(max_num, ccount, ii, jj)
print ("time", timeit('largest()', 'from __main__ import largest', number = 1))
print(largest())


来源:https://stackoverflow.com/questions/7460545/palindrome-from-the-product-of-two-3-digit-numbers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!