2012-11-19 3 views
6

Ich versuche, einen Standard Snake Draft zu programmieren, wo Team A wählen, Team B, Team C, Team C, Team B, Team A, ad nauseuse.aufwärts zählen und dann einen Bereich in Python

Wenn Auswahl Nummer 13 (oder Auswahl Nummer x) einfach passiert ist, wie kann ich herausfinden, welches Team als nächstes für n Anzahl von Teams wählt.

Ich habe so etwas wie:

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 

Ich habe das Gefühl es eine einfachere, pythonic was als diese Lösung. Wer kümmert sich darum, einen Hack zu nehmen?

Also spielte ich ein wenig mehr herum. Ich bin auf der Suche nach der Rückgabe eines einzelnen Werts, anstatt der beste Weg, über eine geloopte Liste zu zählen. Die wörtliche Antwort sein könnte:

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] 

Dies erzeugt eine Liste [1,2,3,4,4,3,2,1], die Indexzahlen (zB 13% (4 * 2) = 5) und gibt dann den Indexwert aus der Liste zurück (z. B. 4). Je länger die Liste, desto langsamer die Funktion.

Wir können eine Logik verwenden, um die Liste zu halbieren. Wenn wir zählen auf (dh (int(x/n) & 1) gibt False zurück), so erhalten wir den offensichtlichen Indexwert (x% n), sonst ziehen wir diesen Wert von 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] 

Noch eine Liste ganz zu vermeiden ist am schnellsten:

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 

Und wenn ich die Liste als Variable halten, anstatt ein Laichen:

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

Sollte Anzahl n Team sowie Team Nummer 1, an der wiederum zweimal in Folge ausgewählt? –

+0

ja. Team 1 und Team n haben am Turn zwei aufeinanderfolgende Picks. – Cole

Antwort

7

Warum itertools nicht cycle Funktion:

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] 

Hinweis: vorher hatte ich geantwortet, wie hoch und runter laufen, wie folgt:

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

Ordnung sollte sein [1,2,3,4,4,3,2,1,1,2, ...] .. was mache ich sonst mit der Zyklusfunktion? – Cole

+0

@Cole aktualisiert ... –

5

hier ein Generator ist, der wird erfüllt, was Sie wollen.

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] 
Verwandte Themen