Час виборів!


13

Пора ... порахувати голоси!

Сьогодні в моїй країні проводяться місцеві вибори. Тут кількість місць для кожної партії визначається методом Д'Хондта . Ваша мета - реалізувати програму або функцію, яка визначатиме, скільки місць отримає кожна сторона, в найкоротшій кількості байтів.

Для цього методу існує фіксована кількість місць для розподілу, і це робиться так:

  1. Кожній партії присвоюється змінна кількість, яка починається з кількості отриманих голосів.
  2. Тоді перше місце надається партії, яка має найбільшу цінність у своїй змінній, а потім цією цінністю для цієї партії стає їх загальна кількість голосів, поділене на 1+seats, округлене вниз, де seatsце кількість місць, які вона вже має (тому після отримання по-перше, їх голоси діляться на 2, і на 3 після отримання другого місця).
  3. Після цього голоси партій знову порівнюються. Процес триває, поки не будуть призначені всі місця.

Якщо найбільша кількість є зв’язком між двома або більше сторонами, вона вирішується випадковим чином (вона повинна бути випадковою, вона не може бути просто першою з двох у списку).

Вхідні дані

Ви отримаєте номер N, в якому буде вказана кількість наявних місць та список голосів, отриманих кожною стороною, у будь-якому форматі, який ви бажаєте. Приклад:

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

Вихідні дані

Вам слід вивести список місць, які отримала кожна сторона. У наведеному вище прикладі це було б щось подібне

8,5,9,2,1,0

Вони повинні бути в тому ж порядку, що і сторони у введенні.

Приклади

5
3,6,1

outputs: 2,3,0

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

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

Бонус

-20% бонус, якщо взяти назву сторін як вхідну інформацію та дати їм у висновку, наприклад:

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

Я відчуваю, що ми вже зробили щось подібне
edc65

Я не міг знайти нічого подібного в пошуку ... Але якщо ви знайдете щось, я його зміню або видаляю питання, жодних проблем!
rorlork

@rcrmn У вашому останньому прикладі щось не так. Можливо, ти мав на увазі 153 загальні місця замість 135.
Тіїло,

@Tyilo Правильно! Я написав це неправильно у своїй тестовій програмі та скопіював відповіді без подвійної перевірки. Це зараз виправлено. Дякую!
rorlork

1
Дякую @Jakube, це була проблема з програмою, яку я використовував для обчислення, яка повертала впорядкований вихід на місця з мітками. Dennis, ви можете повернути його в будь-якому порядку, оскільки мітка працює як ідентифікатор. Ви можете припустити, що в ньому є лише букви, якщо вам простіше.
rorlork

Відповіді:


6

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

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

Ця повна програма становить 33 байти і відповідає умовам отримання бонусу.

Спробуйте його в Інтернеті в інтерпретаторі CJam .

Приклад виконання

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

Як це працює

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#

6

Pyth, 36 байт - 20% = 28,8

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

Це кваліфікується як бонус.

Спробуйте в Інтернеті: Демонстрація або Тест-джгут

Пояснення:

                                       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

Jє непотрібним. Ви можете позбутися і зберегти 2 байти.
isaacg

Крім того , якщо ви підкачки zі Q, а потім зберегти Cvzв K, ви можете зберегти ще один байт.
isaacg

@isaacg Ні, це дуже важливо. Через перетасування вираз може дати різні результати, .eі це зіпсує підрахунок.
Якубе

1
Насправді, друга порада також не працює, вибачте, тому що я пропустила UQ.
isaacg

2
@isaacg Опублікуйте це як відповідь.
Якубе

5

Javascript, 210 байт

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}

Примітки:

  • Потрібен сучасний браузер / движок з підтримкою ES6. Випробуваний у Firefox.
  • Використовує дуже важливого /-~++оператора :)

Приклад використання:

v(25, {cio:12984,pcc:7716,irc:13009,icb:4045,cub:1741,bb:1013})

1
Не потрібно оголошувати всі свої змінні як аргументи.
nderscore

2
Так, але я хотів уникнути забруднення глобальної сфери можливих
user2951302

1
JS golf - все про те, що забруднює сферу
гобалу

2
Я переграв ваш метод до 168 байт. Вибачте за керування іменами змінних. 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 байти

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

Формат введення (stdin):

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

Формат виводу (stdout):

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

Використовувані змінні:

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

Використовуйте vzі Qзамість Gі Z. Таким чином ви збережете завдання за допомогою A.
Якубе

2

Перл, 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"

Вхідний простір, розділене останнім числом сидінь.

Спробуй мене .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.