소개
총선에서 의회 의석 당 일정한 가격을 계산하려고합니다. 즉, N >= 0좌석 배분 및 ns파티 당 투표 목록 을 위해 다음 d과 같은 숫자를 찾고 싶습니다.
sum(floor(n/d) for n in ns) == N
일을 흥미롭게 만들고 현실 세계와 비슷하게 만들기 위해 두 가지 사실을 더 추가합니다.
두 당사자가 '연합'에 모일 수 있으므로 모든 당사자에 대한 투표의 합에 의해 좌석이 '연합'에 제공됩니다. 그런 다음 '연합'이 얻은 좌석은 비슷한 방식으로 당사자간에 나뉩니다 (찾기 제수 등).
특정 비율의 투표를 통과하지 못한 당사자 (예 : 3.25 %)는 자동으로 0 석을 얻으며 해당 투표는 '연합'에 포함되지 않습니다.
도전
당신은 주어진다 :
- 목록의 목록, 각 중첩 목록에는 정수 (투표 수)가 포함되며 단일 당사자의 경우 길이가 1이고 '연합'의 경우 길이가 2입니다.
- 자리를 얻는 최소 투표율 (일명 "막대기"는 "bar") (분수) (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 석으로 점프 할 때 이것이 해결할 수없는 사건이라고 생각합니다 .