介绍
在大选中,人们想计算每个议会席位的不变价格。这意味着N >= 0
要分配席位和ns
每个政党的投票清单,我们希望找到一个数字d
,以便
sum(floor(n/d) for n in ns) == N
为了使事情变得有趣(更像现实世界),我们添加了两个事实:
两党可以聚集在一个“联盟”中,这样,“联盟”的席位就由该联盟中所有各方的票数之和决定。然后,“联盟”获得的席位以类似的方式在各方之间分配(找到除数等)
没有获得一定比例票数(例如3.25%)的政党自动获得0席,其票数不计入“同盟”。
挑战
给你:
- 列表列表,每个嵌套列表都包含整数(投票数),单方长度为1,“联盟”长度为2。
- 获得席位的最低票数百分比(又称“弹幕”的“巴”),即分数(因此3.25%表示为0.0325)
- 各方之间分配的席位总数(整数)
您将打印出相同的嵌套列表结构,并用议席数代替票数。
优胜者是字节数最少的代码。
角落案例:
- 除数可能(通常会)有一个以上。由于它不在输出中,因此它并不重要。
- 想象
N=10
和ns = [[1]]
,所以除数可以是0.1(不是整数) - 有些案件不能得到解决,例如
ns=[[30],[30],[100]]
,bar=0
,N=20
。d=7.5
下限的总和从19跳到21,这是一个边界。您不希望解决这些情况。(感谢社区成员Arnauld指出此案)
输入和输出示例
一个未优化的Python3示例:
from math import floor
def main(_l, bar, N):
# sum all votes to calculate bar in votes
votes = sum(sum(_) for _ in _l)
# nullify all parties that didn't pass the bar
_l = [[__ if __ >= bar * votes else 0 for __ in _] for _ in _l]
# find divisor for all parliament seats
divisor = find_divisor([sum(_) for _ in _l], N)
# find divisor for each 'coalition'
divisors = [find_divisor(_, floor(sum(_)/divisor)) for _ in _l]
# return final results
return [[floor(___/_) for ___ in __] for _, __ in zip(divisors, _l)]
def find_divisor(_l, N, _min=0, _max=1):
s = sum(floor(_ / _max) for _ in _l)
if s == N:
return _max
elif s < N:
return find_divisor(_l, N, _min, (_max + _min) / 2)
else:
return find_divisor(_l, N, _max, _max * 2)
print(main(l, bar, N))
输入示例:
l = [[190970, 156473],
[138598, 173004],
[143666, 193442],
[1140370, 159468],
[258275, 249049],
[624, 819],
[1125881],
[152756],
[118031],
[74701]]
bar = 0.0325
N = 120
及其输出:
[[6, 4], [0, 5], [4, 6], [35, 5], [8, 8], [0, 0], [35], [4], [0], [0]]
其他一些示例输出:
如果bar=0.1
我们在两个政党之间产生有趣的对峙,因为较小的政党都不算在内:
[[0, 0], [0, 0], [0, 0], [60, 0], [0, 0], [0, 0], [60], [0], [0], [0]]
而且,如果N=0
(角落情况)那么,当然没人会得到任何东西:
[[0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0], [0], [0], [0]]
d=7.5
您可以从19个席位跃升至21个席位。