Палиндром


#43

Получилось вот так:

Код

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

var s = poly;
while (ylop < poly) {
ylop = ylop + (s % 10);
if (ylop === poly) {
isPalindrome = true;
break;
}
s = Math.floor(s / 10);
ylop = ylop * 10;
}


#44

У меня получилось 2 решения - одно полностью завязанное на String, другое на String + математика:
1.
var poly = 1221;
var doString = poly.toString();
var ylop = “”;
var isPalindrome = false;

for (var i = 0; i < doString.length; i++) {
ylop = doString.charAt(i) + ylop;
}

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

var poly = 1221;
var doString = poly.toString();
var ylop = “”;
var isPalindrome = false;

var residue = 0;
var subtr = poly;

for (var i = 0; i < doString.length; i++) {
residue = subtr % 10;
subtr = subtr - residue;
subtr = subtr / 10;
ylop = ylop + residue;
}

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

Второй вариант не очень нравится, т.к. все ломается если число начинается с нуля


#45

если не использовать изящное решение через reverse, то вот он:

самый каеф
var poly = 1221;
var ylop = 0;
var isPalindrome = false;
for (var i = 1; poly / i >= 1; i *= 10) { // счетчик 1, 10, 100, 1000 и т.д. пока результат деления больше 1, значит мы не достигли лимита разрядности poly и повторяем итерацию
    ylop += Math.floor(poly / i) % 10; // math.floor обрезает число от остатка деления для захода на новую итерацию, а сам остаток вписываем в ylop
    ylop = ylop.toString();  // тут вписываем в строку подряд остаток от деления
} 
if (ylop == poly) { // используем нестрогое сравнение, т.к. ylop у нас сейчас строка
    isPalindrome = true;
}

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

var polyCheck = poly;

for (var i = 0; i <= String(poly).length; i++) {
  ylop += (poly % 10) * Math.pow(10,(String(poly).length - 1)); 
  poly = (poly - (poly % 10)) / 10;
}

ylop += poly;

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

#47
ylop = poly.toString();
var symbAmount=ylop.length;

var n=~~(symbAmount/2); /*Пробовал 
math.round, но она округляет в 
большую сторону*/
var b=-1;
for (var i=0; i<n; i++) {
  if (i==0) {
   if ( ylop.slice(i,(i+1)) == ylop.slice(b)) {
    isPalindrome = true;
   }else{isPalindrome=false; 
     break;/*сравнение первого и 
  последнего символов*/
   }
 }
  else if (ylop.slice(i,(i+1))==ylop.slice((b-1),b)) {
    b=b-1;
    isPalindrome=true;
  }else{isPalindrome=false;
   break; /*сравнение второго и 
предпоследнего, и т.д.*/
 }
} /*проверка останавливается, как 
только натыкается на первое 
несовпадение*/

#48

Усовершенствованный вариант:

ylop = poly.toString();
var n = (ylop.length - 1);
for (var i=0; i<(Math.floor(ylop.length/2));i++) {
  if (ylop[i] == ylop[n]) {
    console.log(ylop[i],ylop[n]);
    isPalindrome = true;
    n -= 1;
    }else{
     isPalindrome = false;
     break;
    }
 }
 console.log(isPalindrome);

#49
var poly = 1221;
var polyHelp = poly; //чтобы не затерлось первое значение
var ylop = 0;
var isPalindrome = false;

if (poly >= 10) {    //это проверка на одноразрядное число
  ylop = polyHelp % 10;
  while (polyHelp > 9) {
    polyHelp = ~~(polyHelp / 10);
    ylop = ylop * 10 + polyHelp % 10;
  }
} else {
  ylop = poly;
}
if (ylop === poly) {
  isPalindrome = true;
}

это мой вариант без использования строк.


#50

Соорудила вот такой вариант.

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

var number;
var polyForCount = poly;

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

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


#51

Не понял встроенной подсказки. Хотя и посмотрел ее после того как сам решил. Но решение как по мне не лаконичное. Тут в примерах намного короче увидел. Мне пришлось вообще вносить длинную формулу. Ну и конечно использовал предыдущие упражнения (как подсчет цыфр в числе). Ну и конечно применял только изученное.

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

//Ищем кол-во знаков в числе

var number = poly;
var quantity = 0;
while (number > 1) {
  number /=10;
  quantity++;
}
//Переворачиваем число

