लालच पुनरावृत्ति के साथ संयोजन की सूची को विभाजित करता है


10

सबसे पहले, कुछ परिभाषाएँ:

  • दिया nऔर k, मल्टीसेट्स की सॉर्ट की गई सूची पर विचार करें , जहां प्रत्येक मल्टीसेट के लिए हम पुनरावृत्ति के साथ kसंख्या चुनते हैं {0, 1, ..., n-1}

उदाहरण के लिए, के लिए n=5और k=3, हमने:

[(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 0, 3), (0, 0, 4), (0, 1, 1), ( 0, 1, 2), (0, 1, 3), (0, 1, 4), (0, 2, 2), (0, 2, 3), (0, 2, 4), (0,) 3, 3), (0, 3, 4), (0, 4, 4), (1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 1, 1) 4), (1, 2, 2), (1, 2, 3), (1, 2, 4), (1, 3, 3), (1, 3, 4), (1, 4, 4) , (2, 2, 2), (2, 2, 3), (2, 2, 4), (2, 3, 3), (2, 3, 4), (2, 4, 4), ( 3, 3, 3), (3, 3, 4), (3, 4, 4), (4, 4, 4)]

  • एक भाग संपत्ति के साथ मल्टीसेट की एक सूची है कि भाग में सभी मल्टीसेट के चौराहे का आकार कम से कम है k-1। यही कारण है कि हम सभी मल्टीसेट्स लेते हैं और उन्हें (मल्टीसेट चौराहे का उपयोग करके) एक ही बार में इंटरसेक्ट करते हैं। उदाहरण के लिए, [(1, 2, 2), (1, 2, 3), (1, 2, 4)]एक हिस्सा है क्योंकि इसका चौराहा आकार 2 का है, लेकिन [(1, 1, 3),(1, 2, 3),(1, 2, 4)]ऐसा नहीं है, क्योंकि इसका प्रतिच्छेदन आकार 1 का है।

कार्य

आपका कोड दो तर्क लेना चाहिए nऔर k। इसके बाद लालची को इन मल्टीसेट के माध्यम से क्रमबद्ध क्रम में जाना चाहिए और सूची के कुछ हिस्सों का उत्पादन करना चाहिए। मामले के लिए n=5, k=3, सही विभाजन है:

(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 0, 3), (0, 0, 4)
(0, 1, 1), (0, 1, 2), (0, 1, 3), (0, 1, 4)
(0, 2, 2), (0, 2, 3), (0, 2, 4)
(0, 3, 3), (0, 3, 4)
(0, 4, 4)
(1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 1, 4)
(1, 2, 2), (1, 2, 3), (1, 2, 4)
(1, 3, 3), (1, 3, 4)
(1, 4, 4)
(2, 2, 2), (2, 2, 3), (2, 2, 4)
(2, 3, 3), (2, 3, 4)
(2, 4, 4)
(3, 3, 3), (3, 3, 4)
(3, 4, 4), (4, 4, 4)

यहाँ एक और उदाहरण है n = 4, k = 4

(0, 0, 0, 0), (0, 0, 0, 1), (0, 0, 0, 2), (0, 0, 0, 3)
(0, 0, 1, 1), (0, 0, 1, 2), (0, 0, 1, 3)
(0, 0, 2, 2), (0, 0, 2, 3)
(0, 0, 3, 3)
(0, 1, 1, 1), (0, 1, 1, 2), (0, 1, 1, 3)
(0, 1, 2, 2), (0, 1, 2, 3)
(0, 1, 3, 3)
(0, 2, 2, 2), (0, 2, 2, 3)
(0, 2, 3, 3), (0, 3, 3, 3)
(1, 1, 1, 1), (1, 1, 1, 2), (1, 1, 1, 3)
(1, 1, 2, 2), (1, 1, 2, 3)
(1, 1, 3, 3)
(1, 2, 2, 2), (1, 2, 2, 3)
(1, 2, 3, 3), (1, 3, 3, 3)
(2, 2, 2, 2), (2, 2, 2, 3)
(2, 2, 3, 3), (2, 3, 3, 3)
(3, 3, 3, 3)

