संसद सीटों का वितरण


14

परिचय

एक आम चुनाव में, एक प्रति संसद सीट की लगातार कीमत की गणना करना चाहेगा। इसका मतलब यह है कि N >= 0सीटों के वितरण के लिए और nsप्रति पार्टी वोटों की एक सूची के लिए , हम एक dऐसी संख्या खोजना चाहेंगे

sum(floor(n/d) for n in ns) == N 

चीजों को दिलचस्प बनाने के लिए (और वास्तविक दुनिया की तरह), हम दो और तथ्य जोड़ते हैं:

  1. दो दल एक parties गठबंधन ’में एकत्रित हो सकते हैं, जिससे कि सभी दलों को वोटों के योग से a गठबंधन’ को सीटें मिलें। फिर जिन सीटों पर 'गठबंधन' हुआ, वे कुछ इसी अंदाज में पार्टियों में बंट गईं (विभाजक खोजें, आदि)।

  2. एक पार्टी जो वोटों का एक निश्चित प्रतिशत पारित नहीं करती (उदाहरण के लिए 3.25%) को स्वचालित रूप से 0 सीटें मिलती हैं, और उसके वोटों की गिनती 'गठबंधन' के लिए नहीं होती है।

चुनौती

तुम्हे दिया गया है :

  1. सूचियों की एक सूची, प्रत्येक नेस्टेड सूचियों में पूर्णांक (वोटों की संख्या) होती है, और किसी एक पार्टी के लिए लंबाई 1 या 'गठबंधन' के लिए लंबाई 2 होती है।
  2. सीटों को पाने के लिए न्यूनतम प्रतिशत वोट (उर्फ "बार" "बैराज"), एक अंश के रूप में (इसलिए 3.25% 0.0325 के रूप में दिया जाता है)
  3. सभी दलों के बीच वितरित की जाने वाली सीटों की कुल संख्या (पूर्णांक)

आपको समान नेस्टेड सूची संरचना का प्रिंट आउट लेना है, संसद की सीटों के साथ वोट की संख्या के साथ।

विजेता बाइट्स की सबसे छोटी राशि वाला कोड है।

कोने के मामले:

  • एक से अधिक संभावित भाजक हो सकते हैं (और आमतौर पर होंगे)। चूंकि यह आउटपुट में नहीं है, इसलिए यह वास्तव में मायने नहीं रखता।
  • कल्पना करें N=10और ns = [[1]], इसलिए विभाजक 0.1 हो सकता है (पूर्णांक नहीं)
  • कुछ मामलों उदाहरण के लिए हल नहीं किया जा सकता है, , ns=[[30],[30],[100]], ।bar=0 N=20एक सीमा होती है d=7.5जहाँ 19 से 21 तक फ़्लार किए गए मानों का योग कूदता है। आपको इन मामलों को हल करने की उम्मीद नहीं है। (इस मामले को इंगित करने के लिए समुदाय के सदस्य अरनुलद को धन्यवाद)

उदाहरण इनपुट और आउटपुट

एक बहुत ही नहीं अनुकूलित पायथन 3 उदाहरण:

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

5
PPCG में आपका स्वागत है!
अरनुलद

CGCC में आपका स्वागत है (पहले PPCG के रूप में जाना जाता है)! मैंने पायथन को जोड़ने की स्वतंत्रता पर प्रकाश डाला ताकि आपका कोड अधिक पठनीय हो जाए, और मैंने इनपुट के नीचे कोड डाल दिया है ताकि इनपुट-आउटपुट एक साथ करीब हो। मैंने दो प्रासंगिक टैग भी जोड़े हैं। अच्छा पहला चैलेंज हालांकि, मेरी तरफ से +1! पुनश्च: आप उन्हें मुख्य पोस्ट करने से पहले चुनौतियों पर प्रतिक्रिया प्राप्त करने के लिए प्रस्तावित चुनौतियों के सैंडबॉक्स का उपयोग कर सकते हैं , हालांकि इस मामले में मुझे लगता है कि चुनौती स्पष्ट है। शायद कुछ अतिरिक्त परीक्षण मामले जोड़ें? अपने प्रवास का आनंद लें :)
केविन क्रूज़सेन

