4,7K подписчиков

Проект Эйлер 4: Наибольшее произведение-палиндром

Рассматриваю решение очередной задачи, сделанное автором канала:

Кстати, задачу №3 (Наибольший простой делитель) я делать не стал, так как не нашёл, что в ней можно улучшить. Вы найдёте её на том же канале.

Задача

Число-палиндром с обеих сторон (справа налево и слева направо) читается одинаково. Самое большое число-палиндром, полученное умножением двух двузначных чисел – 9009 = 91 × 99.

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

Решение

Для начала нужна функция, которая определяет, что число – палиндром.

Возможно, она вообще окажется лишней, если откроется некая магическая возможность подобрать два множителя, которые заведомо дадут палиндром. Например, множители 202 и 202 заведомо дают палиндром 40804.

Но для порядка я её сделаю (она может пригодиться сама по себе).

Посмотрим решение автора. Так как оно длинное, то приведу только пару кусочков.

Рассматриваю решение очередной задачи, сделанное автором канала: Кстати, задачу №3 (Наибольший простой делитель) я делать не стал, так как не нашёл, что в ней можно улучшить.

Для начала он получает по отдельности все разряды числа (для произведения двух трёхзначных чисел это максимум 6 разрядов).

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

и т.д.
и т.д.

Именно из-за разного количества разрядов требуются отдельные блоки сравнений на каждый вариант, что сильно удлиняет код. Его можно подсократить таким образом: вместо трёх строчек

Рассматриваю решение очередной задачи, сделанное автором канала: Кстати, задачу №3 (Наибольший простой делитель) я делать не стал, так как не нашёл, что в ней можно улучшить.-3

можно написать одну строчку:

return num6 == num1 && num5 == num2 && num4 == num3;

Но по сути это ничего не меняет.

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

Рассматриваю решение очередной задачи, сделанное автором канала: Кстати, задачу №3 (Наибольший простой делитель) я делать не стал, так как не нашёл, что в ней можно улучшить.-4

Что она делает: пока число не обнулилось, отделяет от него младший разряд и кладёт его в массив digits, одновременно накапливая его длину len.

Затем в цикле проходит по массиву digits, двигая счётчик цикла i и len навстречу друг другу, пока они не встретятся. Ну и конечно сравнивая соответствующие ячейки массива друг с другом.

Посмотрев на это и не совсем удовлетворившись, я решил написать ещё одну функцию, которая имеет ограничение на 8 разрядов (может быть расширено до 16), но зато по хардкору.

Рассматриваю решение очередной задачи, сделанное автором канала: Кстати, задачу №3 (Наибольший простой делитель) я делать не стал, так как не нашёл, что в ней можно улучшить.-5

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

Прямое число на каждом шаге сдвигается влево на 4 бита, и в его младшие 4 бита помещается 1 разряд. Обратное число на каждом шаге сдвигается вправо на 4 бита, и в его старшие 4 бита помещается тот же разряд.

После завершения процедуры сдвигаем вправо обратное число на неиспользованное количество бит.

После этого получим числа, где в каждых 4-х битах лежит по одному разряду, в прямом и обратном порядке соответственно.

Если число палиндром, то прямое и обратное числа будут равны.

Множители

Второй этап это организовать тестирование двух множителей. Конечно, тут ничего кроме цикла на ум не приходит, поэтому моё решение ничем не отличается от авторского.

Рассматриваю решение очередной задачи, сделанное автором канала: Кстати, задачу №3 (Наибольший простой делитель) я делать не стал, так как не нашёл, что в ней можно улучшить.-6

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

Ссылка на онлайн-компилятор языка C с текстом программы:

https://onlinegdb.com/29wA5kv-m

Вся подборка задач: