Ruby算法循环代码大战

时间:2018-11-10 19:09:30

标签: ruby algorithm math

我被困在下面的任务上,花了大约3个小时试图弄清楚。
任务说明:一个人有一辆相当旧的汽车,价值2000美元。他看到一辆二手车价值8000美元。他想保留自己的旧车,直到他可以买二手车。 他认为自己每月可以节省$ 1000,但旧车和新车的价格每月降低1.5%。此外,每两个月末,损失的百分比将增加0.5%。我们的男人发现很难进行所有这些计算。 他要花多少个月的时间来积enough足够的钱来购买他想要的汽车,他还剩下多少钱?

到目前为止,我的代码:

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 :(得分:1)

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

答案 1 :(得分:1)

数据如下。

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个月之后,该人(我们称他为“ Rufus”)的积蓄加上他的汽车价值等于

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的上述方程式,则可能证明Rufus将不得不等待更长的时间。那是因为对于给定的n,两辆车的折旧本钱都将减少(或至少不超过),并且由于要购买的汽车比当前的汽车更昂贵,因此其价值差异将大于获得的价值。与1/n的浮点近似。但是,我们需要检查一下。 n年后,Rufus的积蓄和击败者的价值将等于

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年后,Rufus梦想中的汽车的成本将为

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相同。)

是的,Rufus将能够在6年内购买汽车。