निश्चित बात @KevinCruijssen, मैंने दो और मामले जोड़े। मौजूदा आउटपुट के लिए मुझे विश्वास है कि यह सच है क्योंकि यह हालिया चुनाव का सटीक परिणाम है :)
scf

@ अर्नुलड आउट ऑफ क्यूरोसिटी, उस टेस्ट केस के लिए अपेक्षित आउटपुट क्या होना चाहिए?
केविन क्रूज़सेन

1
मैंने पहले से ही कोने के मामले में एक बुलेट जोड़ा है, मुझे लगता है कि यह एक अयोग्य मामला है क्योंकि सीमा में d=7.5आपको 19 सीटों से 21 सीटों तक की छलांग मिलती है।
एस सी एफ

जवाबों:


2

05AB1E , 42 39 बाइट्स

ÐOOI*@*DO¸I¸¸2Fнζε`sDO/*Щ±/D{®1%Oòè‹+ï

इसे ऑनलाइन आज़माएं!

05AB1E में अच्छी पुनरावृत्ति का अभाव है, इसलिए संदर्भ कोड में एक द्विआधारी खोज को लागू करना दर्दनाक होगा। शुक्र है, हमें विभाजक खोजने की आवश्यकता नहीं है!

आइए एक सरल उदाहरण का उपयोग करें: [६००, ३, ९, १२, ९] वोट, १०० सीटें, कोई गठबंधन नहीं, कोई बार नहीं। सबसे पहले, हम गणना करते हैं कि भिन्नात्मक सीटों को परिभाषित करते हुए प्रत्येक पार्टी को कितनी भिन्नात्मक सीटें मिलती हैं party_votes * seats / sum_of_votes। हमारे उदाहरण में, यह उपज [60, 37.9, 1.2, 0.9] है।

दिलचस्प बात यह है कि यदि किसी पार्टी को fभिन्नात्मक सीटें मिलती हैं, तो उसे int(f)या तो int(f) + 1वास्तविक सीटें मिलेंगी । इसका मतलब है कि हम पहले से ही जानते हैं कि कैसे 60 + 37 + 1 = 98 सीटों का आवंटन किया जाएगा, और हम 4 पार्टियों के बीच वितरित करने के लिए 2 "बोनस सीटों" के साथ बचे हैं (कोई भी पार्टी 1 से अधिक बोनस सीट नहीं पा सकती है)। ये बोनस सीटें किसके पास जाती हैं? उच्चतम अनुपात वाले पक्ष f / (int(f) + 1)(प्रमाण पाठक के लिए एक अभ्यास के रूप में छोड़ दिए गए)। हमारे उदाहरणों में, अनुपात हैं [0.98, 0.997, 0.6, 0.9], इसलिए पहले दो दलों को प्रत्येक में एक बोनस सीट मिलती है।


आइए कोड पर एक नज़र डालें। सबसे पहले, हम उन सभी दलों की मतगणना की जगह लेते हैं, जो 0 से बार से नहीं मिली थीं:

Ð          # triplicate the first input (list of votes)
 OO        # flattened sum
   I*      # multiply by the second input (bar)
     @     # greater than? (returns 0 or 1)
      *    # multiply

अब, पुनरावृत्ति की कमी के आसपास काम करने के लिए, हम 2Fमुख्य कोड को दो बार दोहराने के लिए एक अजीब उपयोग करते हैं । पहले पास पर यह गठबंधन के बीच कुल सीटों का वितरण करेगा, और दूसरे पास पर यह प्रत्येक गठबंधन की सीटों को अपनी पार्टियों के बीच वितरित करेगा। चूंकि पहला पास केवल एक बार चलता है, लेकिन दूसरा पास प्रत्येक गठबंधन के लिए चलता है, इसमें बहुत अधिक व्यस्त काम शामिल है।

DO¸I¸¸2Fнζε`s    # i don’t want to detail this tbh

ठीक है, इस अस्पष्ट बिट के बाद, स्टैक के शीर्ष पर अब वोटों की एक सूची है (पहले पास पर गठबंधन वोट, दूसरे पर पार्टी वोट), और उसके नीचे सीटों की संख्या आवंटित करने के लिए है। हम इसका उपयोग भिन्नात्मक सीटों की सूची की गणना करने के लिए करते हैं:

D        # duplicate
 O       # sum  
  /      # divide each vote count by the sum
   *     # multiply by the number of seats
    ©    # save the fractional seats in variable r

अब, हम अनुपात की गणना करते हैं:

Ð            # triplicate
 ±           # bitwise not
  /          # divide

बिटवाइज़ सुंदर काम नहीं करता है, यहाँ। यह पूर्णांक को जोड़ता है, 1 जोड़ता है, और नकारात्मक, सभी एक ही बाइट में। क्यों नकारा? 05AB1E में, 0 रिटर्न 0 से विभाजन होता है, और हमें अंतिम क्रमबद्ध करने के लिए इनकी आवश्यकता होती है।

D {# अनुपात की सॉर्ट की गई®®1% # आंशिक वोट mod 1 (उर्फ दशमलव भागों) उपरोक्त का # योग (यह बोनस सीटों की संख्या है) to # राउंड टू निकटतम (अस्थायी बिंदु bs के कारण आवश्यक) क्रमबद्ध अनुपात में è # सूचकांक

यह हमें (n + 1) वें सर्वश्रेष्ठ अनुपात देता है, जहां n बोनस सीटों की संख्या है (+1 क्योंकि अनुक्रमण 0 आधारित है)। इस प्रकार, जिन पार्टियों को बोनस सीट मिलती है, वे ऐसे हैं जिनका अनुपात इससे कम है।

‹      # less than
 +     # add to the fractional seats
  ï    # truncate to integer

बहुत अच्छा। उपयोग गणित के लिए शानदार तरीका अपने कोड :) अनुकूलन करने के लिए
एस सी एफ

3

पायथन 2 , 220 बाइट्स

