Помогите решить задачку [найти сумму или четных или нечетных или всех подряд натуральных n чисел в зависимости от значения аргумента]

Необходимо создать функцию. Она будет считать сумму от 0 до переданного числа.
Функция принимает в себя 2 параметра: number и type.

Параметр number - это число, до которого будет считаться сумма. То есть, если было передано число 10, то функция должна посчитать сумму от 0 до 10 (0 + 1 + 2 + … + 10). Если параметр не передан или значение было не числом, то из функции необходимо вернуть NaN.

Параметр type отвечает за выбор чисел для подсчета суммы. Он может быть одним из 3-х значений: “odd”, “even” и “”. Если type равняется “odd”, то в сумму должны входить только нечетные числа, “even” - четные числа, пустая строка “” - все числа. По умолчанию параметр type должен быть равен “odd”.

Вот скелет функции, а дальше не могу:

const getSumOfNumbers = function (number,type = "odd") { 
    let sum =0;
    for (let i = 0; i <= number; i++) {
      if (type === "") {

      } else if (type === "even") {

      } else if (type === "odd") {

      }
    }
  return sum
}

Я с такими задачами разбирался с помощью “прогона” на бумажке нескольких конкретных случаев. (и до сих под использую этот метод).

Решение “в лоб”, основываясь на твоем скелете. Идем по всем числам до number. Для каждого числа смотрим чего там в type, и в зависимости от значения уже проверяем нужно ли число добавлять к сумме или нет. Для неожиданного значения в type даем ошибку (не критично, но правильнее с точки зрения моделирования функций).

const getSumOfNumbers = function (number,type = "odd") { 
    let sum =0;
    for (let i = 0; i <= number; i++) {
      if (type === "even") {
        // условие добавления и добавление если надо
      } else if (type === "odd") {
         // условие добавления и добавление если надо
      } else if (type === "") {
         // добавление безусловно
      } else {
        // может бросить тут исключение так как агумент неожидаемого значения
        // throw new Error('Unexpected argument value')
      }
    }
  return sum
}

Есть вериант не в лоб. В котором можно исходить из того что суть четных и нечетных чисел в инкременте на двойку только от разного основания (нечетные 1, 3, 5, 7 …, четные 0, 2, 4, 6, 8). Можно подумать и описать подготовку к циклу так что цикл будет итерировать по четным или нечетным или по всем числам.

Чтобы реализовать подход выше, нужно вынести шаг цикла и число с которого цикл стартует в переменные. И исходя из значения type задать начальные значения в вынесенные переменные. Думаю это единственный неочевидный момент, остальное можно додумать: там код будет без сюрпризов.

let step
let start
// вместо комментария - логика задачи начальных значений ...
for (let i = start; i <= number; i += step) {
   // логика подсчета суммы  в теле цикла ...
}

Как часто бывает одну и ту же задачу можно решить несколькими способами. Метод грубой силы (brut force) вполне приемлем на малом значении number. Но при значении 10^42 вычисление будет проходить очень долго.
Чтоб избежать этого можно воспользоваться математикой. Есть формула расчёта

1 лайк

Всем привет!

Вставлю свои 5 копеек… Если решать задачу с помощью циклов, то сложность алгоритма будет О(n) согласно теории большого О (вот неплохое обучающее видео по теме). А при использовании формулы для вычисления арифметической прогрессии, сложность алгоритма будет О(1), то есть алгоритм будет работать значительно быстрее.
Как сказано выше, условие задачи подходит под вычисление арифметической прогрессии (вот неплохой материал по теме)

Вот мой вариант решения задачи, с использованием формулы для вычисления арифметической прогрессии.

function getSumOfArithmProgession(lastNumber, type = 'odd') {
  if (typeof lastNumber !== 'number' || lastNumber < 0) {
    return NaN;
  }
    
  let n;
  let d;  
  let a1;
  if (type === 'odd') {
    n = Math.ceil((lastNumber + 1) / 2);
    d = 2;
    a1 = 0
  } else if (type === 'even') {
    n = Math.floor((lastNumber + 1) / 2);
    d = 2;
    a1 = 1;
  } else {
    n = lastNumber + 1; 
    d = 1;
    a1 = 0;
  }
     
  return ((2 * a1 + d * (n - 1)) * n) / 2;
}
1 лайк