我要解决的问题是:
“哈姆雷特的三个女巫只要有
正确的成分假设
制作保健药水:蝾螈眼(EON)、青蛙趾(TOF)、羊毛
蝙蝠(wob),加法器叉(af),狼牙(tow)四种反应
可能>发生在这些成分之间:
4eon+2wob=3af+4tow
3拖+1拖=2 eon
1钻压+2 af=1 tof
4tof+7tow+2af=1健康药水
假设你能控制反应的顺序,写一个程序
可以计算出一个可以用一个
一定量的配料。下面是输出示例:如果我有34个eon,
59 tof,20 wob,5 af和20 tow,我可以制作七种保健药水。”
摘录自:欧菲弗里德,吉迪恩弗里德和大卫格罗斯曼。
“Ruby的计算机科学编程基础。”iBooks。
我的解决方案是:

ingredients = Hash.new
potion = 0

puts "Welcome to potion brewer! To make a health potion you must combine 4 TOF + 7 TOW + 2 AF. Let's get started.\n\n"

puts "How many EON do you have?"

ingredients["EON"] = gets.to_i

puts "How many TOF do you have?"

ingredients["TOF"] = gets.to_i

puts "How many WOB do you have?"

ingredients["WOB"] = gets.to_i

puts "How many AF do you have?"

ingredients["AF"] = gets.to_i

puts "How many TOW do you have?"

ingredients["TOW"] = gets.to_i


while (ingredients["EON"] >= 4 and ingredients["WOB"] >= 2)
    ingredients["AF"] += 3
    ingredients["TOW"] += 4
    ingredients["EON"] -= 4
    ingredients["WOB"] -= 2
    # ==/== DEBUG ==/==
#    puts "4 EON and 2 WOB convereted into +3 AF and +4 TOW."
#    puts ingredients["EON"]
#    puts ingredients["WOB"]
end
while ((ingredients["TOF"]/4) < (ingredients["AF"]/2))
   ## puts "debug"
    if (ingredients["WOB"] >= 1 and ingredients["AF"] >= 2)
        ingredients["TOF"] += 1
        ingredients["WOB"] -= 1
        ingredients["AF"] -= 2
   #     puts "1 WOB and 2 AF converted to +1 TOF."
    else
    break
    end
end
while (ingredients["TOF"] >= 4 and ingredients["TOW"] >= 7 and ingredients["AF"] >= 2)
    potion += 1
    ingredients["TOF"] -= 4
    ingredients["TOW"] -= 7
    ingredients["AF"] -= 2
    # ==/== DEBUG ==/==
    #puts "Potion created.."
end


puts "\n\nMade #{potion} potion(s).\n\n"

for name in ingredients.keys
puts "You have " + ingredients[name].to_s + " " + name + " left.\n"
end

不管怎样,这是我能想到的解决问题的“最整洁的”。我想我正确地安排了转换顺序,这样就不会在制作药水时出现任何低效的情况……而且我从书中的例子得到了期望的结果。
任何人都可以确认它看起来还行吗?我没有错过一些主要的优化,可以进一步最大化我的药剂吗?我找不到与第三次转换(1wob+2af=1tof)有多大关系。
谢谢!

最佳答案

有趣的问题!
所以让我们换个说法:目标是计算“健康”药水,如果这个药水的任何成分丢失,找到其他可以用来制造丢失成分的药水。
这听起来是一个递归算法。
所以,首先,让我们模拟一下“制造药剂”的问题。
假设e有一个药水公式,一个包含所有必需成分(负值)的散列,以及由此产生的ingreident正值。
例如:

4 eon + 2 wob = 3 af + 4 tow

可以写成:
formulae={:eon=>-4,:wob=>-2,:af=>3,:tow=>4}

因此,计算公式将非常简单:
def compute_formulae ingredients,formulae
   result=ingredients.clone
   formulae.each do |needed,amount|
     if ingredients[needed]<-amount
        puts "Missing #{needed}" # The is an ingredient missing, we should probably exit now
        return nil
     else
        result[needed]+=amount
     end
   end
   result
end

现在的问题是当缺少一种成分时该怎么办我们必须找到一个公式,我们可以用来“创造它”,根据我们现有的成分,在公式的列表中。
formulas=[
 {:tof=>-4,:tow=>-7,:af=>-2,:health=>1},
 {:eon=>-4,:wob=>-2,:af=>3,:tow=>4},
 {:tow=>-3,:tof=>-1,:eon=>2},
 {:wob=>-1,:af =>-2,:tof=>1}
  ]
formulas.each{|f| f.default=0} # Just ensure that there is de fault value for all ingredients


def find_missing_ingredient ingredients,formulas,missing
   formulas.each do | formulae |
      if formulae[missing]>0
        compute_formulae_ingredient ingredients,formulae
      end
   end
end

# so basically, the problem is
ingredients={:eon=>34,:tof=>59,:wob=>20,:af=>5,:tow=>20}
ingredients.default=0

while find_missing_ingredient ingredients,formulas,:health
end

现在,有一些小细节,比如主循环(我们需要继续,只要我们能得到新的“健康”,错误(何时停止在这个递归循环),输入部分,但我把这个留给了读者!

关于ruby - 使用 ruby 中的成分和配方转换来优化药水冲泡程序?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26440997/

10-10 05:07