introduzione
In un'elezione generale, si vorrebbe calcolare un prezzo costante per sede parlamentare. Ciò significa che per la N >= 0
distribuzione dei seggi e un elenco ns
di voti per partito, vorremmo trovare un numero d
tale
sum(floor(n/d) for n in ns) == N
Per rendere le cose interessanti (e più simili al mondo reale), aggiungiamo altri due fatti:
Due partiti possono riunirsi in una "coalizione", in modo che i posti siano assegnati alla "coalizione" dalla somma dei voti per tutte le parti in essa contenute. Quindi i posti ottenuti dalla "coalizione" sono divisi tra le parti in modo simile (trova divisore, ecc.)
Un partito che non ha superato una determinata percentuale di voti (ad es. 3,25%) ottiene automaticamente 0 seggi e i suoi voti non contano per una "coalizione".
Sfida
Ti viene dato:
- Un elenco di elenchi, ciascuno degli elenchi nidificati contiene numeri interi (numero di voti) ed è della lunghezza 1 per un singolo partito o della lunghezza 2 per una "coalizione".
- Percentuale minima di voti (alias "bar" per "barrage") per ottenere seggi, in percentuale (quindi il 3,25% è dato come 0,0325)
- Numero totale di seggi da distribuire tra tutte le parti (numero intero)
Devi stampare la stessa struttura di elenco nidificata, con il numero di voti sostituito con seggi parlamentari.
Il vincitore è il codice con il minor numero di byte.
Valigie angolari:
- Potrebbero esserci (e di solito ci saranno) più di un possibile divisore. Dal momento che non è nell'output, non importa davvero.
- Immagina
N=10
ens = [[1]]
, quindi, il divisore può essere 0.1 (non un numero intero) - Alcuni casi non possono essere risolti, ad esempio
ns=[[30],[30],[100]]
,bar=0
,N=20
. C'è un limite ind=7.5
cui la somma dei valori minimi salta da 19 a 21. Non ci si aspetta che tu risolva questi casi. (grazie al membro della comunità Arnauld per aver segnalato questo caso)
Esempio di input e output
Un esempio di Python3 molto non ottimizzato:
from math import floor
def main(_l, bar, N):
# sum all votes to calculate bar in votes
votes = sum(sum(_) for _ in _l)
# nullify all parties that didn't pass the bar
_l = [[__ if __ >= bar * votes else 0 for __ in _] for _ in _l]
# find divisor for all parliament seats
divisor = find_divisor([sum(_) for _ in _l], N)
# find divisor for each 'coalition'
divisors = [find_divisor(_, floor(sum(_)/divisor)) for _ in _l]
# return final results
return [[floor(___/_) for ___ in __] for _, __ in zip(divisors, _l)]
def find_divisor(_l, N, _min=0, _max=1):
s = sum(floor(_ / _max) for _ in _l)
if s == N:
return _max
elif s < N:
return find_divisor(_l, N, _min, (_max + _min) / 2)
else:
return find_divisor(_l, N, _max, _max * 2)
print(main(l, bar, N))
Esempio di input:
l = [[190970, 156473],
[138598, 173004],
[143666, 193442],
[1140370, 159468],
[258275, 249049],
[624, 819],
[1125881],
[152756],
[118031],
[74701]]
bar = 0.0325
N = 120
E il suo output:
[[6, 4], [0, 5], [4, 6], [35, 5], [8, 8], [0, 0], [35], [4], [0], [0]]
Alcuni altri esempi di output:
Se bar=0.1
otteniamo un interessante scontro tra due parti in quanto nessuna delle parti minori viene conteggiata in:
[[0, 0], [0, 0], [0, 0], [60, 0], [0, 0], [0, 0], [60], [0], [0], [0]]
E se N=0
(caso d'angolo), ovviamente, nessuno ottiene nulla:
[[0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0], [0], [0], [0]]
d=7.5
si ottiene un salto da 19 a 21 posti.