Я пытаюсь написать программу, которая ищет идеальные и почти идеальные числа.
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));
Он принимает несколько входов от пользователя и выводит идеальные для идеальных чисел, почти идеально подходит для почти идеальных номеров, и не идеален для... ну, вы его получите.
Пример ввода/вывода
Мой вопрос:
Я почти на месте. Вышеприведенный код работает, за исключением одного. Цикл while пропускает смежные значения и отмечает их как undefined
.
Например, когда я нахожу 6,43,2,650,28, выход будет 6 - совершенным, [43 будет пропущен], 2 - не идеально, [650 будет пропущено], 28 - совершенным, undefined
.
Проблемный выход
Вы вызываете 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
строку в своем выпуске.
while(readline()){
sumDivisors(readline());
}
Эта часть - проблема. Вы читаете строку, чтобы проверить, закончится ли она, отбросить эту строку, а если нет, вы прочитаете следующую строку для обработки. Сохраните результат и используйте эту строку, чтобы суммировать ваши делители.
У вас также будет очень странное поведение из-за рекурсии внутри цикла. Я предлагаю вам извлечь цикл в одну функцию, которая вызывает другую функцию, которая имеет дело только с одной строкой:
function findPerfectionInNumbers() {
let line;
while (line = readline()) {
checkNumberForPerfection(line);
}
}
и вы не выполняете рекурсии внутри этой другой функции.
Вам не нужно полностью перебирать целевой номер. Это нормально, чтобы дойти до половины, 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));
readline()
while(var num = readline()){ sumDivisors(num); }
while(var num = readline()){ sumDivisors(num); }
дает мне синтаксическую ошибку. Заменить это наfor(var num; num = readline();) { sumDivisors(num); }
дает мне правильный ответ, но сundefined
в конце. Я думаю, потому что он находит пустую строку в конце. Любая работа вокруг вас может придумать?