Torba operasyonlarını uygulayın


20

Bir torba ayrıca multiset adlandırılan, bir sırasız koleksiyon. Yinelemelere izin veren bir küme veya sıralanmamış / dizine eklenmemiş bir liste (veya bir dizi) diyebilirsiniz. Bu zorlukta, torba işlemlerini gerçekleştirmeniz istenir: toplama, fark, çarpma, bölme, sayma ve eşitlik testi.

Operasyonlar

Belirtilen işlemler geleneksel olmayabilir.

  • toplama , her bir değerin toplam sayısını koruyarak iki torbayı bir araya getirir
    [1,2,2,3] + [1,2,4] = [1,1,2,2,2,3,4]
  • fark bir torbadan başka bir torbanın her elemanını kaldırır veya böyle bir eleman yoksa hiçbir şey yapmaz
    [1,2,2,4] - [1,2] = [2,4] [1,2,3] - [2,4] = [1,3]
  • çarpma torbadaki her elemanı çarpar.
    [1,2,3,3,4] * 3 = [1,1,1,2,2,2,3,3,3,3,3,3,4,4,4] 2 * [1,3] = [1,1,3,3]
  • bölme nadirdir: her n eşit eleman n eşit yeni torbaya konur, n-grubu oluşturamayan elemanlar torbada kalır. Yeni torbalardan herhangi birini iade edin.
    [1,1,2,2,2] / 2 = [1,2] [1,2,2,3,3,3] / 3 = [3]
  • sayma , temettü çantasından kaç bölen torbasının üretilebileceğini sayar
    [1,1,2,2,2,2,3,3,3] c [1,2,3] = 2
  • Eşitlik testi , iki torbanın her elemanın aynı sayıda olup olmadığını kontrol eder
    [1,2,2,3] == [3,2,1,2] = truthy [1,2,3] == [1,2,2,3] = falsy(bunun için de kullanılabilir =)

Operatörler için kendi sembollerinizi kullanıyorsanız, lütfen belirtin.

Biçimleri

Çantalar form listesi olarak gösterilecektir [1,1,2,3,4]. Kare olanlardan başka herhangi bir köşeli ayraç kullanabilir, hatta tırnak işaretleri kullanabilirsiniz veya hiçbir şey kullanamazsınız. Öğeler intbu sorunun amacı için tamsayılar (matematiksel olarak değil ) olacaktır. Çantaların sınıflandırılması gerekmez.

Giriş biçimi bir operatör ile iki torba ya da bir torba ile bir tam sayı olacaktır. Bu üçünü içerdiği sürece kendi biçiminizi belirtebilirsiniz.

Çıkış biçimi aynı formatta tek bir çanta olmalıdır.

kurallar

  • bunları zaten uygulayan yerleşik işlevleri, işlemleri veya kitaplıkları (standart kitaplık dahil) kullanamazsınız; çanta birleştirme (temel olarak aynı şeyi yapan) değil, tanımlama listesi işlemleri tarafından olduğundan, liste birleştirme ve çarpma kullanmak için sorun değil
  • standart boşluklar geçerlidir
  • en kısa cevap kazanır

Test senaryoları

[1,2,2,3] + [1,2,4]
[1,1,2,2,2,3,4]

[1,2,2,4] - [1,2]
[2,4]

[1,2,3] - [2,4]
[1,3]

[1,2,3,3,4] * 3
[1,1,1,2,2,2,3,3,3,3,3,3,4,4,4]

2 * [1,3]
[1,1,3,3]

[1,1,2,2,2] / 2
[1,2]

[1,2,2,3,3,3] / 3
[3]

[1,1,2,2,2,2,3,3,3] c [1,2,3]
2

[3,2,1,2] == [1,2,2,3]
truthy

[1,2,3] == [1,2,2,3]
falsy

2
Giriş formatını rahatlatabilir misiniz? Örneğin, torbanın, torba / numaranın ve operatörün ayrı argümanlar olarak veya serbest bir biçimde alınmasına izin verin. Aksi takdirde, mücadelenin önemli bir kısmı girdiyi ayrıştırmaktır, ki bu özellikle ilginç değildir
Luis Mendo

@LuisMendo boşluk ayrımı bunu ayrıştırmak için yeterlidir, eğer dizeleri liste olarak değerlendirebilecek bir diliniz varsa, değil mi?
Mesaj

Bir alakalı meta yayını bulamadık, ancak ifadeler örneğin göremiyordu burada : onun ondalık temsili olarak tamsayı, tekli temsilini (seçtiğiniz bir karakteri kullanılarak), bayt dizisi (büyük ya da küçük endian) veya tek bayt okuyabilir (bu diller en büyük veri türü ise) . Veya burada : Giriş ve çıkış biçimleri her zamanki gibi esnektir (diziler, listeler, liste listesi, makul ayırıcılı dizeler vb. ).
Luis Mendo

@LuisMendo artık temelde ücretsiz. Ve tamsayı hakkında, sadece matematiksel anlamda veri türünü değil demek istedim.
busukxuan

1
@LuisMendo hayır, semboller biraz da olsa mantıklı olmalı. Eşitlik testi için bir = kullanabilirsiniz.
busukxuan