लालची का क्या अर्थ है: इसके बदले में प्रत्येक मल्टीसेट के लिए हम देखते हैं कि क्या इसे मौजूदा हिस्से में जोड़ा जा सकता है। अगर हम इसे जोड़ सकते हैं। अगर यह हम एक नया हिस्सा शुरू नहीं कर सकते। हम ऊपर दिए गए उदाहरण के अनुसार क्रमबद्ध क्रम में मल्टीसेट को देखते हैं।

उत्पादन

आप अपनी पसंद के किसी भी समझदार प्रारूप में विभाजन को आउटपुट कर सकते हैं। हालांकि, एक लाइन पर क्षैतिज रूप से मल्टीसेट लिखा जाना चाहिए। यह एक व्यक्तिगत मल्टीसेट है जिसे लंबवत नहीं लिखा जाना चाहिए या कई लाइनों में फैला हुआ नहीं होना चाहिए। आप चुन सकते हैं कि आप आउटपुट में भागों के प्रतिनिधित्व को कैसे अलग करते हैं।

मान्यताओं

हम ऐसा मान सकते हैं n >= k > 0


@LuisMendo मैंने बस एक गलती की। मेरा मतलब था कि मल्टीसेट को एक पंक्ति में क्षैतिज रूप से लिखा जाना चाहिए।

पहले परीक्षण मामले में, (0, 4, 4)अपने आप से क्यों है ? आपके विवरण को देखते हुए, मुझे लगता है कि इसका "भाग" होगा (0, 4, 4), (1, 4, 4), (2, 4, 4), (3, 4, 4), (4, 4, 4)। इसी तरह (0, 0, 3, 3)दूसरे टेस्ट केस के लिए।
ग्रेग मार्टिन

@GregMartin विधि के लालच के कारण। आप सही कह रहे हैं कि यह सामान्य रूप से उप-प्रकार होगा। एक गैर लालची विधि द्वारा प्राप्त किए जा सकने वाले भागों की न्यूनतम संख्या यदि कठिन प्रश्न है, तो एक दिलचस्प है,

ओह, आपका शाब्दिक अर्थ है कि एक बार अगला कार्यकाल "सक्रिय" भाग से मेल नहीं खाता है, तो वह हिस्सा हमेशा के लिए बंद हो जाता है। ठीक है।
ग्रेग मार्टिन

जवाबों:


4

जेली , 26 25 बाइट्स

œ&µL‘<⁴ȧ⁹ȯ
œċµç\L€=⁴œṗµḊ’

पूर्ण कार्यक्रम जो सूची की एक सूची का प्रतिनिधित्व करता है, प्रत्येक सूची का एक हिस्सा है, उदाहरण के लिए n = 5, k = 3:

[[[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 0, 3], [0, 0, 4]], [[0, 1, 1], [0, 1, 2], [0, 1, 3], [0, 1, 4]], [[0, 2, 2], [0, 2, 3], [0, 2, 4]], [[0, 3, 3], [0, 3, 4]], [0, 4, 4], [[1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 1, 4]], [[1, 2, 2], [1, 2, 3], [1, 2, 4]], [[1, 3, 3], [1, 3, 4]], [1, 4, 4], [[2, 2, 2], [2, 2, 3], [2, 2, 4]], [[2, 3, 3], [2, 3, 4]], [2, 4, 4], [[3, 3, 3], [3, 3, 4]], [[3, 4, 4], [4, 4, 4]]]

नोट: उपयोग किया गया निरूपण निरर्थक [ और लगभग 1 की सूची को हटा देता है ]

इसे ऑनलाइन आज़माएं! या एक सुंदर प्रिंट संस्करण देखें (लागत 3 बाइट्स)

कैसे?

œ&µL‘<⁴ȧ⁹ȯ - Link 1, conditional multi-set intersection: list x, list y
œ&         - multi-set intersection(x, y)
  µ        - monadic chain separation (call that i)
   L       - length(i)
    ‘      - increment
     <     - less than?:
      ⁴    -     2nd program input, k
       ȧ   - logical and with:
        ⁹  -     link's right argument, y (y if i is too short, else 0)
         ȯ - logical or (y if i is too short, else i)

