লোভের সাথে পুনরাবৃত্তি সহ সংমিশ্রনের তালিকা ভাগ করে নিন


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, 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 মাপের size

কার্য

আপনার কোডে দুটি যুক্তি নেওয়া উচিত 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


@ লুইস মেন্ডো আমি কেবল একটি ভুল করেছি। আমি বোঝাতে চাইছিলাম বহু লাইসেটগুলি এক লাইনে অনুভূমিকভাবে লেখা উচিত।

প্রথম পরীক্ষার ক্ষেত্রে, কেন (0, 4, 4)নিজে থেকে? আপনার বিবরণ দেওয়া, আমি মনে করি এটি "অংশ" হবে (0, 4, 4), (1, 4, 4), (2, 4, 4), (3, 4, 4), (4, 4, 4)। একইভাবে (0, 0, 3, 3)দ্বিতীয় পরীক্ষার ক্ষেত্রেও।
গ্রেগ মার্টিন

@ গ্রেগমার্টিন পদ্ধতির লোভের কারণে। আপনি ঠিক বলেছেন যে এটি সাধারণভাবে সাবপটিমাল হবে। অ লোভী পদ্ধতিতে আপনি যে সর্বনিম্ন সংখ্যক অংশগুলি পেতে পারেন তা যদি একটি কঠিন প্রশ্ন হয় তবে

ওহ, আপনি আক্ষরিক অর্থ দাঁড়ালেন যে একবার খুব পরের শব্দটি "সক্রিয়" অংশের সাথে মেলে না, তবে সেই অংশটি চিরতরে বন্ধ হয়ে যায়। ঠিক আছে.
গ্রেগ মার্টিন

উত্তর:


4

জেলি , 26 25 বাইট

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

সম্পূর্ণ প্রোগ্রাম যা তালিকাগুলির তালিকার একটি প্রতিনিধিত্ব ছাপায়, প্রতিটি তালিকা অংশ হিসাবে রয়েছে, যেমন এন = 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]]]

দ্রষ্টব্য: ব্যবহৃত উপস্থাপনা অনর্থক [ এবং দৈর্ঘ্য 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

ম্যাটল্যাব, 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) পুনরাবৃত্ত ভেক্টরের সমস্ত কে-সংমিশ্রণ সহ একটি ম্যাট্রিক্স প্রদান করে।

sort(x, 2)সমস্ত কে-কম্বিনেশন বাছাই করে এবং তারপরে unique(x, 'rows')সমস্ত নকল সরিয়ে দেয়।

p=zeros(0,k);kকলাম সহ খালি ম্যাট্রিক্স তৈরি করে । আমরা এটি স্ট্যাক হিসাবে ব্যবহার করব। Outernmost প্রতিটি পুনরাবৃত্তির উপর forলুপ, তাই আমরা প্রথমেই বলেন স্ট্যাকের বর্তমান multiset যোগ করুন: p=[p;l(i,:)];

তারপরে আমরা স্ট্যাকের সমস্ত মাল্টিসেটের ছেদটি k-1নিম্নলিখিত কোড সহ কমপক্ষে দীর্ঘ কিনা তা পরীক্ষা করে দেখছি (ছেদগুলি intersectপরীক্ষা করার জন্য আমরা ম্যাটল্যাবের নির্দেশটি ব্যবহার করতে পারি না , কারণ এটি একটি সেট দেয়, তবে আমাদের একটি মাল্টিসেট প্রয়োজন):

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

এমএটিএল , 34 বাইট

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

অংশগুলি সাদা বাক্সযুক্ত একটি রেখার দ্বারা পৃথক করা হয়।

এটি অনলাইন চেষ্টা করুন!

ব্যাখ্যা

দাবি অস্বীকার: এই পদ্ধতিটি কাজ করে বলে মনে হচ্ছে (এবং এটি পরীক্ষার ক্ষেত্রেও ঘটে) তবে আমার কাছে এমন প্রমাণ নেই যা এটি সর্বদা করে

Multisets সাজানো হয়, উভয় অভ্যন্তরীণভাবে (অর্থাত প্রতিটি multiset অ কমে গেছে এন্ট্রি) এবং বাহ্যিকভাবে (অর্থাত multiset এম multiset সামনে আসে এন যদি এম আগে বসেছে এন lexicographically)।

মাল্টিসেট ছেদটি গণনা করতে, বাছাই করা মাল্টিটগুলি ম্যাট্রিক্সের সারি হিসাবে সাজানো হয় এবং প্রতিটি কলামের সাথে পরপর পার্থক্য গণনা করা হয়। যদি সর্বাধিক এক ব্যতীত সমস্ত কলামে শূন্যের সমান পার্থক্য থাকে তবে বহুগুণ একই অংশের অন্তর্গত।

এই পরীক্ষাটি মাল্টিসেটের মতো (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)কী ব্যবহার করা হয়েছিল ?)
জোনাথন অ্যালান

আহ, আমি আপনাকে একটানা পার্থক্য সম্পাদন করতে দেখছি। হ্যাঁ এটি সর্বদা কাজ করা উচিত! আপনি আক্ষরিকভাবে এমন পয়েন্টগুলি সন্ধান করছেন যেখানে একাধিক আইটেম পরিবর্তিত হয়, তবে একাধিক সেট ছেদ না করে কেবল ভেক্টোরাইজড ছেদ - যেটি কাজ করবে যেহেতু মুতলি-সেটগুলি সাজানোর জন্য শুরু করা হয়েছে।
জোনাথন অ্যালান

@ জোনাথন অ্যালান হ্যাঁ, এটি ছেদ না করে ক্রমাগত পার্থক্য। আমি এখনও এটি পরিষ্কার দেখতে পাচ্ছি না যে এটি সর্বদা কার্যকর হবে, তবে আপনি যদি তাই বলেন ... :-)
লুইস মেন্ডো

1

পিএইচপি, 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;
}

এই কাজ বলে মনে হচ্ছে! তবে আরও নির্ভুলতার দ্বারা আপনি কী বোঝাতে চাইছেন?

@Lembik সংক্ষিপ্ত সংস্করণ ফিরিয়ে দেয় 0জন্য (16**16-1)%16এবং শুধুমাত্র স্পষ্টতা যে জন্য প্রয়োজন হয় সঙ্গে দীর্ঘ সংস্করণ কাজ n>15 bcmod(bcsub(bcpow(16,16),1),16)হয় 15 php.net/manual/en/ref.bc.php
Jörg Hülsermann
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.