Yanıtlar:


3

05AB1E, 92 87 83 82 77 bayt

>i‚˜,}¹iи˜Qis}GD})˜,}¹<i³v²y¢O}){0è,}¹Íi{s{Q,}¹Í<iÙv²y¢O³‹_iy}}),}svy†¬yQi¦}}

İşleme göre böl

>i                      # if 0
  ‚˜,}                  # addition
¹i                      # if 1
  и˜Qis}GD})˜,}        # multiplication
¹<i                     # if 2
   ³v²y¢O}){0è,}        # count
¹Íi                     # if 3
   {s{Q,}               # equality
¹Í<i                    # if 4
   Ùv²y¢O³÷Fy}}),}      # division
                        # else
   svy†¬yQi¦}}          # difference

açıklama

İlave

‚˜,}

Bir torbayı diğerine koyun ve bir torbaya düzleştirin.

Çarpma işlemi

и˜Qis}

Numaranın yığının üstünde olduğundan emin olun. Buna X deyin.

GD})˜,}

Torbayı X kez çoğaltın ve bir torbaya katılın.

saymak

³v²y¢O}){0è,}

Bölen torbasındaki her eleman için, temettü torbasındaki oluşum sayısını sayın.
Minimum sayı, yapabileceğimiz torba sayısı olacaktır.

eşitlik

 {s{Q,}

Her iki torbayı da sıralayın ve eşit olup olmadığını kontrol edin.

Bölünme

Ùv²y¢O³÷Fy}}),}

Her benzersiz elemanın torbada kaç kez meydana geldiğini sayın.
En az bölen kadar fazla olursa. (Nr_of_copies_total // divisor) kopyalarını çantada saklayın.

fark

svy†¬yQi¦}} 

Alt grafikteki her öğe için minuend'in önüne sıralayın.
Geçerli alt grafik, minuend'deki ilk öğeye eşitse minuend'den kaldırın.


9

APL (155)

∆←{O←⍺⍺⋄'+'=O←⎕CR'O':R[⍋R←⍺,⍵]⋄'-'=O:⍺{⍵≡⍬:⍺⋄(⍺/⍨(⍳⍴⍺)≠⍺⍳⊃⍵)∇1↓⍵}⍵⋄(⍬≡⍴⍵)∧K←'×'=O:⍵/⍺⋄K:⍺/⍵⋄'÷'=O:∪⍺⌿⍨⍵≤+/⍺∘.=⍺⋄'⊂'=O:⍵{(∪⍺)≢∪⍵:0⋄1+⍺∇⍵-∆⍺}⍺⋄⍺[⍋⍺]≡⍵[⍋⍵]}⋄⎕

Bu, verilen işlevler için torba işlemlerini tanımlayan bir operatör 'torbasını' tanımlar. Yani +∆ekleme olurdu. Daha sonra klavyeden bir satır okur ve bunu APL ifadesi olarak değerlendirir.

Fonksiyonlar:

  • +∆, ilave
  • -∆, çıkarma
  • ×∆, çarpma işlemi
  • ÷∆, bölünme
  • ⊂∆, sayma
  • ≡∆, denklik (tanınmayan herhangi bir fonksiyonun golf oynaması nedeniyle denklik yapacaktır)

Açıklama:

  • ∆←{... }: bir operatör tanımlayın :

    • O←⍺⍺: verilen işlevi saklayın O( doğrudan ⎕CRçalışmaz ⍺⍺)
    • O←⎕CR'O': bu işlevin dize olarak temsilini alır
    • '+'=O... :: ek olarak,
      • ⍺,⍵: iki listeye birlikte katılın
      • R[⍋R←... ]: ve sonucu sırala
    • '-'=O:: çıkarma için,
      • ⍺{... }⍵: aşağıdaki özyinelemeli işlevi çalıştırır:
        • ⍵≡⍬:⍺: alt proje boşsa, minuend'i iade edin
        • ⍺/⍨(⍳⍴⍺)≢⍺⍳⊃⍵∇1↓⍵: aksi takdirde, alt ekibin ilk öğesini hem alt hem de minuend'ten kaldırın ve tekrar deneyin
    • (⍬=⍴⍵)∧K←'×'=O: çarpma için ve doğru argüman bir çanta değilse:
      • ⍵/⍺: sol argümandaki her öğeyi sağ argümanla çoğalt
    • K:: ... ve sağ argüman eğer olduğunu bir torba:
      • ⍺/⍵: sağ argümandaki her öğeyi sol argümanla çoğaltır (çarpma değişmeli olur)
    • '÷'=O:: bölme için,
      • ⍵≤⍺∘.+⍺: elements 'da hangi öğelerin en az ⍵ kez meydana geldiğine bakın,
      • ⍺/⍨: ⍺,
      • : ve bu listeden tüm kopyaları kaldır
    • '⊂'=O:: saymak için,
      • ⍵{... }⍺: aşağıdaki özyinelemeli işlevi çalıştırır:
        • (∪⍺)≢∪⍵:0: bir listede diğerinin içermediği öğeler varsa, sonuç 0 olur
        • 1+⍺∇⍵-∆⍺: aksi takdirde, temettüyü bölenden çıkarın, tekrar deneyin ve sonucu artırın.
    • : yukarıdakilerin hiçbiri yoksa, denklik testini yapın:
      • ⍺[⍋⍺]≡⍵[⍋⍵]: her iki listeyi de sıralayın ve bunların eşit olup olmadığını görün
  • : klavyeden bir ifade okur, değerlendirir ve sonucu çıkarır.

