Project Euler # 4 крупнейший палиндромный продукт

#java

#java

Вопрос:

Мы пытаемся найти наибольшее число палиндрома, которое генерируется путем умножения двух 3-значных чисел. Номер палиндрома — это тот, который одинаково читается с обеих сторон (пример: 12345654321 или просто 9009). Следующий код компилируется правильно, но, очевидно, имеет место логическая ошибка, потому что результат равен 749947, когда он должен быть 906609. Если бы кто-нибудь мог помочь объяснить логику того, где я неправильно понимаю эту проблему, это было бы здорово.

 boolean valid = false;
for (int i = 999*999; i > 100*100; i--) {
  if (i / 100000 == i % 10 amp;amp;
      i / 10000 % 10 == i / 10 % 10 amp;amp;
      i / 1000 % 10 == i / 100 % 10) {
        int buffer = i;
        int total = 1;
        for (int k = 2; k < buffer; k  ) {
          if (buffer % k == 0) {
            buffer /= k;
            total *=k;
          }
        }
        if (buffer >= 100 amp;amp; buffer < 1000 amp;amp; total >=100 amp;amp; total < 1000 ) {
          System.out.println(i);
          System.out.println(total);
          System.out.println(buffer);
          break;
        }
     }
    }
  }
}
  

Комментарии:

1. Что вы заметили, когда подключили отладчик в вашей IDE и прошлись по коду построчно ?

2. я бы спросил, не анализируя лакмусовую бумажку, которую вы используете, какова цель первой строки кода в вставленном вами фрагменте? Вы нигде не устанавливаете valid = true ….

3. еще один совет для проверки логики в вашем лакмусовой бумажке — сначала попробуйте более простой тест, например, преобразование i в строку, которая равна себе в обратном порядке

Ответ №1:

 906609  =  3 * 11 * 83 * 331  =  2739 * 331  =  913 * 993  =  ...
  

Ваш код преобразуется в buffer = 331, total = 2739 , что приводит к сбою вашего if оператора.

Предложение: вместо того, чтобы проверять все числа от 998001 до 10000 и пытаться найти 3-значные значения, которые приводят к числу при умножении, используйте двойной for цикл из 3-значных чисел и найдите наибольшее произведение, которое также является палиндромом.

Ответ №2:

Этому подходу легче следовать, и он работает.

 import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Palindrome
{
  private static List<Integer> palindromes = new ArrayList<Integer>();

  public static void main(String[] args)
  {
    for (int i = 999; i > 99; i--)
    {
      for (int j = 999; j > 99; j--)
      {
        if (isPalendrome(i * j))
        {
          palindromes.add(i * j);
        }
      }
    }
    if (!palindromes.isEmpty())
    {
      Collections.sort(palindromes);
      System.out.println(palindromes.get(palindromes.size() - 1));
    }
  }

  private static boolean isPalendrome(int number)
  {
    char[] word = String.valueOf(number).toCharArray();
    int i1 = 0;
    int i2 = word.length - 1;
    while (i2 > i1)
    {
      if (word[i1] != word[i2])
      {
        return false;
      }
        i1;
      --i2;
    }
    return true;
  }
}
  

Ответ №3:

Что ж, вам должно было быть проще объяснить, написав код, но мы должны вернуться к рассуждениям внутри него. Внешний цикл использует метод грубой силы, проверяя все числа на наличие палиндромных шаблонов, а затем применяя внутренний тест.

Этот внутренний тест — это то, где все идет наперекосяк. Он пытается быть умным, но выдает логическую ошибку. Я вижу, что он пытается разложить найденное число на buffer и total , предназначенное для двух трехзначных чисел. Однако позже он проверяет, что они являются трехзначными; они вычисляются без учета этого правила.

k используется в качестве потенциального фактора для передачи из buffer в total . Каждое число проверяется один раз, что исключает любое число с квадратными или более высокими коэффициентами мощности. Что еще более важно в этом случае, они проверяются от низкого до высокого, пока total не станут меньше buffer . Так что же происходит с 906609?

 (%i1) factor(906609);
(%o1) 3 11 83 331
  

Алгоритм останавливается на 3*11*83 * 331 , но 3*11*83 =2739, значит, неверное количество цифр. В искомом ответе используется другое разделение факторов: 3*331 * 11*83 . Подход факторизации выполним, но вам нужно будет проверить наличие групп факторов, которые, в свою очередь, дают трехзначные продукты.