Палиндром


#1

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

// 1.Берём остаток от деления 505 на 10
505 % 10 = 5;

// 2.Уменьшаем изначальное число
505 / 10 = 50;

// 3.Начинаем собирать число 505 задом наперёд
// 5 — остаток от деления
// 50 — результат деления 505 на 10
5 * 10 + 50 % 10 = 50;

// 4.Снова уменьшаем изначальное число
50 / 10 = 5;

// 5.Продолжаем собирать число
// 50 — результат третьей операции
// 5 — результат деления 50 на 10
50 * 10 + 5 % 10 = 505;

// Получилось то же самое число
// 505 — палиндром
505 === 505

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


#2

Принцип моего решения:

Находим число цифр в числе. Предположим, у нас четырехзначное число, т.е. число вида abcd. Делим его на 10^3, 10^2, 10^1, 10^0. Полученные значения округляем вниз до целого, получаем числа a, ab, abc, abcd. Эти числа уменьшаем соответственно на 0 * 10, a * 10, ab * 10, abc * 10, получаем числа a, b, c, d. Умножаем полученные значения на 10^0, 10^1, 10^2, 10^3 и складываем, получаем число вида dcba. Проводим проверку на палиндром.

В коде это выглядит так:

var poly = 65487;
var ylop = 0;
var isPalindrome = false;

// Находим разрядность числа:
var quantity = 0;
var i = 1;
while (poly / i >= 1) {
  quantity ++;
  i *= 10;
}

var currentDigit = 0;
var exponentCounter = 0;

for (var i = quantity - 1; i >= 0; i --) {
  
  var previousDigit = currentDigit;
  currentDigit = Math.floor(poly / Math.pow(10, i));
  var number = currentDigit - previousDigit * 10;
  var ylopDigit = number * Math.pow(10, exponentCounter);
  exponentCounter ++;
  ylop += ylopDigit;  
}

if (poly === ylop) {
  isPalindrome = true;
}

#3

Выглядит занимательно, но может можно это испытание и попроще можно пройти.
Предлагайте ещё варианты, интересно будет посмотреть.


#4

Эх, ладно, вот вам попроще.

var poly = 7997;
var ylop = 0;
var isPalindrome = false;
var number = poly

var quantity = 0;
var i = 1;
while (poly / i >= 1) {
  quantity ++;
  i *= 10;
}

for (var i = quantity - 1; i >=0; i --) {
  ylop += (poly % 10) * Math.pow(10, i);
  poly = Math.floor(poly / 10);
}

  if (number === ylop) {
  isPalindrome = true;
}

Принцип такой: находим разрядность числа (для определения числа прогонов в цикле). Находим остаток от деления poly на 10 и умножаем его на 10^(n-1), где n - разрядность poly. Складываем это значение в переменную ylop. Переменную poly переопределяем как округленный вниз результат от деления poly на 10. Повторяем n раз. Если округления вниз мы еще не знаем, отнимаем от poly остаток от деления poly на 10 и полученное значение делим на 10. При проверке на палиндром не забываем, что poly в цикле переопределилось.


#5

Почему бы не работать с числом как со строкой?


#6

Потому что мы еще:

  1. не умеем
  2. задание про циклы

А если бы умели, то вот:

var poly = 1023094885;
var ylop = 0;
var isPalindrome = false;
var number = poly;

number = number.toString();
var splitString = number.split("");
var reverseArray = splitString.reverse();
number = reverseArray.join("");
ylop = parseInt(number);

if (ylop === poly) {
  isPalindrome = true;
}

Или даже проще:

var poly = 1023094885;
var ylop = 0;
var isPalindrome = false;
var number = poly;

number = number.toString();
var splitString = number.split("");
var reverseArray = splitString.reverse();
ylop = reverseArray.join("");

if (ylop == poly) {
  isPalindrome = true;
}

#7

Это уже массивы, да и можно короче, промежуточные переменные здесь не нужны. Хотя может и читается хуже

