我有这个;
import operator
cuts = { "Emerald" : (10,125),
"Oval" : (20,150),
"Pear" : (35, 175),
"Plumbbob" : (50,200),
"Marquis" : (75, 230),
"Crystal Ball" : (100, 260),
"Brilliant" : (250, 350),
"Star Cut" : (400,400),
"Heart-shaped" : (1000, 500)
}
def best(amount):
"Returns most profitable cut's name."
max_name = ""
max_value = -10000
for k,v in cuts.iteritems():
value = ((float(amount) * (v[1] - 100) / 100)) - v[0]
if value > max_value:
max_value = value
max_name = k
return max_name
def create_table():
"""Creates a table like
0-40 emerald
40-45 Oval
...
2000 + Heart-shaped
"""
但我仍然坚持写create_table
。此代码用于帮助我正在玩的游戏。 best
函数,给定金额,返回该金额最有利可图的剪切名称。我想创建一个显示范围的表格。例如,对于0-40之间的数量,最好的切割是祖母绿,40-45之间的最佳切割是椭圆形等。
答案 0 :(得分:1)
def create_table():
curname = None
for amount in xrange(2500):
name = best(amount)
if name != curname:
if curname is not None:
print "%d-%d %s" % (minamt, amount-1, curname)
curname = name
minamt = amount
print "%d-%d %s" % (minamt, amount-1, curname)
(未经测试,顺便说一句)
答案 1 :(得分:1)
分析解决方案无疑是矫枉过正......但是,嘿,我喜欢矫枉过正。
首先,我将cuts
转换为y = mx + b格式:
cuts = [(k, (v1-100)*0.01,-v0) for k,(v0,v1) in cuts.items()]
cuts.sort()
导致
cuts = [
('Brilliant', 2.5, -250),
('Crystal Ball', 1.6, -100),
('Emerald', 0.25, -10),
('Heart-shaped', 4.0, -1000),
('Marquis', 1.3, -75),
('Oval', 0.5, -20),
('Pear', 0.75, -35),
('Plumbbob', 1.0, -50),
('Star Cut', 3.0, -400)
]
对于每对切割,我可以找到交叉点 - 切割值相同的宝石大小
from itertools import combinations
xints = []
for (na,ma,ba),(nb,mb,bb) in combinations(cuts, 2):
xint = (bb-ba)/(ma-mb)
val = ma*xint + ba
# figure out which cut dominates to the right
va = ma*(xint+0.01)+ba
vb = mb*(xint+0.01)+bb
if vb > va:
xints.append((xint,val,na,nb))
else:
xints.append((xint,val,nb,na))
这导致36个交叉点,其中大多数是多余的 - 其他一些切割在这一点上更有价值。所以我们过滤:
xints = [(xint,val,na,nb) for xint,val,na,nb in xints if all(nc==na or nc==nb or mc*xint+bc <= val for nc,mc,bc in cuts)]
xints.sort()
留下10个有效的交叉点:
[
(40.0, 0.0, 'Emerald', 'Oval'),
(60.0, 10.0, 'Oval', 'Pear'),
(60.0, 10.0, 'Oval', 'Plumbbob'),
(60.0, 10.0, 'Pear', 'Plumbbob'),
(83.33333333333331, 33.333333333333314, 'Marquis', 'Crystal Ball'),
(83.33333333333331, 33.333333333333314, 'Plumbbob', 'Crystal Ball'),
(83.33333333333331, 33.333333333333314, 'Plumbbob', 'Marquis'),
(166.66666666666669, 166.66666666666674, 'Crystal Ball', 'Brilliant'),
(300.0, 500.0, 'Brilliant', 'Star Cut'),
(600.0, 1400.0, 'Star Cut', 'Heart-shaped')
]
通过检查,我们发现梨和马奎斯的削减是多余的 - 它们仅在交叉点处具有竞争力 - 所以我们丢弃它们出现的4个项目,
[
(40.0, 0.0, 'Emerald', 'Oval'),
(60.0, 10.0, 'Oval', 'Plumbbob'),
(83.33333333333331, 33.333333333333314, 'Plumbbob', 'Crystal Ball'),
(166.66666666666669, 166.66666666666674, 'Crystal Ball', 'Brilliant'),
(300.0, 500.0, 'Brilliant', 'Star Cut'),
(600.0, 1400.0, 'Star Cut', 'Heart-shaped')
]
是最佳交叉点;然后你的桌子看起来像
Size Value Cut
---- ----- ------------
0 -10
Emerald
40 0
Oval
60 10
Plumbbob
83.33 33.33
Crystal Ball
166.67 166.67
Brilliant
300 500
Star Cut
600 1400
Heart-shaped
严格来说,你可以放弃祖母绿切割,因为预期的值是负的(在任何小于40的宝石上切割会损失你的钱)。