¡Es hora de elecciones!

13

¡Es hora de contar los votos!

Hoy hay elecciones locales en todo mi país. Aquí, el número de asientos para cada parte se decide utilizando el método D'Hondt . Su objetivo es implementar un programa o función que decida cuántos asientos obtiene cada parte, en la menor cantidad de bytes.

Para este método, hay un número fijo de asientos para distribuir, y se hace así:

  1. A cada partido se le asigna un número variable, que comienza con el número de votos que obtuvo.
  2. Luego, el primer asiento se otorga al partido que tiene el mayor valor en su variable y luego ese valor para ese partido se convierte en el número total de votos dividido por 1+seats, redondeado hacia abajo, dondeseats está el número de asientos que ya tiene (así que después de obtener el primero, sus votos se dividen por 2 y por 3 después de obtener el segundo asiento).
  3. Después de eso, los votos de los partidos se comparan nuevamente. El proceso continúa hasta que se hayan asignado todos los asientos.

Si el número más alto es un empate entre dos o más partes, se resuelve al azar (tiene que ser aleatorio, no puede ser el primero de los dos en la lista).

Entrada

Recibirá un número N, que indicará el número de escaños disponibles, y una lista de los votos que recibió cada parte, en el formato que prefiera. Ejemplo:

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

Salida

Debería generar una lista de los asientos que obtuvo cada parte. En el ejemplo anterior sería algo así como

8,5,9,2,1,0

Deben estar en el mismo orden que las partes en la entrada.

Ejemplos

5
3,6,1

outputs: 2,3,0

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

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

Prima

-20% de bonificación si toma el nombre de las partes como entrada y las da en la salida, como por ejemplo:

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
fuente
Siento que ya hicimos algo así
edc65
No pude encontrar nada parecido en la búsqueda ... Pero si encuentras algo, lo cambiaré o eliminaré la pregunta, ¡no hay problema!
rorlork
@rcrmn Hay algo mal con tu último ejemplo. Tal vez quisiste decir 153 asientos totales en lugar de 135.
Tyilo
@Tyilo ¡Correcto! Lo escribí mal en mi programa de prueba y copié las respuestas sin doble verificación. Ya está arreglado. ¡Gracias!
rorlork
1
Gracias @Jakube, ese fue un problema con el programa que solía calcular, que devolvió la salida ordenada en asientos con etiquetas. Dennis puede devolverlo en cualquier orden, ya que la etiqueta funciona como un identificador. Puede suponer que solo tiene letras si es más fácil para usted.
rorlork

Respuestas:

6

CJam, 35.2 28.8 28.0 26.4

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

Este programa completo tiene 33 bytes y califica para el bono.

Pruébelo en línea en el intérprete de CJam .

Ejecución de ejemplo

$ 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]

Cómo funciona

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
fuente
6

Pyth, 36 bytes - 20% = 28.8

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

Esto califica para el bono.

Pruébelo en línea: demostración o prueba de arnés

Explicación:

                                       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
fuente
Jes innecesario Puede deshacerse de él y guardar 2 bytes.
isaacg
Además, si intercambia zy Q, y luego guarda Cvzen K, puede guardar otro byte.
isaacg
@isaacg No, es muy importante. Debido a la combinación aleatoria, la expresión puede producir resultados diferentes .ey estropea el recuento.
Jakube
1
En realidad, el segundo consejo tampoco funciona, lo siento, porque me perdí el UQ.
isaacg
2
@isaacg Publícalo como respuesta.
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}

Notas:

  • Requiere un navegador / motor moderno con soporte para ES6. Probado en Firefox.
  • Utiliza el /-~++operador muy importante :)

Ejemplo de uso:

v(25, {cio:12984,pcc:7716,irc:13009,icb:4045,cub:1741,bb:1013})
usuario2951302
fuente
1
No es necesario declarar todas sus variables como argumentos.
nderscore
2
Sí, pero quería evitar contaminar el alcance global de lo posible
usuario 2951302
1
JS golf se trata de contaminar el alcance global :)
nderscore
2
He golfizado su método hasta 168 bytes. Perdón por destrozar los nombres de las variables. 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

Formato de entrada (stdin):

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

Formato de salida (stdout):

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

Variables utilizadas:

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
fuente
Use vzy en Qlugar de Gy Z. De esta manera guardará la tarea con 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"

Espacio de entrada separado con el último recuento de asientos.

Trate de mí .

nutki
fuente