2012-06-25 29 views
0

我有这个;从函数的返回值创建表格

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之间最佳切割是椭圆形等

回答

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

的解析解无疑矫枉过正..但是,嘿,我喜欢矫枉过正。

首先,我转化cuts成Y = mx + b中的格式:导致

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) 
] 

对于每对切口的

cuts = [(k, (v1-100)*0.01,-v0) for k,(v0,v1) in cuts.items()] 
cuts.sort() 

,我能找到的交叉点 - 宝石大小其中任一切割的值相同

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个交点,大多数w这是多余的 - 在这一点上,其他一些削减更有价值。因此,我们筛选:

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失去你的钱)。

+0

哇,只是哇:)你真棒。 – yasar