Javascript пропускает смежное значение как неопределенное

1

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

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));

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

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

Изображение 174551

Мой вопрос:

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

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

Проблемный выход

Изображение 174551

  • 0
    слишком много вызовов readline() while(var num = readline()){ sumDivisors(num); }
  • 0
    Благодарю. Использование while(var num = readline()){ sumDivisors(num); } дает мне синтаксическую ошибку. Заменить это на for(var num; num = readline();) { sumDivisors(num); } дает мне правильный ответ, но с undefined в конце. Я думаю, потому что он находит пустую строку в конце. Любая работа вокруг вас может придумать?
Теги:
spidermonkey

3 ответа

1
Лучший ответ

Вы вызываете 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
    Благодарю. Это работает. Просто нужно оптимизировать мой код сейчас. Предполагается, что он наберет меньше секунды, и сейчас он превышает это. Еще раз спасибо!
1
while(readline()){
  sumDivisors(readline());
}

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

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

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

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

1

Вам не нужно полностью перебирать целевой номер. Это нормально, чтобы дойти до половины, 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
    Вау, очень умно. Я попробую это, может сэкономить мне время загрузки. Спасибо
  • 0
    @kwangonya Спасибо, но имейте в виду, что это все еще просто практика кодирования для вычисления идеальных чисел .. В реальной жизни вы бы не использовали это, потому что очень мало идеальных чисел, таких как 15 или около того ... и вы можно просто сохранить их в объекте Map для сравнения с входными данными. :)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню