C'est le temps des élections!

13

Il est temps ... de compter les votes!

Aujourd'hui, il y a des élections locales dans tout mon pays. Ici, le nombre de sièges pour chaque parti est décidé en utilisant la méthode D'Hondt . Votre objectif est de mettre en œuvre un programme ou une fonction qui décidera du nombre de sièges accordés à chaque parti, dans le plus court nombre d'octets.

Pour cette méthode, il y a un nombre fixe de sièges à distribuer, et cela se fait comme suit:

  1. Chaque parti se voit attribuer un numéro variable, qui commence au nombre de votes qu'il a obtenu.
  2. Ensuite, le premier siège est attribué au parti qui a la plus grande valeur dans sa variable, puis cette valeur pour ce parti devient le nombre total de votes divisé par 1+seats, arrondi vers le bas, où seatsest le nombre de sièges qu'il détient déjà (donc après avoir obtenu le tout d'abord, leurs votes sont divisés par 2 et par 3 après avoir obtenu le deuxième siège).
  3. Après cela, les votes des partis sont à nouveau comparés. Le processus se poursuit jusqu'à ce que tous les sièges aient été attribués.

Si le nombre le plus élevé est une égalité entre deux ou plusieurs parties, il est résolu au hasard (il doit être aléatoire, il ne peut pas être le premier des deux dans la liste).

Contribution

Vous recevrez un numéro N, qui indiquera le nombre de sièges disponibles, ainsi qu'une liste des votes reçus par chaque parti, dans le format que vous préférez. Exemple:

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

Production

Vous devriez produire une liste des sièges obtenus par chaque parti. Dans l'exemple ci-dessus, ce serait quelque chose comme

8,5,9,2,1,0

Ils doivent être dans le même ordre que les parties en entrée.

Exemples

5
3,6,1

outputs: 2,3,0

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

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

Prime

-20% de bonus si vous prenez le nom des parties en entrée et les donnez dans la sortie, comme par exemple:

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
la source
Je pense que nous avons déjà fait quelque chose comme ça
edc65
Je n'ai rien trouvé de semblable dans la recherche ... Mais si vous trouvez quelque chose, je vais le changer ou supprimer la question, pas de problème!
rorlork
@rcrmn Il y a un problème avec votre dernier exemple. Peut-être que vous vouliez 153 sièges au total au lieu de 135.
Tyilo
@Tyilo Droite! Je l'ai mal écrit dans mon programme de test et j'ai copié les réponses sans revérifier. C'est réparé maintenant. Je vous remercie!
rorlork
1
Merci @Jakube, c'était un problème avec le programme que j'ai utilisé pour calculer, qui a renvoyé la sortie commandée dans des sièges avec des étiquettes. Dennis, vous pouvez le retourner dans n'importe quel ordre, car l'étiquette fonctionne comme un identifiant. Vous pouvez supposer qu'il n'a que des lettres si c'est plus facile pour vous.
rorlork

Réponses:

6

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

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

Ce programme complet fait 33 octets de long et donne droit au bonus.

Essayez-le en ligne dans l' interpréteur CJam .

Exemple d'exécution

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

Comment ça fonctionne

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
la source
6

Pyth, 36 octets - 20% = 28,8

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

Cela donne droit au bonus.

Essayez-le en ligne: démonstration ou test harnais

Explication:

                                       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
la source
Jest inutile. Vous pouvez vous en débarrasser et économiser 2 octets.
isaacg
En outre, si vous échangez zet Q, puis enregistrez Cvzà K, vous pouvez enregistrer un autre octet.
isaacg
@isaacg Non, c'est très important. En raison du brassage, l'expression peut donner des résultats différents .eet perturber le comptage.
Jakube
1
En fait, le deuxième conseil ne fonctionne pas non plus, désolé, car j'ai raté le UQ.
isaacg
2
@isaacg Publiez-le comme réponse.
Jakube
5

Javascript, 210 octets

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}

Remarques:

  • Nécessite un navigateur / moteur moderne avec prise en charge d'ES6. Testé dans Firefox.
  • Utilise l' /-~++opérateur très important :)

Exemple d'utilisation:

v(25, {cio:12984,pcc:7716,irc:13009,icb:4045,cub:1741,bb:1013})
user2951302
la source
1
Il n'est pas nécessaire de déclarer toutes vos variables comme arguments.
nderscore
2
Oui, mais je voulais éviter de polluer la portée mondiale du possible
user2951302
1
Le golf JS vise à polluer la portée
mondiale
2
J'ai joué à votre méthode jusqu'à 168 octets. Désolé d'avoir modifié les noms de 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 octets

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

Format d'entrée (stdin):

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

Format de sortie (stdout):

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

Variables utilisées:

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
la source
Utilisez vzet Qau lieu de Get Z. De cette façon, vous enregistrerez le devoir avec 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"

Espace d'entrée séparé avec le dernier nombre de sièges.

Essayez- moi .

nutki
la source