前書き
総選挙では、議席ごとに定価を計算したいと思います。これは、N >= 0
配布されるシートとns
パーティーごとの投票リストについて、次のd
ような数を見つけたいことを意味します。
sum(floor(n/d) for n in ns) == N
物事を面白くするために(さらに現実の世界に近づけるために)、さらに2つの事実を追加します。
2つの政党が「連合」に集まって、その中のすべての政党の票の合計によって議席が「連合」に与えられます。次に、「連合」が獲得した座席は、同様の方法でパーティ間で分割されます(除数を見つけるなど)。
一定の割合の票(3.25%など)を渡さなかった党は自動的に0議席を獲得し、その票は「連合」にカウントされません。
チャレンジ
あなたが与えられます:
- リストのリスト。ネストされた各リストには整数(投票数)が含まれ、単一のパーティの場合は長さ1、「連合」の場合は長さ2です。
- 議席を獲得するための票の最小割合(別名「弾幕」の「バー」)、分数(したがって、3.225%は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
小規模なパーティは含まれていないため、2つのパーティ間で興味深いスタンドオフが発生した場合:
[[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席にジャンプするので、これは解決できないケースだと思います。