Вечный вопрос - ошибка


#1
var simpleDeposit = function(startDeposite, percent, months) {
  var generalPercent = startDeposite * (percent / 12 * months + 100) / 100;
  return Math.floor(generalPercent);
}

var smartDeposite = function(startDeposite, percent, months) {
  for (var i = 1; i < months; i++) {
    startDeposite *= (100 + percent / 12) / 100;
  }
  return Math.floor(startDeposite);
}

var getProfitableDeposit = function (startDeposite, months, simplePercent, smartPercent) {
  var firstVar = simpleDeposit(startDeposite, simplePercent, months);
  var secondVar = smartDeposite(startDeposite, smartPercent, months);
  console.log(firstVar);
  console.log(secondVar);
   if (firstVar > secondVar) {
     return 'Выбирай обычный вклад. Заработаешь ' + firstVar;
   }
   else{
     return 'Выбирай капитализацию. Заработаешь ' + secondVar;
   }
  
}

Извините, я снова не могу победить эту программу. Помогите ауту найти причину, почему не работает корректно программа при вкладе с капитализацией :smiley:


#2

@GreenLera подозрение на нерабочую (третью) проверку с капитализацией

Задание поменяли, теперь у меня тоже не работает:

моё
let calculateDeposit = function(deposit, percent, duration, isCapitalization) {
  if (!isCapitalization) {
    deposit *= (100+percent/12*duration)/100; 
  } else {
      for (let i = 0; i < duration; i++) {
        deposit *= (100+percent/12)/100;
      }
    }
  return Math.round(deposit);  
}

let getProfitableDeposit = function(deposit, duration, simplePercent, complexPercent) {
  let simple = calculateDeposit(deposit, simplePercent, duration, false);
  let complex = calculateDeposit(deposit, complexPercent, duration, true);
  let recommendedType = 'капитализацию';
  let finalAmount = complex;
  
  if (complex <= simple) {
    recommendedType = 'обычный вклад';
    finalAmount = simple;
  } 
  return `Выбирай ${recommendedType}. Заработаешь ${finalAmount}`;
}
getProfitableDeposit(250000, 14, 7, 6.8);

#3

Проверим, спасибо.


#4

Здравствуйте, я сейчас проверила, у меня все проверки проходят.

1 - надо округлять теперь вниз через floor
2 - можете объяснить свою формулу? Почему именно такое решение? Почему вы прибавляете 100?


#5

так, при применении Math.floor теперь выбивается вторая проверка, а третья проходит нормально.
повторюсь, что при ручном выводе результаты корректны. т.е. нормально выбивает шаблонную строку, арифметика верна.

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

полное объяснение под катом

Простой депозит: считаем проценты:

  1. Годовой процент делим на 12, чтобы получить месячный. умножаем его на месяцы.
    yearPercent / 12 * months
  2. Столько процентов мы получим за весь срок вклада. У нас уже было 100% от депозита. к ним добавляем посчитанное.
    100 + yearPercent / 12 * months
  3. Делим на 100, чтобы получить размерность в долях. Вот во столько раз увеличится наша сумма.
    (100 + yearPercent / 12 * months) / 100
  4. Осталось умножить это на сумму, чтобы узнать скока получим.
    startSum * (100 + yearPercent / 12 * months) / 100
  5. Запишем сам депозит в локальную переменную startSum (та, которая у нас параметр).
    startSum = startSum * (100 + yearPercent / 12 * months) / 100
  6. Сократим запись
    startSum *= (100 + yearPercent / 12 * months) / 100

Сложный процент: тут нужен цикл:

  1. Каждый месяц идет пересчет, так что цикл ограничен количеством месяцев
    for (var i = 1; i <= months; i++) ну или for (var i = 0; i < months; i++)
  2. Нам надо знать месячный прирост, т.е. прирост за каждый месяц: это yearPercent / 12 (пока в процентах )
  3. У нас уже было 100%, к ним мы добавляем месячный прирост в процентах : 100 + yearPercent / 12
  4. Возвращаем размерность дроби к долям : (100 + yearPercent / 12) / 100
  5. Умножаем на собственно сумму депозита и узнаем, сколько получаем в первую итерацию нашего цикла первый месяц
    startSum * (100 + yearPercent / 12) / 100
  6. Перезапишем значение в локальную переменную – параметр.
    startSum = startSum * (100 + yearPercent / 12) / 100
  7. Сократим запись:
    startSum *= (100 + yearPercent / 12) / 100

по факту имеем 2 правильные формулы:
X = X + X * Y ==>

  1. X += X*Y
  2. X = X (1 + Y) ==> X *= 1 + Y

И вот вторую формулу проверка не принимает. А вывод строки одинаковый и там и там.

вот с этой формулой проверки проходят нормально
let calculateDeposit = function(deposit, percent, duration, isCapitalization) {
  if (!isCapitalization) {
    deposit += deposit*percent/12*duration/100; 
  } else {
      for (let i = 0; i < duration; i++) {
        deposit += deposit*percent/12/100;
      }
    }
  return Math.floor(deposit);  
}

let getProfitableDeposit = function(deposit, duration, simplePercent, complexPercent) {
  let simple = calculateDeposit(deposit, simplePercent, duration, false);
  let complex = calculateDeposit(deposit, complexPercent, duration, true);
  let recommendedType = 'капитализацию';
  let finalAmount = complex;
  
  if (complex <= simple) {
    recommendedType = 'обычный вклад';
    finalAmount = simple;
  } 
  return `Выбирай ${recommendedType}. Заработаешь ${finalAmount}`;
}
getProfitableDeposit(250000, 14, 7, 6.8);

Вечный вопрос 11/11
#6

for (var i = 1; i < months; i++)

c 0 счетчик цикла, если строгое неравенство.
и проверка пройдет


#7

там вообще неравенства нет, там сравнение
как раз от нуля до длительности будет расстояние в длительность
там либо i = 0 и <
либо i = 1 и <=
подставьте, все равно проверки не пройдут как вы говорите.


#8

Подставила. Прошли. Строгое неравенство это знак меньше в данном случае :slight_smile: если строго меньше, то считаем с нуля.

У @neatomaru именно в этом была ошибка.


#9

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


#10

Странно, я нажимала как раз ссылку Ответить у верхнего сообщения.


#11

все, мы с @zateya разобрались почему так выходит, в общем если у задачи есть решение через *= и +=, то следует применять последнее, если применяется метод Math.floor или Math.ceil. Вопрос в принципе снят.
Я так понимаю Math.floor применяется тут, потому что банкиры жадные и им жалко один рупь, на этом округлении и зарабатывают =)