ruby 中的尾递归产生条件之前和条件之后的总和?

Tail recursion in ruby producing a sum of total before conditional and after conditional?

所以我试图从数组中求和,但是一旦总数超过 8000,它应该将添加的数量减少 50%。我似乎得到了 if 条件前后的总和。任何人都可以解释为什么以及如何解决它吗?

arr = [{ add_on: "AWD Drivetrain", price: 2500 }, { add_on: "Sport Package", price: 3500 }, { add_on: "Winter Tire Package", price: 2000 }, { add_on: "GPS Navigation", price: 2000 },]

def calculate_price_recursive(arr)
  prices = arr.sort_by { |x| -x[:price] }.map { |x| x[:price] }
  return recur_sum(prices, 0)
end


def recur_sum(prices, total)
  puts "#{prices}"
  return total if prices.count == 0
  if total < 8000
    prices[0] + recur_sum(prices[1..-1], total + prices[0])
  else
    (prices[0] / 2) + recur_sum(prices[1..-1], total + prices[0])
  end
end

\\对于 Arr 中的元素:

\\\\如果元素总和 < 8300

\\\\\\元素总和=元素总和+元素

\\\\其他

\\\\\\ElementSum = ElementSum + (Element / 2)

我加了两次东西。

def recur_sum(prices, total)
  puts "#{prices}"
  return total if prices.count == 0
  if total < 8000
    recur_sum(prices[1..-1], total + prices[0])
  else
    recur_sum(prices[1..-1], total + prices[0] / 2)
  end
end

我找到了一种在一个函数中递归完成整个事情的方法:

def recur_sum_holistic(arr, base, check, constant)
  if check == 1
    constant = arr.map { |x| x[:add_on] }.join(', ')
  end
  return "The cost for this car is $#{((base + (((base - 24999) * 0.02) + 1200)) * 1.13).round(2)} with the following configuration: #{constant}" if arr.count == 0
  recur_sum_holistic(arr[1..-1], base + (arr[0][:price] / (base < (24999 + 8000) ? 1 : 2)), 2, constant)
end

Ruby 默认没有启用 TCO。要明确启用它,应该这样做:

RubyVM::InstructionSequence.compile_option = {
  tailcall_optimization: true,
  trace_instruction: false
}

也就是说,结果可能看起来像

RubyVM::InstructionSequence.compile_option = {
  tailcall_optimization: true,
  trace_instruction: false
}

arr = [
  { add_on: "AWD Drivetrain", price: 2500 },
  { add_on: "Sport Package", price: 3500 },
  { add_on: "Winter Tire Package", price: 2000 },
  { add_on: "GPS Navigation", price: 2000 }
]

def calculate_price_recursive(arr)
  prices = arr.map { |x| x[:price] }.sort.reverse
  recur_sum(prices)
end

def recur_sum(prices, total = 0)
  return total if prices.count == 0
  recur_sum(
    prices[1..-1],
    total + prices[0] / (total < 8000 ? 1 : 2)
  )
end