2012-06-25 65 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