Test senaryoları:

      ∆←{O←⍺⍺⋄'+'=O←⎕CR'O':R[⍋R←⍺,⍵]⋄'-'=O:⍺{⍵≡⍬:⍺⋄(⍺/⍨(⍳⍴⍺)≠⍺⍳⊃⍵)∇1↓⍵}⍵⋄(⍬≡⍴⍵)∧K←'×'=O:⍵/⍺⋄K:⍺/⍵⋄'÷'=O:∪⍺⌿⍨⍵≤+/⍺∘.=⍺⋄'⊂'=O:⍵{(∪⍺)≢∪⍵:0⋄1+⍺∇⍵-∆⍺}⍺⋄⍺[⍋⍺]≡⍵[⍋⍵]}⋄⎕
⎕:
      1 2 2 3 +∆ 1 2 4
1 1 2 2 2 3 4
      ∆←{O←⍺⍺⋄'+'=O←⎕CR'O':R[⍋R←⍺,⍵]⋄'-'=O:⍺{⍵≡⍬:⍺⋄(⍺/⍨(⍳⍴⍺)≠⍺⍳⊃⍵)∇1↓⍵}⍵⋄(⍬≡⍴⍵)∧K←'×'=O:⍵/⍺⋄K:⍺/⍵⋄'÷'=O:∪⍺⌿⍨⍵≤+/⍺∘.=⍺⋄'⊂'=O:⍵{(∪⍺)≢∪⍵:0⋄1+⍺∇⍵-∆⍺}⍺⋄⍺[⍋⍺]≡⍵[⍋⍵]}⋄⎕
⎕:
      1 2 2 4 -∆ 1 2
2 4
      ∆←{O←⍺⍺⋄'+'=O←⎕CR'O':R[⍋R←⍺,⍵]⋄'-'=O:⍺{⍵≡⍬:⍺⋄(⍺/⍨(⍳⍴⍺)≠⍺⍳⊃⍵)∇1↓⍵}⍵⋄(⍬≡⍴⍵)∧K←'×'=O:⍵/⍺⋄K:⍺/⍵⋄'÷'=O:∪⍺⌿⍨⍵≤+/⍺∘.=⍺⋄'⊂'=O:⍵{(∪⍺)≢∪⍵:0⋄1+⍺∇⍵-∆⍺}⍺⋄⍺[⍋⍺]≡⍵[⍋⍵]}⋄⎕
⎕:
      1 2 3 -∆ 2 4
1 3
      ∆←{O←⍺⍺⋄'+'=O←⎕CR'O':R[⍋R←⍺,⍵]⋄'-'=O:⍺{⍵≡⍬:⍺⋄(⍺/⍨(⍳⍴⍺)≠⍺⍳⊃⍵)∇1↓⍵}⍵⋄(⍬≡⍴⍵)∧K←'×'=O:⍵/⍺⋄K:⍺/⍵⋄'÷'=O:∪⍺⌿⍨⍵≤+/⍺∘.=⍺⋄'⊂'=O:⍵{(∪⍺)≢∪⍵:0⋄1+⍺∇⍵-∆⍺}⍺⋄⍺[⍋⍺]≡⍵[⍋⍵]}⋄⎕
⎕:
      1 2 3 3 4 ×∆ 3
1 1 1 2 2 2 3 3 3 3 3 3 4 4 4
      ∆←{O←⍺⍺⋄'+'=O←⎕CR'O':R[⍋R←⍺,⍵]⋄'-'=O:⍺{⍵≡⍬:⍺⋄(⍺/⍨(⍳⍴⍺)≠⍺⍳⊃⍵)∇1↓⍵}⍵⋄(⍬≡⍴⍵)∧K←'×'=O:⍵/⍺⋄K:⍺/⍵⋄'÷'=O:∪⍺⌿⍨⍵≤+/⍺∘.=⍺⋄'⊂'=O:⍵{(∪⍺)≢∪⍵:0⋄1+⍺∇⍵-∆⍺}⍺⋄⍺[⍋⍺]≡⍵[⍋⍵]}⋄⎕
⎕:
      2 ×∆ 1 3
1 1 3 3
      ∆←{O←⍺⍺⋄'+'=O←⎕CR'O':R[⍋R←⍺,⍵]⋄'-'=O:⍺{⍵≡⍬:⍺⋄(⍺/⍨(⍳⍴⍺)≠⍺⍳⊃⍵)∇1↓⍵}⍵⋄(⍬≡⍴⍵)∧K←'×'=O:⍵/⍺⋄K:⍺/⍵⋄'÷'=O:∪⍺⌿⍨⍵≤+/⍺∘.=⍺⋄'⊂'=O:⍵{(∪⍺)≢∪⍵:0⋄1+⍺∇⍵-∆⍺}⍺⋄⍺[⍋⍺]≡⍵[⍋⍵]}⋄⎕
⎕:
      1 1 2 2 2 ÷∆ 2
1 2
      ∆←{O←⍺⍺⋄'+'=O←⎕CR'O':R[⍋R←⍺,⍵]⋄'-'=O:⍺{⍵≡⍬:⍺⋄(⍺/⍨(⍳⍴⍺)≠⍺⍳⊃⍵)∇1↓⍵}⍵⋄(⍬≡⍴⍵)∧K←'×'=O:⍵/⍺⋄K:⍺/⍵⋄'÷'=O:∪⍺⌿⍨⍵≤+/⍺∘.=⍺⋄'⊂'=O:⍵{(∪⍺)≢∪⍵:0⋄1+⍺∇⍵-∆⍺}⍺⋄⍺[⍋⍺]≡⍵[⍋⍵]}⋄⎕
⎕:
      1 2 2 3 3 3 ÷∆ 3
3
      ∆←{O←⍺⍺⋄'+'=O←⎕CR'O':R[⍋R←⍺,⍵]⋄'-'=O:⍺{⍵≡⍬:⍺⋄(⍺/⍨(⍳⍴⍺)≠⍺⍳⊃⍵)∇1↓⍵}⍵⋄(⍬≡⍴⍵)∧K←'×'=O:⍵/⍺⋄K:⍺/⍵⋄'÷'=O:∪⍺⌿⍨⍵≤+/⍺∘.=⍺⋄'⊂'=O:⍵{(∪⍺)≢∪⍵:0⋄1+⍺∇⍵-∆⍺}⍺⋄⍺[⍋⍺]≡⍵[⍋⍵]}⋄⎕
⎕:
      1 1 2 2 2 2 3 3 3 ⊂∆ 1 2 3
2
      ∆←{O←⍺⍺⋄'+'=O←⎕CR'O':R[⍋R←⍺,⍵]⋄'-'=O:⍺{⍵≡⍬:⍺⋄(⍺/⍨(⍳⍴⍺)≠⍺⍳⊃⍵)∇1↓⍵}⍵⋄(⍬≡⍴⍵)∧K←'×'=O:⍵/⍺⋄K:⍺/⍵⋄'÷'=O:∪⍺⌿⍨⍵≤+/⍺∘.=⍺⋄'⊂'=O:⍵{(∪⍺)≢∪⍵:0⋄1+⍺∇⍵-∆⍺}⍺⋄⍺[⍋⍺]≡⍵[⍋⍵]}⋄⎕
⎕:
      3 2 1 2 ≡∆ 1 2 2 3
1
      ∆←{O←⍺⍺⋄'+'=O←⎕CR'O':R[⍋R←⍺,⍵]⋄'-'=O:⍺{⍵≡⍬:⍺⋄(⍺/⍨(⍳⍴⍺)≠⍺⍳⊃⍵)∇1↓⍵}⍵⋄(⍬≡⍴⍵)∧K←'×'=O:⍵/⍺⋄K:⍺/⍵⋄'÷'=O:∪⍺⌿⍨⍵≤+/⍺∘.=⍺⋄'⊂'=O:⍵{(∪⍺)≢∪⍵:0⋄1+⍺∇⍵-∆⍺}⍺⋄⍺[⍋⍺]≡⍵[⍋⍵]}⋄⎕
⎕:
      1 2 3 ≡∆ 1 2 2 3
0

Gerçekten profesyonel çözüm ve mükemmel yazma! +1

Yazmanız ve açıklamanız gerçekten sağlam! Bir şey olsa da: bölünme için, spesifikasyonun [2,2,2,2,2,2]/3vermesi gereken bir şekilde ifade edildiğine inanıyorum [2,2], ancak sizinki veriyor gibi görünüyor [2].
Değer Mürekkebi

REPL'i kodlamanız gerekmez. Sadece tanımlarsanız , kullanıcı şu anda geçerli olan APL'nin yerel REPL'sine dökülür . Bence iki satır gerektiren tek çıkartma olduğu için çıkartmayı sonuna kadar hareket ettirerek bazı baytlar kaydedebilirsiniz. Bunun yerine, sayıyı sembolize etmek için ⎕CRkullanın *ve O←⍺⍺2sonra 2=O:artı, 1=Omult 0=O:için, equiv, 7<O:count 0<O:için ve div için ( 0>O:subtr için ima edilen ) yapın.
16:32

6

JavaScript (ES6), 260 bayt

(x,o,y,a=a=>a.reduce((r,e,i)=>[...r,...Array(e).fill(i)],[]),b=(a,r=[])=>a.map(e=>r[e]=-~r[e])&&r)=>[z=>a(b(y,z)),z=>y.map(e=>z[e]&&z[e]--)&&a(z),z=>a(z.map(e=>e*y)),z=>a(z.map(i=>i/y|0)),z=>b(y).map((e,i)=>r=Math.min(r,z[i]/e),r=1/0)|r,z=>``+z==b(y)][o](b(x))

3 parametre alır. İlk parametre bir dizidir, ikincisi bir operatördür, üçüncüsü operatöre bağlıdır. Torbaların negatif olmayan tamsayıları tutması gerekir.

