Riguardo al discorso dell'indice ho cercato di ragionare in astratto, nel senso che noi non dovremmo sapere l'implementazione interna della funzione (se usa indici, liste, varie ed eventuali), ma usarla per operare nel dominio del problema, che consiste di N disgraziati numerati da 1 a N (ma al posto dei numeri potrebbero esserci i nomi delle persone o di animali ecc), e da uno di quei numeri/nomi dobbiamo partire.
In effetti i fortunati potrebbero anche essere mescolati senza alcun riferimento agli indici usati nella funzione:
Codice: Seleziona tutto
#Py3
import random
SLAVES = 9
STEP = 5
START = random.randrange(SLAVES) + 1
#-------------------------------------------------------------
def g_flavio(lista, passo, start):
i = lista.index(start);
while len(lista) > 1:
killed = lista.pop(i)
print("kill: {} {}".format(killed, lista))
i = (i + passo - 1) % len(lista)
return lista[0]
#-------------------------------------------------------------
lista = list(range(1, SLAVES+1))
random.shuffle(lista)
print("lista originale: {}\n{}".format(lista, "-"*25))
survivor = g_flavio(lista[:], passo=STEP, start=START)
print("sopravvissuto: {}".format(survivor))
Alcune esecuzioni:
Codice: Seleziona tutto
[2, 3, 6, 7, 1, 4, 9, 5, 8]
-------------------------
kill: 8 [2, 3, 6, 7, 1, 4, 9, 5]
kill: 1 [2, 3, 6, 7, 4, 9, 5]
kill: 3 [2, 6, 7, 4, 9, 5]
kill: 5 [2, 6, 7, 4, 9]
kill: 9 [2, 6, 7, 4]
kill: 2 [6, 7, 4]
kill: 7 [6, 4]
kill: 4 [6]
sopravvissuto: 6
Codice: Seleziona tutto
[9, 7, 2, 1, 5, 6, 8, 3, 4]
-------------------------
kill: 5 [9, 7, 2, 1, 6, 8, 3, 4]
kill: 9 [7, 2, 1, 6, 8, 3, 4]
kill: 8 [7, 2, 1, 6, 3, 4]
kill: 1 [7, 2, 6, 3, 4]
kill: 2 [7, 6, 3, 4]
kill: 6 [7, 3, 4]
kill: 4 [7, 3]
kill: 7 [3]
sopravvissuto: 3
Codice: Seleziona tutto
[3, 4, 1, 5, 8, 9, 7, 2, 6]
-------------------------
kill: 1 [3, 4, 5, 8, 9, 7, 2, 6]
kill: 2 [3, 4, 5, 8, 9, 7, 6]
kill: 8 [3, 4, 5, 9, 7, 6]
kill: 4 [3, 5, 9, 7, 6]
kill: 3 [5, 9, 7, 6]
kill: 5 [9, 7, 6]
kill: 7 [9, 6]
kill: 6 [9]
sopravvissuto: 9
Riguardo al controllo di cosa si passa alla funzione... in genere in un esempio/esercizio si assume che i dati in ingresso siano "well-formed", altrimenti, se si prevede che nell'utilizzo reale possano essere incongruenti, ci si dovrebbe chiedere in quale modo sensato per il dominio del problema vada fatta la gestione degli errori.
Per me non ha senso nell'uso reale passare una lista vuota ottenendo nessun sopravvissuto, come non ha senso che il boia entri in una stanza vuota ed esca dicendo che non è sopravvissuto nessuno... nel caso reale il boia entrerebbe e griderebbe "ma qui non c'è nessuno!", quindi secondo me la funzione dovrebbe incazzarsi di brutto:
Codice: Seleziona tutto
def g_flavio(lista, passo, start):
if not lista or start not in lista:
raise ValueError("Lista vuota o elemento di partenza mancante")