Палиндром из произведения двух трехзначных чисел - PullRequest
1 голос
/ 18 сентября 2011

Я хочу найти самый большой палиндром, который можно получить путем умножения двух трехзначных чисел.

Я начал с a и b, которые равны 999, и уменьшали a и b при каждом умножении.

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

Результат оказался 698896, 289982, 94249, 69696 ... с первым номером 698896. В настоящее время я все еще пытаюсь выяснить, чего мне не хватает.

Ответы [ 6 ]

14 голосов
/ 18 сентября 2011

Вы не можете уменьшать a и b поочередно, потому что вы пропускаете пары значений, такие как a = 999 и b = 997.

Вместо этого попробуйте использовать вложенные циклы, начиная с 999и считать в обратном направлении.

Что-то вроде

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

РЕДАКТИРОВАТЬ: Изменены нижние границы после комментария Павла.

3 голосов
/ 18 сентября 2011

Ваш алгоритм неверен.Вам нужно будет проверить все значения от a до всех значений b, что можно решить, используя два цикла (внешний для a и внутренний для b).Я также предлагаю вам использовать a и b в качестве индексов цикла, что упрощает логику (облегчает держать в голове).

Также рассмотрите возможность переноса проверки палиндрома на его собственную функцию, чтобы упростить кодчтобы понять.


Я не программист Python, но вот мое решение на 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];
1 голос
/ 08 сентября 2017
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
1 голос
/ 20 ноября 2015

Самый быстрый метод состоит в том, чтобы отклониться от самого большого полиндрома до максимального значения 999x999 = 998001. 997799,996699, .. и проверьте каждый, может ли он быть разделен на A и B в диапазоне 100..999. Мой код занял 2200 циклов. Ваш код займет от 4K до 8K циклов.

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

0 голосов
/ 07 декабря 2016

Я сделал это, оптимизировал и сократил количество шагов для поиска

время 0.03525909700010743

палиндром = 906609

count = 3748

я = 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())
0 голосов
/ 10 января 2013

В C # - решение в гисте - https://gist.github.com/4496303

работник общественного класса { государственный служащий () {

    }
    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);
    }



}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...