Интерация чисел, пока не станет 1

117
06 сентября 2019, 19:40

Нужно написать функцию JavaScript,которая возьмет число,и сложит квадрат каждой его цифры, пока не станет 1, если конечно с этим числом это возможно. Например:

x=23 -> 2^2+3^2=13 -> 1^2+3^2=10 -> 1^2+0^2=1

Числа могут быть разными, например 0, 1, 12, 123, 1234... Если задано такое число, что в конце станет 1, то пусть возвращает true, а если нет - false. (Не использовать prototype.) Я написал что-то такое, но это работает неправильно, так как это для двузначных чисел (10-99)

function solution5(x) { 
  let a; 
  let b; 
  for (var i = 0; i < x.length; i++) { 
    a = Math.floor(x / 10) 
    b = (x / 10) % 1 * 10 
    x = a ** 2 + b ** 2 
    if (x == 1) { 
      return true 
    } 
  } 
  return false 
} 
console.log(solution5(10))

Answer 1

Неоптимальный с точки зрения производительности вариант, можно и быстрее: :)

function sum2(num) { 
  return (num + '').split('').map(n => parseInt(n)).filter(isFinite).reduce((acc, n) => acc += n * n, 0); 
} 
 
function check(num) { 
  let count = 0; 
  let max = -Infinity; 
  let cur = num; 
  do { 
    cur = sum2(cur); 
    if (cur > Number.MAX_SAFE_INTEGER) throw 'Loss of precision, unable to calculate'; 
    if (cur == 1) return true; 
    if (cur > max) max = cur; 
    count++; 
  } while (count < max) 
  return false; 
} 
 
console.log(0, check(0)); 
console.log(1, check(1)); 
console.log(12, check(12)); 
console.log(23, check(23)); 
console.log(123, check(123)); 
console.log(1234, check(1234));

Оптимизированный вариант:

function sum2(num) { 
  return (num + '').split('').map(n => parseInt(n)).filter(isFinite).reduce((acc, n) => acc += n * n, 0); 
} 
 
function check(num) { 
  let used = new Set(); 
  let cur = num; 
  do { 
    cur = sum2(cur); 
    if (used.has(cur)) return false; 
    if (cur == 1) return true; 
    if (cur > Number.MAX_SAFE_INTEGER) throw 'Loss of precision, unable to calculate'; 
    used.add(cur); 
  } while (true) 
} 
 
console.log(0, check(0)); 
console.log(1, check(1));  
console.log(12, check(12)); 
console.log(23, check(23)); 
console.log(123, check(123)); 
console.log(1234, check(1234));

Строго говоря, в обоих вариантах проверка на MAX_SAFE_INTEGER не особо нужна, потому что даже если передать в функцию sum2 число, записанное в виде достаточно длинной строки, превысить это значение не удастся (строка необходимой для этого длины не поместится в памяти), однако пусть будет, для полноты картины.

Answer 2

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

const input = document.getElementById('number'); 
const result = document.getElementById('result'); 
var sum; 
function count() { 
  var number = input.value; 
  let array = number.toString().split(''); 
  sum = 0; 
  for (let i=0; i<array.length; i++) { 
    sum += Math.pow(array[i],2); 
  } 
  result.insertAdjacentHTML('afterend', sum + '<br>'); 
   
  //console.log(sum); 
}
<input type="number" id="number"> 
<button onclick="count()">count</button> 
<h4>result</h4> 
<hr> 
<div id="result"></div>

READ ALSO
Как добавить в lazy load background?

Как добавить в lazy load background?

Стоит плагин на wp lazy-load, но не работают изображения через стили background

137
Подгон размеров div блоков под экран

Подгон размеров div блоков под экран

Всем привет! Как реализовать изменение размеров блока при изменении размеров экрана? На сайте http://agario это реализовано так, что блок не может...

110
Один файл js не видит действия другого [закрыт]

Один файл js не видит действия другого [закрыт]

Есть два файла *js , в первом создание дива

141
GZIP не сжимает javascript файлы

GZIP не сжимает javascript файлы

Адрес сайта - omiksagrocom Работаю над оптимизацией

120