Es ist Wahlzeit!

13

Es ist Zeit ... die Stimmen zu zählen!

Heute finden in meinem ganzen Land Kommunalwahlen statt. Hier wird die Anzahl der Sitze für jede Partei nach der D'Hondt-Methode festgelegt . Ihr Ziel ist es, ein Programm oder eine Funktion zu implementieren, die in kürzester Zeit entscheidet, wie viele Sitze jede Partei erhält.

Für diese Methode gibt es eine feste Anzahl von zu verteilenden Plätzen. Dies geschieht folgendermaßen:

  1. Jeder Partei wird eine variable Nummer zugewiesen, die mit der Anzahl der abgegebenen Stimmen beginnt.
  2. Dann wird der erste Sitz an die Partei vergeben, die den größten Wert in ihrer Variablen hat, und dieser Wert für diese Partei ergibt sich aus der Gesamtzahl der durch dividierten Stimmen 1+seats, abgerundet nach seatsder Anzahl der Sitze, die sie bereits hat (also nach dem Erhalt der Zunächst werden ihre Stimmen durch 2 und nach Erreichen des zweiten Sitzes durch 3 geteilt.
  3. Danach werden die Stimmen der Parteien erneut verglichen. Der Vorgang wird fortgesetzt, bis alle Sitze zugewiesen wurden.

Wenn die höchste Zahl ein Gleichstand zwischen zwei oder mehr Parteien ist, wird sie zufällig aufgelöst (Es muss zufällig sein, es kann nicht nur die erste der beiden in der Liste sein).

Eingang

Sie erhalten eine Nummer N, die die Anzahl der verfügbaren Plätze angibt, und eine Liste der Stimmen, die jede Partei erhalten hat, in dem von Ihnen bevorzugten Format. Beispiel:

25
12984,7716,13009,4045,1741,1013

Ausgabe

Sie sollten eine Liste der Sitze jeder Partei ausgeben. Im obigen Beispiel wäre es so etwas wie

8,5,9,2,1,0

Sie sollten in der gleichen Reihenfolge wie die Parteien in der Eingabe sein.

Beispiele

5
3,6,1

outputs: 2,3,0

135
1116259,498124,524707,471681,359705,275007,126435

outputs: 45,20,21,19,14,11,5

Bonus

-20% Bonus, wenn der Name der Partei als Eingabe genommen und in der Ausgabe angegeben wird, wie zum Beispiel:

25
cio:12984,pcc:7716,irc:13009,icb:4045,cub:1741,bb:1013

outputs

cio:8
pcc:5
irc:9
icb:2
cub:1
bb:0
rorlork
quelle
Ich glaube, wir haben schon so etwas gemacht
edc65
Ich konnte in der Suche nichts Ähnliches finden ... Aber wenn Sie etwas finden, werde ich es ändern oder die Frage entfernen, kein Problem!
rorlork
@rcrmn Mit Ihrem letzten Beispiel stimmt etwas nicht. Vielleicht meinten Sie 153 Sitzplätze statt 135.
Tyilo
@ Tyilo Richtig! Ich habe es in meinem Testprogramm falsch geschrieben und die Antworten ohne Überprüfung kopiert. Es ist jetzt behoben. Vielen Dank!
Lorlork
1
Danke @Jakube, das war ein Problem mit dem Programm, das ich verwendet habe, um zu berechnen, das die Ausgabe zurückgab, die in Sitzen mit Aufklebern bestellt wurde. Dennis Sie können es in beliebiger Reihenfolge zurückgeben, da das Etikett als Identifikator fungiert. Sie können davon ausgehen, dass es nur Buchstaben enthält, wenn es für Sie einfacher ist.
rorlork

Antworten:

6

CJam, 35,2 28,8 28,0 26,4

q2*~,m*mr{~)f/1=~}$<:(f{1$e=1\tp}

Dieses vollständige Programm ist 33 Byte lang und qualifiziert sich für den Bonus.

Probieren Sie es online im CJam-Interpreter aus .

Beispiellauf

$ cjam seats <<< '[["cio"12984]["pcc"7716]["irc"13009]["icb"4045]["cub"1741]["bb"1013]]25'
["cio" 8]
["pcc" 5]
["irc" 9]
["icb" 2]
["cub" 1]
["bb" 0]

Wie es funktioniert

q2*~   e# Repeat the input from STDIN twice. Evaluate.
       e# STACK: Array seats Array seats
,      e# Range: seats -> [0 ... seats-1]
m*     e# Take the cartesian product of the array from the input and the range.
mr     e# Shuffle the array. This makes sure tie breakers are randomized.
{      e# Sort by the following key:
  ~    e#     Dump: [["party" votes] number] -> ["party" votes] number
  f/   e#     Divide each: ["party" votes] number -> ["party"/number votes/number]
  1=   e#     Select: ["party"/number votes/number] -> votes/number
  ~    e#     Bitwise NOT.
}$     e#
<      e# Keep only the elements that correspond to seats.
:(     e# Shift each array.
       e# RESULT: S := [[number] ["party" votes] [number] ["party" votes] ...]
f{     e# For each A := ["party" votes]:
       e#     Push S.
  1$   e#     Push a copy of A.
  e=   e#     Count the occurrences of A in S.
  1\t  e#     Replace the vote count with the number of occurrences.
  p    e#     Print.
}      e#
Dennis
quelle
6

Pyth, 36 Bytes - 20% = 28,8

J<_hCo/@eCQhNheN.S*UQUvzvz.e,b/JkhCQ

Dies qualifiziert sich für den Bonus.

Probieren Sie es online aus: Vorführ- oder Testgeschirr

Erläuterung:

                                       implicit: z = 1st input (as string)
                                                 Q = 2nd input (evaluated)

                      vz               evaluate z (#seats)
                     U                 generate the list [0,1,...,seats-1]
                   UQ                  generate the list [0,1,...,len(Q)-1]
                  *                    Cartesian product of these lists
                .S                     shuffle (necessary for break ties randomly)
     o                                 order these tuples N by:
        eCQ                               list of votes
       @   hN                             take the N[0]th vote count
      /      heN                          and divide by N[1]+1
   hC                                  extract the party index of the tuples
  _                                    reverse the list
 <                      vz             take the first #seats elements
J                                      and store them in J

                          .e     hCQ   enumerated map over the names of the parties
                                       (k = index, b = name):
                            ,             generate the pair:
                             b/Jk            name, J.count(k)
                                       print implicitely
Jakube
quelle
Jist unnötig. Sie können es loswerden und 2 Bytes sparen.
isaacg
Wenn Sie tauschen zund Qspeichern Cvz, Kkönnen Sie auch ein weiteres Byte speichern.
isaacg
@isaacg Nein, es ist sehr wichtig. Aufgrund des Mischens kann der Ausdruck zu unterschiedlichen Ergebnissen führen .eund die Zählung durcheinander bringen.
Jakube,
1
Eigentlich funktioniert der zweite Tipp auch nicht, sorry, weil ich den verpasst habe UQ.
isaacg
2
@isaacg Poste es als Antwort.
Jakube,
5

Javascript, 210 Bytes

v=(a,b,c,d,e,f,g)=>{d=Object.assign({},b),c={};for(g in b)c[g]=0;for(;a--;)e=0,f=Object.keys(d),f.forEach(a=>e=d[a]>e?d[a]:e),f=f.filter(a=>d[a]===e),f=f[~~(Math.random()*f.length)],d[f]=b[f]/-~++c[f];return c}

Anmerkungen:

  • Erfordert einen modernen Browser / eine moderne Engine mit Unterstützung für ES6. Getestet in Firefox.
  • Benutzt den sehr wichtigen /-~++Operator :)

Beispielverwendung:

v(25, {cio:12984,pcc:7716,irc:13009,icb:4045,cub:1741,bb:1013})
user2951302
quelle
1
Es ist nicht erforderlich, alle Variablen als Argumente zu deklarieren.
nderscore
2
Ja, aber ich wollte vermeiden, den globalen Geltungsbereich des Möglichen zu verschmutzen
user2951302
1
JS Golf ist alles über die Verschmutzung der globalen Reichweite :)
nderscore
2
Ich habe Ihre Methode auf 168 Bytes reduziert. Tut mir leid, dass ich die Variablennamen entstellt habe. F=(N,X)=>{for(t=[o={}],[t[o[j]=0,j]=X[j]for(j in X)];N--;t[z=y[new Date%y.length]]=X[z]/-~++o[z])m=0,y=[(m=m<t[j]?t[j]:m,j)for(j in X)],y=y.filter(j=>t[j]==m);return o}
nderscore
4

Pyth - 54 Bytes

AGZQ=kZK*]0lZVGJhOfqeTh.MZZ.e(kb)Z XJK1 XZJ/@kJ+@KJ1;K

Eingabeformat (stdin):

[25,[12984,7716,13009,4045,1741,1013]]

Ausgabeformat (stdout):

[8, 5, 9, 2, 1, 0]

Verwendete Variablen:

G = total number of seats
K = array of seats currently assigned to each party
k = number of votes for each party
Z = k/(K+1)
J = which party should have the next seat
Tyilo
quelle
Verwenden Sie vzund Qanstelle von Gund Z. Auf diese Weise speichern Sie die Zuordnung mit A.
Jakube,
2

Perl, 110

#!perl -pa
$n=pop@F;@x=map
0,@F;/a/,$x[$'/$n]++for(sort{$b-$a}map{map{($'/$_|0).rand.a.$i++}//..$n}@F)[0..$n-1];$_="@x"

Der Eingabebereich wird durch die Anzahl der letzten Sitzplätze getrennt.

Versuch es mit mir .

nutki
quelle