Рубиновые алгоритмы зацикливают кодовые войны - PullRequest
0 голосов
/ 10 ноября 2018

Я застрял с задачей ниже и потратил около 3 часов, пытаясь понять это.
Описание задачи: У человека довольно старая машина стоимостью 2000 долларов. Он увидел подержанную машину стоимостью 8000 долларов. Он хочет оставить свою старую машину, пока не купит подержанную. Он думает, что может сэкономить 1000 долларов в месяц, но цены на его старый автомобиль и новый снижаются на 1,5 процента в месяц. Кроме того, этот процент потерь увеличивается на 0,5 процента в конце каждых двух месяцев. Нашему человеку сложно сделать все эти расчеты. Сколько месяцев ему понадобится, чтобы накопить достаточно денег, чтобы купить автомобиль, который он хочет, и сколько денег у него останется?

Пока мой код:

def nbMonths(startPriceOld, startPriceNew, savingperMonth, percentLossByMonth)
  dep_value_old = startPriceOld    
  mth_count = 0
  total_savings = 0
  dep_value_new = startPriceNew
  mth_count_new = 0
  while startPriceOld != startPriceNew do    
    if startPriceOld >= startPriceNew
      return mth_count = 0, startPriceOld - startPriceNew
    end    
    dep_value_new = dep_value_new - (dep_value_new * percentLossByMonth / 100)
    mth_count_new += 1
    if mth_count_new % 2 == 0
      dep_value_new = dep_value_new - (dep_value_new * 0.5) / 100
    end
    dep_value_old = dep_value_old - (dep_value_old * percentLossByMonth / 100)
    mth_count += 1
    total_savings += savingperMonth
    if mth_count % 2 == 0
      dep_value_old = dep_value_old - (dep_value_old * 0.5) / 100
    end
    affordability = total_savings + dep_value_old
    if affordability >= dep_value_new
      return mth_count, affordability - dep_value_new
    end
  end
end

print nbMonths(2000, 8000, 1000, 1.5) # Expected result[6, 766])

Ответы [ 2 ]

0 голосов
/ 11 ноября 2018

Данные следующие.

op = 2000.0  # current old car value
np = 8000.0  # current new car price
sv = 1000.0  # annual savings
dr = 0.015   # annual depreciation, both cars (1.5%)
cr = 0.005.  # additional depreciation every two years, both cars (0.5%)

После n >= 0 месяцев мужская (назовем его "Руфус") экономия плюс стоимость его машины, равная

sv*n + op*(1 - n*dr - (cr + 2*cr + 3*cr +...+ (n/2)*cr))

, где n/2 - целочисленное деление. Как

cr + 2*cr + 3*cr +...+ (n/2)*cr = cr*((1+2+..+n)/2) = cr*(1+n/2)*(n/2)

выражение становится

sv*n + op*(1 - n*dr - cr*(1+(n/2))*(n/2))

Аналогичным образом, через n лет стоимость машины, которую он хочет приобрести, упадет до

np * (1 - n*dr - cr*(1+(n/2))*(n/2))

Если мы установим эти два выражения равными, мы получим следующее.

sv*n + op - op*dr*n - op*cr*(n/2) - op*cr*(n/2)**2 =
np - np*dr*n - np*cr*(n/2) - np*cr*(n/2)**2

, который уменьшается до

cr*(np-op)*(n/2)**2 + (sv + dr*(np-op))*n + cr*(np-op)*(n/2) - (np-op) = 0

или

cr*(n/2)**2 + (sv/(np-op) + dr)*n + cr*(n/2) - 1 = 0

Если мы на мгновение рассматриваем (n / 2) как деление с плавающей точкой, это выражение сокращается до квадратичного.

(cr/4)*n**2 + (sv/(np-op) + dr + cr/2)*n - 1 = 0
  = a*n**2 + b*n + c = 0

, где

a = cr/4 = 0.005/4 = 0.00125
b = sv/(np-op) + dr + cr/(2*a) = 1000.0/(8000-2000) + 0.015 + 0.005/2 = 0.18417
c = -1

Кстати, у Руфуса нет компьютера, но у него есть калькулятор HP 12c, который ему дал дедушка, когда он был ребенком, что вполне подходит для этих простых вычислений.

Корни вычисляются следующим образом.

(-b + Math.sqrt(b**2 - 4*a*c))/(2*a)  #=>    5.24
(-b - Math.sqrt(b**2 - 4*a*c))/(2*a)  #=> -152.58

Похоже, что Rufus может приобрести новое транспортное средство (если оно все еще продается) через шесть лет. Если бы мы смогли решить вышеприведенное уравнение для n/2, используя целочисленное деление, могло бы оказаться, что Руфусу пришлось бы ждать дольше. Это связано с тем, что для данного n оба автомобиля амортизировались бы меньше (или, по крайней мере, не более), и поскольку приобретаемый автомобиль дороже, чем текущий, разница в значениях была бы больше, чем у аппроксимация с плавающей точкой для 1/n. Мы должны проверить это, однако. По истечении n лет сбережения Руфуса и стоимость его битера будут равны

sv*n + op*(1 - dr*n - cr*(1+(n/2))*(n/2))
  = 1000*n + 2000*(1 - 0.015*n - 0.005*(1+(n/2))*(n/2))

Для n = 6 это равно

1000*6 + 2000*(1 - 0.015*6 - 0.005*(1+(6/2))*(6/2))
  = 1000*6 + 2000*(1 - 0.015*6 - 0.005*(1+3)*3)
  = 1000*6 + 2000*0.85
  = 7700

Стоимость машины мечты Руфуса после n лет составит

np * (1 - dr*n - cr*(1+(n/2))*(n/2))
  = 8000 * (1 - 0.015*n - 0.005*(1+(n/2))*(n/2))

Для n=6 это становится

8000 * (1 - 0.015*6 - 0.005*(1+(6/2))*(6/2))
  = 8000*0.85
  = 6800

(Обратите внимание, что коэффициент 0.85 одинаков в обоих расчетах.)

Да, Руфус сможет купить машину через 6 лет.

0 голосов
/ 10 ноября 2018
def nbMonths(old, new, savings, percent)
  percent = percent.fdiv(100)
  current_savings = 0
  months = 0
  loop do
    break if current_savings + old >= new
    current_savings += savings
    old -= old * percent
    new -= new * percent
    months += 1
    percent += 0.005 if months.odd?
  end
  [months, (current_savings + old - new).round]
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...