É hora da eleição!

13

Está na hora de contar os votos!

Hoje existem eleições locais em todo o meu país. Aqui, o número de assentos para cada parte é decidido usando o método D'Hondt . Seu objetivo é implementar um programa ou função que decida quantos assentos cada parte recebe, na menor quantidade de bytes.

Para esse método, há um número fixo de assentos a serem distribuídos, e é feito da seguinte maneira:

  1. Cada partido recebe um número variável, que começa com o número de votos que obteve.
  2. Em seguida, o primeiro assento é dado ao partido que tem o maior valor em sua variável e, em seguida, esse valor para esse partido se torna seu número total de votos dividido por 1+seats, arredondado para baixo, onde seatsestá o número de lugares que ele já tem (portanto, depois de obter o primeiro, seus votos são divididos por 2 e 3 após obter o segundo lugar).
  3. Depois disso, os votos dos partidos são comparados novamente. O processo continua até que todos os assentos tenham sido atribuídos.

Se o número mais alto for um empate entre duas ou mais partes, ele será resolvido aleatoriamente (deve ser aleatório, não pode ser apenas o primeiro dos dois na lista).

Entrada

Você receberá um número N, que indicará o número de assentos disponíveis, e uma lista dos votos que cada parte recebeu, no formato que preferir. Exemplo:

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

Resultado

Você deve exibir uma lista dos assentos que cada parte obteve. No exemplo acima, seria algo como

8,5,9,2,1,0

Eles devem estar na mesma ordem que as partes na entrada.

Exemplos

5
3,6,1

outputs: 2,3,0

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

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

Bônus

-20% de bônus se pegar o nome das partes como entrada e fornecer a saída, como por exemplo:

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
fonte
Sinto que já fez algo parecido com isso
edc65
Não encontrei nada parecido na pesquisa ... Mas se você encontrar alguma coisa, vou alterá-la ou remover a pergunta, sem problemas!
Rorlork
@rcrmn Há algo errado com o seu último exemplo. Talvez você quis dizer 153 total de assentos em vez de 135.
Tyilo
@Tyilo Right! Eu escrevi errado no meu programa de teste e copiei as respostas sem verificar duas vezes. Está consertado agora. Obrigado!
Rorlork # 24/15
1
Obrigado @Jakube, esse foi um problema com o programa que eu costumava calcular, que retornava a saída solicitada em assentos com etiquetas. Dennis, você pode devolvê-lo em qualquer ordem, pois o rótulo funciona como um identificador. Você pode assumir que só tem letras se for mais fácil para você.
Rorlork # 24/15

Respostas:

6

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

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

Este programa completo tem 33 bytes de comprimento e se qualifica para o bônus.

Experimente on-line no intérprete CJam .

Exemplo de execução

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

Como 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
fonte
6

Pitão, 36 bytes - 20% = 28,8

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

Isso se qualifica para o bônus.

Experimente on-line: demonstração ou equipamento de teste

Explicação:

                                       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
fonte
Jé desnecessário. Você pode se livrar dele e salvar 2 bytes.
Isaacg
Além disso, se você trocar ze Q, e depois salvar Cvzem K, poderá salvar outro byte.
Isaacg
@isaacg Não, é muito importante. Devido ao embaralhamento, a expressão pode produzir resultados diferentes .ee atrapalha a contagem.
Jakube
1
Na verdade, a segunda dica também não funciona, desculpe, porque eu perdi a UQ.
Isaacg
2
@isaacg Publique como resposta.
Jakube 24/05
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:

  • Requer um navegador / mecanismo moderno com suporte para ES6. Testado no Firefox.
  • Usa o /-~++operador muito importante :)

Exemplo de uso:

v(25, {cio:12984,pcc:7716,irc:13009,icb:4045,cub:1741,bb:1013})
user2951302
fonte
1
Não é necessário declarar todas as suas variáveis ​​como argumentos.
Ndscore # 24/15
2
Sim, mas eu queria evitar poluir o escopo global do possível
user2951302
1
JS golfe é tudo sobre poluindo o escopo gobal :)
nderscore
2
Eu joguei seu método de baixo para 168 bytes. Desculpe por manipular os nomes das variáveis. 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}
Ndscore
4

Pitão - 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 saída (stdout):

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

Variáveis ​​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
fonte
Use vze em Qvez de Ge Z. Dessa forma, você salvará a tarefa com A.
Jakube 24/05
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"

Espaço de entrada separado com a última contagem de assentos.

Experimente- me .

nutki
fonte