var poly = 505;
var ylop = Number(poly.toString().split('').reverse().join(''));
var isPalindrome = ylop === poly;

Но я имел ввиду, когда просто число переводим в строку и циклом переворачиваем ее, потом либо нестрогое сравнение(что делать никогда не рекомендуется), либо перевод снова в число и строгое сравнение

var poly = 242342;
var str = String(poly);
var result = '';
for(var i = str.length - 1; i >= 0; i -= 1) {
  result += str[i];
}
var ylop = Number(result);
var isPalindrome = ylop === poly;

#8

А мы еще не знаем length. Это будет в массивах :slight_smile:


#9

¯_(ツ)_/¯
Тогда беру свои слова назад


#10

Не знаю, правильно ли, но проверку этот код прошел

    var poly = 1221;
    var ylop = 0;
    var number = poly;
    var isPalindrome = false;
    for(; poly; poly = Math.floor(poly / 10)) {
        ylop = ylop * 10 + poly % 10;
    }
    if(ylop === number) {
      isPalindrome = true;
      }

#11

Остроумное решение. Я не совсем понимаю, как работает for без счетчика, поэтому предлагаю цикл сделать таким:

while(poly) {  
  ylop = ylop * 10 + poly % 10;
  poly = Math.floor(poly / 10);
}

#12

Спасибо большое ребята. Очень мне помогли а предпоследний код очень загадочный для меня особенно этот цикл for.


#13

Мой вариант, для решения пришлось ввести переменную polyTest.
Похожего еще ни у кого не видел, решение на основе только пройденного материала.
Что скажете?

var poly = 5005;
var polyTest = poly;
var ylop = 0;
var isPalindrome = false;

while (polyTest > 0) {
  ylop += polyTest%10;
  ylop *=10;
  polyTest -= polyTest%10;
  polyTest /=10;
}
ylop = ylop / 10;

if (poly === ylop) {
  isPalindrome = true;
}

#14

У меня как-то так получилось. Решение, конечно, не самое лаконичное, но зато без использования подсказок.

var ylop = '';
var number = poly;

for (var i = 1; i <= poly.toString().length; i++) {
  ylop += number % 10;
  number = Math.floor(number / 10);
}

ylop = +ylop;
if (poly === ylop) {
  isPalindrome = true;
}

#16

А у меня так вышло:

var poly = 1221;
var ylop = 0;
var isPalindrome = false;

ylop = +poly.toString().split("").reverse().join("");
if (poly === ylop) {
  isPalindrome = true;
}

#17

Решил через приведение к массиву:

var poly = 7788;
var ylop = 0;
var isPalindrome = false;

function makeReverse(num) {
  var newNum = String(num).split('').reverse();
  ylop = Number(newNum.join(''));  
  if (!(num - ylop)) {
    isPalindrome = true;
  }
  return ylop;
}
makeReverse(poly);

#18

плохая практика делать функцию с побочными эффектами
Особенно в вашем примере


#19

Тогда так:

var poly = 774588;
var isPalindrome = false;

function makeReverse(num) {
  var newNum = String(num).split('').reverse();
  var newYlop = Number(newNum.join(''));  
  if (!(num - newYlop)) {
    isPalindrome = true;
  }
}
makeReverse(poly);

#20

Казалось бы, куда уж хуже :grin:
Побочный эффект остался тот же - функция не явно меняет окружение, но теперь она еще и не делает reverse.

Давайте представим, используем вашу функцию в другом контексте, где надо просто перевернуть строку и где нет isPalindrome . Что мы получим? Либо появится глобальная переменная isPalindrome либо код рухнет с ошибкой что такой переменной нет и при этом она не будет делать то, что заявлено в название


#21

reverse функция во всех случаях делает)

var poly = 7788;
var ylop = 0;
var isPalindrome = false;

function makeReverse(num) {
  var newNum = String(num).split('').reverse();
  ylop = Number(newNum.join(''));  
  return ylop;
}
makeReverse(poly);
if (!(poly - ylop)) {
  isPalindrome = true;
}