def d(l,n,a=0,b=1.):s=sum(x//b for x in l);return s-n and d(l,n,*[a,b,(a+b)/2,b*2][s>n::2])or b
def f(l,b,n):l=[[x*(x>=b*sum(sum(l,[])))for x in r]for r in l];return[[v//d(x,sum(x)//d(map(sum,l),n))for v in x]for x in l]

इसे ऑनलाइन आज़माएं!

मूल रूप से संदर्भ कार्यान्वयन का सिर्फ एक गोल्फ ...


1

जेली , 63 36 बाइट्स

F×S<ḷ×ḷµ§⁵:,1_×¥:@"§IṠʋ÷9ɗ¥ƬṪṪƲ¥¥@⁺"

इसे ऑनलाइन आज़माएं!

तीन तर्कों को लेकर एक पूरा कार्यक्रम: उस क्रम में प्रश्न, बार और एन द्वारा वर्णित प्रारूप में वोटों की संख्या। सीट की सूची की सूची लौटाता है। टीआईओ पर पाद लेख आउटपुट की सूची संरचना को उजागर करने के लिए है। (अन्यथा जेली []एकल-आइटम सूचियों के लिए छिप जाती है।)

व्याख्या

F×S<ḷ×ḷµ§⁵:,1_×¥:@"§IṠʋ÷9ɗ¥ƬṪṪƲ¥¥@⁺"

F                                   | Flatten vote counts
 ×                                  | Multiply by bar
  S                                 | Sum
   <ḷ                               | Less than original vote counts (vectorises and respects input list structure)
     ×ḷ                             | Multiply by original vote counts
       µ                            | Start a new monadic link with processed vote counts as input
        §                           | Vectorised sum

         ⁵                      ¥@  | Apply the following as a dyad with the number of seats as the right argument and the vectorised sum of votes as left

           ,                  Ʋ¥    |(*)- Pair vote counts with seat sum and find divisor using the following as a monad:
            1             ¥Ƭ        |     - Starting with 1 as a guess for divisor, and using the paired vote counts and seat sum as the right argument, apply the following as a dyad, collecting intermediate results, until the results repeat
                         ɗ          |       - Following as a dyad:
                      ʋ             |         - Following as a dyad:
                :@"                 |           - Integer divide with arguments zipped and reversed, i.e. divide cote counts by current divisor guess and leave total seats alone
                   §                |           -  Vectorised sum (will sum vote counts but leave seat number alone)
                    I               |           - Find differences i.e. desired total seats minus current calculation based on current divisor guess. Will return a list.
                     Ṡ              |           - Sign of this (-1, 0 or 1)
                       ÷9           |         - Divide by 9 (-0.111, 0 or 0.111)
             _×¥                    |     - Now multiply the current divisor guess by this and subtract it from that guess to generate the next guess. If the current guess is correct, the guess will be unchanged and so the Ƭ loop will terminate
                            ṪṪ      |     - Take the last item twice (first time to get the final
                               output of the Ƭ loop and second to remove the list introduced by I
         :                          | - Integer divide the vote counts by the output of the above

                                  ⁺"| Apply the above dyad from the step labelled (*) again, this time with the output of the previous step (total votes per coalition) as right argument and the vote counts as left argument, zipping the two together and running the link once for each pair

मूल सबमिशन (बड़ा लेकिन अधिक कुशल)

जेली , 63 बाइट्स

:S_3ƭƒṠ©ḢḤ;$;ṪƲṖÆm;ḊƲ®‘¤?ߥ/}ṛ¹?,
1,0;çḢḢ
FS×Ċ’<ḷ×ḷµ:"§:⁵ç$$ç"Ɗ

इसे ऑनलाइन आज़माएं!


अच्छा प्रस्तुत किया। मैंने इसे इनपुट [[1]] 0.0 10 के साथ आजमाया, जिसकी मुझे उम्मीद है कि [[10]] (कोने के मामलों में बुलेट प्वाइंट 2 देखें) और समय समाप्त हो गया। क्या आप इसकी पुष्टि कर सकते हैं कि यह केवल बहुत लंबे समय तक चलने वाला समय है और बग नहीं है?
scf

मूल सबमिशन उस इनपुट BTW के साथ काम करता है।
scf

@ मुझे गलत तरीके से माना गया कि वोट हमेशा सीटों की तुलना में बहुत अधिक थे। संशोधित संस्करण ठीक काम करना चाहिए (और बहुत अधिक कुशल है)।
निक केनेडी

1
अच्छा लगा, अच्छा लग रहा है! यदि आप कोड को थोड़ा समझा सकते हैं तो अच्छा होगा।
scf

प्रश्न: छत महत्वपूर्ण क्यों है? यदि मैं सही ढंग से समझता हूं कि आप कम से कम मतों के साथ सीलिंग करते हैं, हालांकि यह तुलना के लिए अनावश्यक है।
एस सी एफ

1

वुल्फराम - कोई गोल्फ नहीं

गोल्फर प्रत्याशी नहीं, बल्कि LinearProgramming का उपयोग करके इसे हल करने के लिए उत्सुक था , लेकिन शायद एक समस्या के लिए एक दिलचस्प दृष्टिकोण:

findDivisor[l_, n_] := Quiet@Module[{s, c, r, m, b, cons, sol},
   s = Length[l];
   c = Append[ConstantArray[0, s], 1];
   r = Thread[Append[IdentityMatrix[s], -l]];
   m = Append[Join[r, r], Append[ConstantArray[1, s], 0]];
   b = Append[Join[ConstantArray[{0, -1}, s], ConstantArray[{-1, 1}, s]], {n, 0}];
   cons = Append[ConstantArray[Integers, s], Reals];
   sol = LinearProgramming[c, m, b, 0, cons];
   {1/sol[[-1]], Most@sol}
   ]
solve[l_, bar_, n_] := 
 With[{t = l /. x_ /; x <= bar Total[l, 2] -> 0},
  With[{sol = findDivisor[Total /@ t, n]}, 
   {First@sol, MapThread[findDivisor, {t, Last@sol}]}]
  ]

कुछ स्पष्टीकरण पढ़ें और इसे आज़माएं!


भले ही यह एक प्रतियोगी नहीं है, लेकिन इस पद्धति और कोड के बारे में कुछ स्पष्टीकरण शैक्षिक उद्देश्यों के लिए बहुत अच्छा होगा।
एस सी एफ

@scf मैं इसे समझा पर मेरे प्रयास के लिए एक लिंक जोड़ दिया है
बेंत की मार
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.