Javascript пропускает смежное значение как неопределенное - PullRequest
0 голосов
/ 06 мая 2018

Я пытаюсь написать программу, которая ищет идеальные и почти идеальные числа.

var num = readline();

function sumDivisors(num){
  var sum = 0;
  for (var i = 1; i < num; i++){
    if (!(num % i)) {
      sum += i;
    }
  }
  if ( sum == num ) {
     print(num + " perfect");
   }
  if ( (sum - num == 2) || (sum - num == -2) ) {
     print(num + " almost perfect");
   }
  if ( ( sum != num ) && (sum - num != 2) && (sum - num != -2) ) {
     print(num + " not perfect");
   }
  while(readline()){
     sumDivisors(readline());
   }
}

print(sumDivisors(num));

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

Пример ввода / вывода

enter image description here

Мой вопрос:

Я почти у цели. Код выше, кажется, работает, за исключением одной вещи. Цикл while пропускает соседние значения и помечает их как undefined.

Например, когда я введу 6,43,2,650,28, вывод будет 6 - идеально, [43 будет пропущено], 2 - не идеально, [650 будет пропущено], 28 - идеально, undefined.

проблемный вывод

enter image description here

Ответы [ 3 ]

0 голосов
/ 06 мая 2018

Вы звоните readline() дважды в каждом цикле:

while(readline()){          // <-- here
   sumDivisors(readline()); // <-- again here
}

Поскольку вы ничего не делаете с первым, он просто удаляет номер из списка. Простое решение - сохранить результат в тесте while():

while((n = readline())){
   sumDivisors(n);
}

или еще лучше:

if((n = readline())){ // <-- you don't need a loop here since you have recursion
   sumDivisors(n);
}

Вы также звоните print на sumDivisors(), который ничего не возвращает: print(sumDivisors(num)); Вот почему вы получаете строку undefined в своем выводе.

0 голосов
/ 06 мая 2018

Вам не нужно повторять весь путь до целевого числа. Это нормально, если доходит до половины, Math.floor(n/2). Также нет нечетных совершенных чисел, поэтому вы можете повторять только четные. Тем не менее, так как вы также проверяете на почти идеальное, я экономлю время. Соответственно, вы можете сделать следующее:

function isPerfect(n){
  var target = Math.floor(n/2),
      sum    = Array.from({length: target})
                    .reduce((s,_,i) => n%(i+1) ? s : s += i+1, 0);
  return sum === n ? "perfect number"
                   : Math.abs(sum-n) < 3 ? "almost perfect number"
                                         : "not a perfect number";
}

console.log(isPerfect(33550336));
0 голосов
/ 06 мая 2018
while(readline()){
  sumDivisors(readline());
}

Эта часть - проблема. Вы читаете строку, чтобы проверить, является ли это концом, отбрасываете эту строку , а если это не так, вы читаете следующую строку для обработки. Сохраните результат и используйте эту строку для суммирования делителей.

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

function findPerfectionInNumbers() {
  let line;
  while (line = readline()) {
    checkNumberForPerfection(line);
  }
}

и вы не выполняете рекурсию внутри этой другой функции.

...