var razryad = 10;
var mnoz = 1;
var mnoz2 = 1;

for (j = 1; j < quantity; j++) {mnoz2 *= 10}

for (var i = 1; i <= quantity; i++) {
  ylop += (poly % (razryad * mnoz) - (poly % mnoz)) / mnoz * mnoz2;
  mnoz *= 10;
  mnoz2 /=10;
}
//Сравниваем с изначальным

if (poly == ylop) {isPalindrome = true} else {isPalindrome = false}

#52

Хорошее и очень короткое решение. Но Math.trunc к этому моменту еще не проходили. ))


#53
var poly = 3223;
var ylop = 0;
var isPalindrome = false;
var fakePoly = poly;

var beforeComma = 0;
var divider = 10;

while (fakePoly > 0.1) {
  
  beforeComma = fakePoly % divider;
  fakePoly = (fakePoly / divider) - (fakePoly % divider) / divider;
  ylop += beforeComma.toString()
 }

ylop = parseInt(ylop, 10);

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

#54

До простого и лаконичного решения пока не дошел, буду пробовать ещё. А пока вот:

var poly = 123456789;
var ylop = 0;
var isPalindrome = false;
var fakePoly = poly;
var quantity = 0;           // количество знаков.

while (fakePoly >= 1) {
  fakePoly /= 10;
  quantity++; 
  }

console.log(quantity + ' quantity')

fakePoly = poly;

var number;
while (fakePoly > 0) {
   number = fakePoly % 10;
 
 for (var i = 1; i <= quantity - 1; i++) { 
 number *= 10;
 }
 
 quantity--;
 console.log(number + ' number')
 fakePoly = fakePoly / 10 - (fakePoly % 10) / 10;

 ylop += number;
 console.log(ylop + ' ylop');
}

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

#55

Решил с помощью встроенной подсказки.:see_no_evil:

var poly = 126780001;
var ylop = 0;
var isPalindrome = false;
var fakePoly = poly;


while (fakePoly >= 1) {
  ylop = fakePoly % 10 + ylop * 10;
  fakePoly = fakePoly / 10 - (fakePoly % 10) / 10;
}

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

#56

Исходя из того, что тема все таки была о циклах, Ваш @deevtmb вариант решения выглядит самым оптимальным. Но, @GreenLera, проверка на числе 1234567890987654321 все таки не работает:

И вот что получается, если вывести в консоль переменную ylop, то число у нас получается совсем не 1234567890987654321, а 44567890987654320 :

Скриншотик

Хм… как же так? Проверки на других числах ведь работают :thinking:

Как оказывается, в javascript есть такое понятие как БЕЗОПАСНЫЕ ЧИСЛА:

Безопасные целые числа состоят из всех целых чисел в диапазоне
от -(2^53 - 1) до 2^53- 1 включительно.

Все что не попало в этот диапазон (и наш палиндром в том числе :point_up: ) округляется в режимах округления к ближайшему и к нулю так, чтоб число все таки вписалалось в диапазон безопасных чисел.

И вот, что мы имеем: мы то думаем, что работаем с числом 1234567890987654321, а на самом деле в цикл у нас попадает уже число 1234567890987654400, т.к. наш палиндром в диапазон безопасных чисел не вписался и javascript заботливо выполнил все округления, чтоб число в диапазон все таки попало:

Ещё один скриншотик

Как-то так :nerd_face:


#57

поверьте, Лера в курсе =)
а это вычисление и не должно работать собственно. для таких длинных чисел есть метод поиска подстроки с начала и конца на проверку палиндрома.
вот вам еще “парадокс”: 0.1 + 0.2 === 0.3 ==> false
по той же причине. особо глубоко не копайте, жабаскрипт не предназначен для космически точных вычислений. не точнее калькулятора бытового.

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


#58

Верю:slight_smile:

Но я что шарилась в гугле и расписывала итерации цикла, чтобы все таки докопаться до того, почему же с одними числами - ок, а с другими - не ок, и оставить эту инфу себе?)

Может кому-то она пригодится)


#59

а тут больше дело в том, что чем глубже проникаешь в жс, тем глубже понимаешь в какую жо…жожореференс влезаешь =) даже те же сравнения чего стоят. почитайте на досуге по каким именно правилам работает сравнение при приведении типов, а также решите простой вопрос, почему
null > 0; // false
null == 0; // false
null >= 0; // true