œċµç\L€=⁴œṗµḊ’ - Main link: n, k
œċ             - combinations with replacement(n, k) (sorted since n implies [1,n])
  µ            - monadic chain separation (call that w)
         œṗ    - partition w at truthy indexes of:
   ç\          -     reduce w with last link (1) as a dyad
     L€        -     length of €ach
        ⁴      -     2nd program input, k
       =       -     equal (vectorises)
           µ   - monadic chain separation
            Ḋ  - dequeue (since the result will always start with an empty list)
             ’ - decrement (vectorises) (since the Natural numbers were used by œċ)

यह भी खूब रही। धन्यवाद।

3

MATLAB, 272 बाइट्स

function g(n,k);l=unique(sort(nchoosek(repmat(0:n-1,1,k),k),2),'rows');p=zeros(0,k);for i=1:size(l,1)p=[p;l(i,:)];a=0;for j=1:size(p,1)for m=1:size(p,1)b=0;for h=1:k if(p(j,h)==p(m,h))b=b+1;end;end;if(b<k-1)a=1;end;end;end;if(a)fprintf('\n');p=l(i,:);end;disp(l(i,:));end;

आउटपुट:

>> g(5,3)
 0     0     0

 0     0     1

 0     0     2

 0     0     3

 0     0     4


 0     1     1

 0     1     2

 0     1     3

 0     1     4


 0     2     2

 0     2     3

 0     2     4


 0     3     3

 0     3     4


 0     4     4


 1     1     1

 1     1     2

 1     1     3

 1     1     4


 1     2     2

 1     2     3

 1     2     4


 1     3     3

 1     3     4


 1     4     4


 2     2     2

 2     2     3

 2     2     4


 2     3     3

 2     3     4


 2     4     4


 3     3     3

 3     3     4


 3     4     4

 4     4     4

>> g(4,4)
 0     0     0     0

 0     0     0     1

 0     0     0     2

 0     0     0     3


 0     0     1     1

 0     0     1     2

 0     0     1     3


 0     0     2     2

 0     0     2     3


 0     0     3     3


 0     1     1     1

 0     1     1     2

 0     1     1     3


 0     1     2     2

 0     1     2     3


 0     1     3     3


 0     2     2     2

 0     2     2     3


 0     2     3     3

 0     3     3     3


 1     1     1     1

 1     1     1     2

 1     1     1     3


 1     1     2     2

 1     1     2     3


 1     1     3     3


 1     2     2     2

 1     2     2     3


 1     2     3     3

 1     3     3     3


 2     2     2     2

 2     2     2     3


 2     2     3     3

 2     3     3     3


 3     3     3     3

विभिन्न भागों के बीच दो खाली लाइनें।

Ungolfed:

function g(n,k);
l=unique(sort(nchoosek(repmat(0:n-1,1,k),k),2),'rows');
p=zeros(0,k);
for i=1:size(l,1)
    p=[p;l(i,:)];
    a=0;
    for j=1:size(p,1)
        for m=1:size(p,1)
            b=0;
            for h=1:k
                if(p(j,h)==p(m,h))
                    b=b+1;
                end;
            end;
                if(b<k-1)
                    a=1;
                end;
        end;
    end;
    if(a)
        fprintf('\n');
        p=l(i,:);
    end;
    disp(l(i,:));
end;

स्पष्टीकरण:

पहले हम सभी बल के साथ मल्टीसेट्स पाते हैं:

l=unique(sort(nchoosek(repmat(0:n-1,1,k),k),2),'rows');

repmat(0:n-1, 1, k)से मूल्यों का वेक्टर दोहराता 0के लिए n-1 kबार।

nchoosek(x, k) बार-बार वेक्टर के सभी k-संयोजनों से युक्त एक मैट्रिक्स लौटाता है।

sort(x, 2)सभी k- संयोजनों को सॉर्ट करें, और फिर unique(x, 'rows')सभी डुप्लिकेट को निकालता है।

p=zeros(0,k);kकॉलम के साथ एक खाली मैट्रिक्स बनाता है । हम इसे स्टैक के रूप में उपयोग करेंगे। Outernmost forलूप के प्रत्येक पुनरावृत्ति पर , हम सबसे पहले मौजूदा मल्टीसेट को स्टैक में जोड़ते हैं p=[p;l(i,:)];:।

