2012-11-19 43 views
6

我想編寫一個標準的蛇草稿,其中A隊選秀,B隊,C隊,C隊,B隊,A隊,ad nauseum。向上計數然後向下在python中的範圍

如果選擇第13號(或選號x)剛剛發生,我怎樣才能確定哪支球隊接下來會選擇n支球隊。

我有類似:

def slot(n,x): 
    direction = 'down' if (int(x/n) & 1) else 'up' 
    spot = (x % n) + 1 
    slot = spot if direction == 'up' else ((n+1) - spot) 
    return slot 

我都感覺有一種更簡單,更Python還有什麼比這個解決方案。任何人都在意對它進行破解?

所以我多玩了一會兒。我正在尋找單個值的返回值,而不是計算循環列表的最佳方式。最直接的答案可能是:

def slot(n, x): # 0.15757 sec for 100,000x 
    number_range = range(1, n+1) + range(n,0, -1) 
    index = x % (n*2) 
    return number_range[index] 

這會創建一個列表[1,2,3,4,4,3,2,1],計算出索引(例如13%(4 * 2)= 5),然後從列表中返回索引值(例如4)。列表越長,功能越慢。

我們可以使用一些邏輯將列表製作成一半。如果我們計數(即(int(x/n) & 1)返回False),我們得到了明顯的指數值(X%N),否則我們減去N + 1的那個值:

def slot(n, x): # 0.11982 sec for 100,000x 
    number_range = range(1, n+1) + range(n,0, -1) 
    index = ((n-1) - (x % n)) if (int(x/n) & 1) else (x % n) 
    return number_range[index] 

仍然避免完全名單最快:

def slot(n, x): # 0.07275 sec for 100,000x 
    spot = (x % n) + 1 
    slot = ((n+1) - spot) if (int(x/n) & 1) else spot 
    return slot 

如果我持有的列表作爲變量,而不是產卵之一:

number_list = [1,2,3,4,5,6,7,8,9,10,11,12,12,11,10,9,8,7,6,5,4,3,2,1] 
def slot(n, x): # 0.03638 sec for 100,000x 
    return number_list[x % (n*2)] 
+0

如果組隊數n,以及球隊1號,之交連續兩次挑? –

+0

是的。車隊1和車隊n在轉彎時有兩個連續的選擇。 – Cole

回答

7

爲什麼不使用itertools cycle功能:

from itertools import cycle 
li = range(1, n+1) + range(n, 0, -1) # e.g. [1, 2, 3, 4, 4, 3, 2, 1] 
it = cycle(li) 

[next(it) for _ in xrange(10)] # [1, 2, 3, 4, 4, 3, 2, 1, 1, 2] 

注:前面我已經回答瞭如何跑上跑下,如下:

it = cycle(range(1, n+1) + range(n, 0, -1)) #e.g. [1, 2, 3, 4, 3, 2, 1, 2, 3, ...] 
+0

順序應該是[1,2,3,4,4,3,2,1,1,2,...] ..那麼我還有什麼要做的循環功能? – Cole

+0

@科爾更新... –

5

這裏有一臺發電機,將滿足你想要的。

def draft(n): 
    while True: 
     for i in xrange(1,n+1): 
      yield i 
     for i in xrange(n,0,-1): 
      yield i 

>>> d = draft(3) 
>>> [d.next() for _ in xrange(12)] 
[1, 2, 3, 3, 2, 1, 1, 2, 3, 3, 2, 1] 
3
from itertools import chain, cycle 

def cycle_up_and_down(first, last): 
    up = xrange(first, last+1, 1) 
    down = xrange(last, first-1, -1) 
    return cycle(chain(up, down)) 

turns = cycle_up_and_down(1, 4) 
print [next(turns) for n in xrange(10)] # [1, 2, 3, 4, 4, 3, 2, 1, 1, 2]