我要解决的问题是:
“哈姆雷特的三个女巫只要有
正确的成分假设
制作保健药水:蝾螈眼(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/