तब हम जांचते हैं कि क्या स्टैक में सभी मल्टीसेट्स का चौराहा k-1निम्न कोड के साथ कम से कम लंबा है ( intersectचौराहों की जांच के लिए हम MATLAB की कमांड का उपयोग नहीं कर सकते हैं , क्योंकि यह एक सेट लौटाता है, लेकिन हमें एक मल्टीसेट की आवश्यकता है):

a=0;
for j=1:size(p,1)
    for m=1:size(p,1)
        b=0;
        for h=1:k 
            if(p(j,h)==p(m,h))
                b=b+1;
            end;
        end;
        if(b<k-1)
            a=1;
        end;
    end;
end;

अब, यदि चौराहा काफी लंबा है a == 0, अन्यथा a == 1

यदि चौराहा काफी लंबा नहीं है, तो हम एक नई लाइन प्रिंट करते हैं और स्टैक को खाली करते हैं:

if(a)
    fprintf('\n');
    p=l(i,:); % Only the current multiset will be left in the stack.
end;

तब हम सिर्फ वर्तमान मल्टीसेट प्रिंट करते हैं:

disp(l(i,:));

लगता है कि आपने इसे फटा दिया! क्या आप अपना तरीका बता सकते हैं?

@ लेम्बिक मैंने एक स्पष्टीकरण जोड़ा।
स्टेडीबॉक्स

3

MATL , 34 बाइट्स

vi:qiZ^!S!Xu!"@!&vt1&dXasq?0&Y)0cb

भागों को व्हॉट्सएप युक्त एक लाइन द्वारा अलग किया जाता है।

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

व्याख्या

डिस्क्लेमर: यह तरीका काम करता है (और यह परीक्षण मामलों में होता है), लेकिन मेरे पास ऐसा कोई प्रमाण नहीं है जो यह हमेशा करता है

Multisets हल कर रहे हैं, दोनों आंतरिक (यानी प्रत्येक मल्टीसेट गैर घटते है प्रविष्टियों) और बाह्य (यानी मल्टीसेट एम मल्टीसेट से पहले आता है एन अगर एम पछाड़ एन कोषगत)।

मल्टीसेट चौराहे की गणना करने के लिए, सॉर्ट किए गए मल्टीसेट को एक मैट्रिक्स की पंक्तियों के रूप में व्यवस्थित किया जाता है और प्रत्येक कॉलम के साथ लगातार अंतर की गणना की जाती है। यदि अधिकांश को छोड़कर सभी कॉलम में शून्य के बराबर सभी अंतर हैं, तो मल्टीसेट एक ही हिस्से के हैं।

यह परीक्षण मल्टीसेट्स के लिए एक गलत नकारात्मक परिणाम देगा जैसे (1,2,3)और (2,3,4): भले ही 2, 3आम प्रविष्टियां हों, उन्हें इस तरह से नहीं पहचाना जाएगा क्योंकि वे गैर-मिलान कॉलम में हैं।

हालांकि, यह कम से कम परीक्षण मामलों में एक समस्या नहीं लगती है। ऐसा प्रतीत होता है कि मल्टीसेट्स जैसे परीक्षण 1,2,3और 2,3,4वास्तव में कभी नहीं करना पड़ता है, क्योंकि कुछ मध्यवर्ती मल्टीसेट ने नकारात्मक परिणाम दिया है और इसलिए वे पहले से ही विभिन्न भागों में हैं। यदि यह वास्तव में सच है, तो इस बात में कोई संदेह नहीं है कि मल्टीसेट को हल किया जाता है।

हालांकि मेरे पास इसका कोई प्रमाण नहीं है। यह सिर्फ काम करने लगता है।

v           % Concatenate stack vertically: gives an empty array. This will
            % grow into the first part
i:q         % Input n. Push [0 1 ... n-1]
i           % Input k
Z^          % Cartesian power. Each Cartesian tuple is on a row
!S!         % Sort each row
Xu          % Unique rows. This gives all multisets, sorted, each on a row
!           % Transpose
"           % For each column
  @!        %   Push current multiset as a row
  &v        %   Vertically concatenate with the part so far
  t         %   Duplicate
  1&d       %   Consecutive differences along each column
  Xas       %   Number of columns that contain at least one non-zero entry
  q?        %   If that number is not 1 (this means that the current 
            %   multiset should begin a new part)
    0&Y)    %     Push last row, then the array with the remaining rows.
            %     Said array is a part, which we now know is complete
    0c      %     Push character 0. This will be shown as a line containing 
            %     a space. This is used as a separator between parts.
    b       %     Bubble up. This moves the loose row to the top. This row 
            %     is the beginning of a new part
            %   Implicitly end if
            % Implicitly end for
            % Implicitly display