[...] 0 [...] -> addition
[...] 1 [...] -> difference
[...] 2 <n> -> multiplication
[...] 3 <n> -> division
[...] 4 [...] -> counting
[...] 5 [...] -> equality

Ungolfed:

function do_bag_op(lhs, op, rhs) {
    function bag2array(bag) {
        return bag.reduce(function (result, entry, index) {
            return result.concat(Array(entry).fill(index));
        }, []);
    }
    function array2bag(array, bag) {
        if (!bag) bag = [];
        array.forEach(function (entry) {
            if (bag[entry]) bag[entry]++;
            else bag[entry] = 1;
        }
        return bag;
    }
    var bag = array2bag(lhs);
    switch (o) {
    case 0: // addition
        return bag2array(array2bag(rhs, bag));
    case 1: // difference
        rhs.forEach(function(entry) {
            if (bag[entry]) bag[entry]--;
        });
        return bag2array(bag);
    case 2: // multiplication
        return bag2array(bag.map(function (entry) {
            return entry * rhs;
        }));
    case 3: // division
        return bag2array(bag.map(function (entry) {
            return Math.floor(entry / rhs);
        }));
    case 4: // counting
        return Math.floor(array2bag(rhs).reduce(function (count, entry, index) {
            return Math.min(count, bag[index] / entry);
        }, Infinity));
    case 5: // equality
        return String(bag) == String(array2bag(rhs));
    }
}

6

Octave, 253 244 226 bayt

function r=f(a,b,o)
u=union(a,b);p=hist(a,u);q=hist(b,u);m=d=0;if(numel(b)==1)m=p.*b;d=p/b;elseif(numel(a)==1)m=a.*q;end
r={p+q,p-q,m,d,min(fix(p./q)),isequal(p,q)}{o};if(o<5)r=[arrayfun(@(x,y)repmat(y,1,x),r,u,'un',0){:}];end

Bu işlev bir dosyada olmalıdır. Fonksiyonu komut penceresine yazmak için endfunctionveya tuşunu kullanmalısınız end.

18 bayt tasarruf için Luis Mendo'ya teşekkürler .

Operasyonlar:

1 = addition
2 = difference
3 = multiplication
4 = division
5 = counting
6 = equality test

Kullanım örneği:

>> f([1,2,2,3], [1,2,4], 1)
ans = 1   1   2   2   2   3   4

>> f([1,2,2,4], [1,2], 2)
ans = 2   4

>> f([1,2,3], [2,4], 2)
ans = 1   3

>> f([1,2,3,3,4], 3, 3)
ans = 1   1   1   2   2   2   3   3   3   3   3   3   4   4   4

>> f(2, [1,3], 3)
ans = 1   1   3   3

>> f([1,1,2,2,2], 2, 4)
ans = 1   2

>> f([1,2,2,3,3,3], 3, 4)
ans =  3

>> f([1,1,2,2,2,2,3,3,3], [1,2,3], 5)
ans =  2

>> f([3,2,1,2], [1,2,2,3], 6)
ans =  1

>> f([1,2,3], [1,2,2,3], 6)
ans = 0

Ungolfed:

function r = f(a,b,o)
    u = union(a,b);
    p = hist(a,u);
    q = hist(b,u);
    m = d = 0;
    if (numel(b)==1)
        m = p.*b;
        d = p/b;
    elseif (numel(a)==1) 
        m = a.*q;
    end
    r = {p+q, p-q, m, d, min(fix(p./q)), isequal(p,q)}{o};
    if (o<5)
        r = [arrayfun(@(x,y) repmat(y, 1, x), r, u, 'un', 0){:}];
    end
end

5

Mathematica, 387 347 300 284 bayt

k=KeyValueMap[Table,#]&;j=b@@Join@@#&;l=List;q=Counts
b~SetAttributes~Orderless
a_b+c_b^:=j@{a,c}
c_b-a_b^:=j@k@Merge[q/@(l@@@{a+c,2a}),-Min[0,+##2-#]&@@#&]
a_b*n_Integer/;n>0^:=a+a*(n-1)
a_Rational c_b^:=j@k[⌊a#⌋&/@q@*l@@c]
a_b==d_b^:=l@@a==l@@d
c_b/a_b^:=If[(c-a)+a==c,1+(c-a)/a,0]

Biraz degolfed (eski sürüm olarak da bilinir), eşitlik testleri için tam desteğe sahip değildi (doğruluk değerleri döndürdü, ancak eşleşmeyen torbalar için değerlendirilmeden bırakıldı).

SetAttributes[b,Orderless]
b/:-a_b:=d@@a
b/:a_b+c_b:=Join[a,c]
d/:a_b+c_d:=b@@Join@@KeyValueMap[Table,Merge[Counts/@(List@@@{a+b@@c,b@@c+b@@c}),Max[0,#-(+##2)]&@@#&]]
b/:Rational[1,a_]c_b:=b@@Join@@KeyValueMap[Table,Floor[#/a]&/@Counts@*List@@c]
b/:(a_b)^-1:=c@@a
c/:a_b d_c:=Min@Merge[Counts/@(List@@@{a,d}),If[+##2==0,\[Infinity],#/+##2]&@@#&]
b/:a_b*n_Integer:=a+a*(n-1)

Gerekli veri türünü head ile uygular b.

İlk bolarak tanımlanır Orderless. Çekirdeğe kafa ile iletilen herhangi bir nesne bargümanlarını otomatik olarak sıralar. Dolayısıyla b[3,2,1], yazılsa bile , değerlendirici asla başka bir şey görmeyecektir b[1,2,3].

Toplama önemsiz olarak elemanlara katılma olarak tanımlanır.

İki torbanın farkı için özel bir kural tanımlanmıştır (aşağıda açıklanmıştır). Önceki sürüm, form ifadeleri için yardımcı bir simgeye sahipti -bag.

Daha sonra çarpma ( npozitif bir tamsayı olduğu sürece ), n*b[...] = b[...] + (n-1)*b[...]nihayetinde basit bir toplamı azaltacak şekilde özyinelemeli olarak tanımlanır .

Özel kural b[...] - b[...], torbaların toplamındaki farklı elemanların sayısını sayar ve bu sonuçtan iki kez çıkarılacak torbayı çıkarır. Daha kolay açıklama:

b[1,2,3,4,5] - b[2,3,6]
Element counts in sum of bags: <|1->1, 2->2, 3->2, 4->1, 5->1, 6->1|>
Element counts in 2x second bag:     <|2->2, 3->2, 6->2|>
Subtracting the corresponding values:
                               <|1->1, 2->0, 3->0, 4->1, 5->1, 6->-1|>

Yukarıda bir liste Keys->Values. KeyValueMapile Tableher Key Valuezamanın listelerini oluşturur . ( Max[...,0]negatif uzunluk tabloları oluşturmaya çalışmayan bir de var). Bu şu şekilde ortaya çıkar:

{{1},{},{},{4},{5},{}}

düzleştirilir ve kafa Listile değiştirilir b.

Tamsayılara göre bölme, kullanılan fonksiyonlarda biraz benzerdir, basitçe, tamsayı tarafından eleman sayımlarının katlanmış bölümüdür.

Setlere göre sayma veya sayma Orijinal uygulamadan bu yana değiştim. Şimdi tekrar tekrar aşağıdaki gibi yapılır. Ki biz torba bölmek b1tarafından b2golfed kodda olan ( cve asırasıyla. Eğer (b1-b2) + b2 == b1, daha sonra 1 ekleyin ve bölünmesi ve bunun sonucunda eklemek (b1-b2)/b2. Değildir, 0 dönmek ve özyinelemeye çıkın.

Çantalar eşleşirse, yerleşik ==verir True. Son satır Falseeğer yapmazlarsa a'yı zorlar .

Test senaryoları:

Input:
b[1, 2, 2, 3] + b[1, 2, 4]
b[1, 2, 2, 4] - b[1, 2]
b[1, 2, 3] - b[2, 4]
b[1, 2, 3, 3, 4]*3
2*b[1, 3]
b[1, 1, 2, 2, 2]/2
b[1, 2, 2, 3, 3, 3]/3
b[1, 1, 2, 2, 2, 2, 3, 3, 3] /b[1, 2, 3]
b[3, 2, 1, 2] == b[1, 2, 2, 3]
b[1, 2, 3] == b[1, 2, 2, 3]

Output:
b[1, 1, 2, 2, 2, 3, 4]
b[2, 4]
b[1, 3]
b[1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4]
b[1, 1, 3, 3]
b[1, 2]
b[3]
2
True
False

2

Q - 219 karakter

a:(,)
s:{[x;y]x((!:)(#:)x)except(,/)({.[(#);x]}')flip(7h$(({(+/)x=y}[y]')(?:)y);(({where x=y}[x]')y))}
m:{(,/)$[0>(@:)x;(#[x]')y;(#[y]')x]}
d:{(?:)x(&:)({y<=(+/)x=z}[x;y]')x}
c:{min({(+/)x=y}[x]')y}
e:{(asc x)~asc y}

ailave edilmesi için, sfark (çıkarma) için mçoğalması için, dbölme için, csayım için, eeşitlik için.

Ekleme algoritması barizdir, sadece torbalara katılır.

Çıktı işlevindeki çıkarma dizisi (dizi olarak temsil edilir), içindeki nher öğeye eşitlikle oluşturulan her eşdeğerlik sınıfının ilk endeksleri hariç y, burada nbu temsilcinin kopya sayısıdır y. Olası kopyaları ele almak y, bu işlevi gerçek bir canavar haline getirir.

Çarpma işlevi xher birinden değerleri alır , bir dizi yerine tek bir değer yolması durumunda, ybunları çoğaltır.

Bölme işlevi, dizideki sayısı daha büyük olan değerleri üretir ve yyinelenenleri kaldırır.

Sayma işlevi, içindeki her öğenin sayısını hesaplar yve ardından minimum değeri döndürür.

Sıralı dizi gösterimleri eşitse iki torba eşittir.


2

Yakut, sınıf tanımı cevap, 323 291 bayt

Çoğunlukla BagRuby'nin sınıflarla esnekliği nedeniyle gerçek bir sınıf yapmak istedim . Bu durumda, Arraydahili bir dizi başlatmak ve diğer şeylerle uğraşmaktan daha kısa olduğu için miras alınır .

Muhtemelen yarınki operasyonlarla başa çıkmak için bir fonksiyon kullanan daha ciddi bir golf cevabı vereceğim. Çok yoruldum ve düzgün çalışabilmek için sayısal sınıf tanımıylaNumber * Bag uğraşmak zorunda kalsam da bu konuda çok eğlendim. NEREDE SINIF TANIMLARINI MESAJ ETMEYE ÇIKMAK İÇİN COERCE FONKSİYONU

Çevrimiçi deneyin! (Beyaz alanın Ruby'de önemi yoktur, bu nedenle kod orada hafifçe çözülmüştür.)

class B<Array
def == o
sort==o.sort
end
def + o
B.new super
end
def - o
r=to_a
o.map{|i|r[r.index(i)||size]=p}
B.new r-[p]
end
def * i
B.new super
end
def / i
B.new uniq.map{|o|[o]*(count(o)/i)}.flatten
end
def c o
o.map{|i|count i}.min
end
def inspect
sort
end
def coerce o
[self,o]
end
end

1

Yakut, 201 bayt

Diğer cevabımda söz verdiğim gibi, burada yeni bir sınıf oluşturmak yerine işlevleri kullanan bir soru var. 200 bayt işaretini ihlal etmeye çok yakınım ... Çevrimiçi deneyin

Bu, JavaScript yanıtında @Neil ile aynı opcodes'i ve aynı argüman sırasını (lhs, opcode, rhs) kullanır.

0: Addition
1: Difference
2: Multiplication
3: Division
4: Counting
5: Equality

Kod:

->x,o,y{[->{(x+y).sort},->r=[*x]{y.map{|i|r[r.index(i)||x.size]=p};r-[p]},->{(x==[*x]?x*y :y*x).sort},->{x.uniq.map{|i|[i]*(x.count(i)/y)}.flatten},->{y.map{|i|x.count i}.min},->{x.sort==y.sort}][o][]}

1

C ++, 555 551 bayt

(okunabilirlik için satır sonları eklendi - yalnızca ilk satırsonu gerekli ve sayıldı)

#include<map>
struct B:std::map<int,int>{
B(std::initializer_list<int>l){for(auto i:l)++(*this)[i];}};
B operator+(B a,B b){for(auto m:b)a[m.first]+=m.second;return a;}
B operator-(B a,B b){for(auto m:b){int&x=a[m.first];x-=x>m.second?m.second:x;if(!x)a.erase(m.first);};return a;}
B operator*(B b,int n){for(auto m:b)b[m.first]*=n;return b;}
B operator*(int n,B b){return b*n;}
B operator/(B b,int n){for(auto m:b)if(!(b[m.first]/=n))b.erase(m.first);return b;}
int operator/(B a,B b){auto r=~0u;for(auto m:b){int x=a[m.first]/m.second;r=r>x?x:r;}return r;}

açıklama

Çantanızı (değer, sayı) haritası olarak uyguluyoruz. Temel işlemler sayıları manipüle ederek uygulanabilir; çıkarma ve tamsayı bölümünün de sayısı sıfıra ulaşan tüm öğeleri kaldırması gerekir, böylece std::map::operator==eşitlik testi olarak çalışır.

Aşağıdaki genişletilmiş kod, yukarıdakilerin genel bir versiyonudur, çok daha az golfçüdür: s()sıfır sayım değerlerini sıkıştırmak için ayrı bir yöntem kullanırız ve constatama operatörleri açısından işlemleri deyimsel C ++ yolunda uygularız . Biz de kullanmak s()tarafından çarpma yapmak için 0dönüş (ekleyerek test gerçekten boş torbayı (B{1}*0 != B{})için main()); orijinal bu testi geçemez ve bunun bir gereklilik olup olmadığı net değildir.

template<class T>
struct Bag{
    std::map<T,int>b;
    Bag(const std::initializer_list<T>& l){for(auto i:l)++b[i];}
    Bag&s(){for(auto i=b.begin();i!=b.end();i=i->second?++i:b.erase(i));return*this;}
    Bag&operator+=(const Bag& o){for(auto m:o.b)b[m.first]+=m.second;return*this;}
    Bag&operator-=(const Bag& o){for(auto m:o.b){auto&x=b[m.first];x-=x>m.second?m.second:x;}return s();}
    Bag&operator*=(int n){for(auto m:b)b[m.first]*=n;return s();}
    Bag&operator/=(int n){for(auto m:b)b[m.first]/=n;return s();}
    auto operator/=(const Bag& o){auto r=~0u;for(auto m:o.b){int x=b[m.first]/m.second;r=r>x?x:r;}return r;}
    bool operator==(const Bag& o)const{return b==o.b;}

    Bag operator+(Bag o)const{return o+=*this;}
    Bag operator-(const Bag& o)const{Bag t=*this;return t-=o;}
    Bag operator*(int n)const{Bag t=*this;return t*=n;}
    friend Bag operator*(int n,const Bag& b){return b*n;}
    auto operator/(auto n)const{Bag t=*this;return t/=n;}
    bool operator!=(const Bag& o)const{return b!=o.b;}
};

using B = Bag<int>;

Testler

bool operator!=(B a,B b){return!(a==b);}
int main()
{
    return 0
        + (B{1,2,2,3}+B{1,2,4}  !=  B{1,1,2,2,2,3,4})
        + (B{1,2,2,4}-B{1,2}  !=  B{2,4})
        + (B{1,2,3}-B{2,4}  !=  B{1,3})
        + (B{1,2,3,3,4}*3  !=  B{1,1,1,2,2,2,3,3,3,3,3,3,4,4,4})
        + (2*B{1,3}  !=  B{1,1,3,3})
        + (B{1,1,2,2,2}/2  !=  B{1,2})
        + (B{1,2,2,3,3,3}/3  !=  B{3})
        + (B{1,1,2,2,2,2,3,3,3}/B{1,2,3} != 2)
        + (B{3,2,1,2}  !=  B{1,2,2,3})
        + (B{1,2,3}  ==  B{1,2,2,3})
        ;
}

Güzel cevap! +1. Kodunuzun yayında doğru biçimlendirmeye ihtiyacı var.
Yytsi

Kasten kodu sarmak istedim, böylece hepsini görebilirsiniz. Alternatif satır sonları eklemekti.
Toby Speight

1
Satır kesmeleri eklendi - Bence bu daha iyi, çünkü şimdi güzelleştirme işe yarıyor.
Toby Speight

1

Python 2.7 - 447B (dosya boyutu)

Bu Codegolf'ta ilk denemem, umarım tatmin olur. 2 saat ihtiyacım vardı. (Ama ben hala Python'da yeni başlıyorum)

Düzenleme: Bu işaret için "Kevin Lau - Kenny değil" için teşekkürler:

  • sınıftaki pitonların kendi argümanları herhangi bir şeyle değiştirilebilir
  • girinti yalnızca tek bir boşluk olmalıdır
  • yerleşik sıralanmış - funktion (onu gördüğümü biliyordum , ama listelerde bir yöntem olduğunu düşündüm)
  • __ radd __ gerekli değil (yine de yalnızca B-nesnelerinin (Çanta tipi) eklenmesini destekliyorum)

Düzenleme: Ayrıca lambdas ve yeni çizgiler ve girinti daha noktalı virgül ile işlevleri değiştirerek yerden tasarruf.

Kod:

class B:
 def __init__(S,L=[]):S.L=sorted(list(L));S.p=lambda:[[i]*S.L.count(i)for k,i in enumerate(S.L)if i!=S.L[k-1]];S.__eq__=lambda o:S.L==o.L;S.__rmul__=S.__mul__=lambda o:B(S.L*o);S.__add__=lambda o:B(S.L+o.L);S.__sub__=lambda o:B([i for k in S.p()for i in k[:max(0,S.L.count(k[0])-o.L.count(k[0]))]]);S.__div__=lambda o:B([i for k in S.p()for i in k[::o][:[-1,None][len(k)%o==0]]]);S.c=lambda o:min([S.L.count(i)//o.L.count(i)for i in o.L])

çekler:

print B([1,2,2,3]) + B([1,2,4]) == B([1,1,2,2,2,3,4]) # Add

print B([1,2,2,4]) - B([1,2]) == B([2,4]) #Substract
print B([1,2,3])   - B([2,4]) == B([1,3]) #Substract

print B([1,2,3,3,4]) * 3 == B([1,1,1,2,2,2,3,3,3,3,3,3,4,4,4])#Multiply
print 2 * B([1,3]) == B([1,1,3,3])                            #

print B([1,1,2,2,2])   /2 == B([1,2]) #Divide
print B([1,2,2,3,3,3]) /3 == B([3])   #

print B([1,1,2,2,2,2,3,3,3]).c(B([1,2,3]))==2 #Contained n times

print B([3,2,1,2]) == B([1,2,2,3]) # Equal
print B([1,2,3])   == B([1,2,2,3]) # Unequal

Çıktı:

True
True
True
True
True
True
True
True
True
False

Bir süre dayanarak ayarlanmış başka bir zaman deneyebilirsiniz. Düzenleme: Belki de sadece fonksiyonları ile deneyeceğim.


PPCG'ye Hoşgeldiniz! Python hakkında dikkat edilmesi gereken bir şey, aslında sınıf işlevlerindeki ilk parametreleri çağırmanıza gerek kalmamasıdır self- aynı şey de Saynı şeydir . Başka bir hile, yerleşik sortedfonksiyonun yeni fonksiyonunuzdan tam olarak ne istediğinizi syapmasıdır, böylece fonksiyon tanımından vazgeçebilirsiniz (sadece bir kez kullandığınızı görerek). Hiç ihtiyacınız yok __radd__çünkü hala ihtiyacınız olmasa da asla çantalı torba eklemeyin __rmul__. Son olarak, bayt sayınızı biraz azaltan dört yerine sadece bir girinti alanına ihtiyacınız var
Value Ink
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.