यह बहुत प्रभावशाली है।

मैं यह समझने की कोशिश कर रहा हूं कि यदि आपके द्वारा वर्णित विधि हमेशा काम करेगी। मुझे लगता है कि इस n=k=4मामले में हम एक नया हिस्सा शुरू करते हैं (0, 0, 3, 3), उस और पिछले बहु-सेट के सदिश अंतर में (0, 0, 2, 3)केवल एक अंतर होता है, इसलिए "भाग अब तक" यह काम कैसे करता है? (या इसके विपरीत वह कौन सा पूर्व चरण परिणाम था जिसका उपयोग किया गया था (0, 0, 2, 3)?)
जोनाथन एलन

आह, मैं देख रहा हूं कि आप लगातार अंतर करते हैं। हाँ यह हमेशा काम करना चाहिए! आप वस्तुतः उन बिंदुओं की तलाश में हैं जिन पर एक से अधिक आइटम बदलते हैं, लेकिन बहु-सेट चौराहे के बजाय, बस सदिश चौराहे - जो कि काम करेंगे चूंकि म्यूटली-सेट के साथ शुरू करने के लिए हल किया जाता है।
जोनाथन एलन

@JonathanAllan हाँ, यह अंतर के बजाय लगातार अंतर है। मैं अभी भी यह स्पष्ट नहीं देखता हूं कि यह हमेशा काम करेगा, लेकिन अगर आप ऐसा कहते हैं ... :-)
लुइस मेंडो

1

PHP, 245 बाइट्स

for(;$i<($n=$argv[1])**$m=$argv[2];$i++){for($a=[],$v=$i;$v|count($a)<$m;$v=$v/$n^0)array_unshift($a,$v%$n);sort($a);in_array($a,$r)?:$r[]=$a;}foreach($r as$k=>$v)$k&&count(array_diff_assoc($x[$c][0],$v))<2?$x[$c][]=$v:$x[++$c][]=$v;print_r($x);

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

विस्तारित

for(;$i<($n=$argv[1])**$m=$argv[2];$i++){ # loop till $argv[1]**$argv[2]
    for($a=[],$v=$i;$v|count($a)<$m;$v=$v/$n^0) 
    array_unshift($a,$v%$n); # create base n array
    sort($a); #sort array
    in_array($a,$r)?:$r[]=$a; # if sorted array is not in result add it
}    
foreach($r as$k=>$v)
    $k&& # > first item and
    count(array_diff_assoc($x[$c][0],$v))<2 # if difference is only 1 item between actual item and first item in last storage item
    ?$x[$c][]=$v # add item in last storage array
    :$x[++$c][]=$v; # make a new last storage array
print_r($x); # Output as array

स्ट्रिंग के रूप में आउटपुट

foreach($x as$y){$p=[];
foreach($y as$z){$p[]=$o="(".join(",",$z).")";}
    echo join(", ",$p)."\n";
}

n> 15 अधिक परिशुद्धता के लिए

for($i=0;$i<bcpow($argv[1],$argv[2]);$i=bcadd($i,1)){
    for($a=[],$v=$i;$v|count($a)<$argv[2];$v=bcdiv($v,$argv[1]))
    array_unshift($a,bcmod($v,$argv[1]));
    sort($a);
    in_array($a,$r)?:$r[]=$a;
}

यह काम करने लगता है! लेकिन अधिक सटीकता से आपका क्या मतलब है?

@ लेम्बिक लघु संस्करण के 0लिए वापस देता है (16**16-1)%16और लंबे संस्करण केवल सटीक के साथ काम करते हैं जो कि php.net/manual/en/ref.bc.php के लिए आवश्यक n>15 bcmod(bcsub(bcpow(16,16),1),16)है15
Jörg Hülsermann
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.