Thực hiện các hoạt động túi


20

Một chiếc túi , còn được gọi là multiset, là một bộ sưu tập không có thứ tự. Bạn có thể gọi nó là một tập hợp cho phép trùng lặp hoặc một danh sách (hoặc một mảng) không được sắp xếp / lập chỉ mục. Trong thử thách này, bạn được yêu cầu thực hiện các thao tác túi: cộng, chênh lệch, nhân, chia, đếm và kiểm tra đẳng thức.

Hoạt động

Các hoạt động được chỉ định có thể không được thông thường.

  • Ngoài ra, kết hợp hai túi thành một, bảo toàn tổng số của mỗi giá trị
    [1,2,2,3] + [1,2,4] = [1,1,2,2,2,3,4]
  • sự khác biệt loại bỏ khỏi túi mỗi yếu tố của túi khác hoặc không làm gì nếu không có yếu tố đó
    [1,2,2,4] - [1,2] = [2,4] [1,2,3] - [2,4] = [1,3]
  • phép nhân nhân từng phần tử trong túi.
    [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]
  • phép chia là một trường hợp không phổ biến: mỗi n phần tử bằng nhau được đặt trong n túi mới bằng nhau, các phần tử không thể tạo thành nhóm n vẫn còn trong túi. Trả lại bất kỳ một trong n túi mới.
    [1,1,2,2,2] / 2 = [1,2] [1,2,2,3,3,3] / 3 = [3]
  • đếm đếm có bao nhiêu túi chia có thể được sản xuất từ ​​túi cổ tức
    [1,1,2,2,2,2,3,3,3] c [1,2,3] = 2
  • kiểm tra sự bằng nhau kiểm tra nếu hai túi có cùng số của mỗi phần tử
    [1,2,2,3] == [3,2,1,2] = truthy [1,2,3] == [1,2,2,3] = falsy(cũng có thể sử dụng =cho điều này)

Nếu bạn đang sử dụng các ký hiệu của riêng mình cho các toán tử, vui lòng chỉ định.

Các định dạng

Túi sẽ được hiển thị dưới dạng danh sách của mẫu [1,1,2,3,4]. Bạn có thể sử dụng bất kỳ dấu ngoặc nào khác ngoài dấu vuông hoặc thậm chí sử dụng dấu ngoặc kép hoặc không có gì cả. Các yếu tố sẽ là số nguyên (về mặt toán học, không nhất thiết int) cho mục đích của câu hỏi này. Túi không phải được sắp xếp.

Các định dạng đầu vào sẽ có hai túi hoặc một chiếc túi và một số nguyên, với một nhà điều hành. Bạn có thể chỉ định định dạng của riêng mình miễn là nó chứa ba định dạng này.

Các định dạng đầu ra phải là một túi duy nhất của định dạng tương tự.

Quy tắc

  • bạn không được sử dụng các hàm, thao tác hoặc thư viện tích hợp (bao gồm cả thư viện chuẩn) đã triển khai các hàm này; Mặc dù sử dụng phép nối và nhân danh sách cũng không sao vì chúng là do hoạt động của danh sách định nghĩa, không phải là hoạt động túi (điều này về cơ bản làm điều tương tự)
  • sơ hở tiêu chuẩn áp dụng
  • câu trả lời ngắn nhất sẽ thắng

Các trường hợp thử nghiệm

[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
Có thể thư giãn các định dạng đầu vào? Ví dụ: cho phép lấy túi, túi / số và toán tử làm đối số riêng biệt hoặc ở định dạng miễn phí. Mặt khác, một phần quan trọng của thử thách là phân tích cú pháp đầu vào, điều này không đặc biệt thú vị
Luis Mendo

@LuisMendo split-on-space đủ để phân tích điều này, nếu bạn có một ngôn ngữ có thể đánh giá các chuỗi dưới dạng danh sách, bạn có nghĩ vậy không? Tôi thiếu kinh nghiệm trong việc đăng các thử thách, vì vậy xin hãy khai sáng cho tôi :-)
busukxuan

Tôi không thể tìm thấy một bài đăng meta có liên quan, nhưng hãy xem ví dụ từ ngữ ở đây : bạn có thể đọc số nguyên dưới dạng biểu diễn thập phân của nó, biểu diễn đơn nhất (sử dụng một ký tự bạn chọn), mảng byte (endian lớn hoặc nhỏ) hoặc byte đơn (nếu đây là loại ngôn ngữ lớn nhất của bạn) . Hoặc ở đây : Định dạng đầu vào và đầu ra linh hoạt như bình thường (mảng, danh sách, danh sách danh sách, chuỗi có dấu phân cách hợp lý, v.v. ).
Luis Mendo

@LuisMendo về cơ bản là miễn phí. Và về số nguyên, tôi chỉ có nghĩa là theo nghĩa toán học, không phải kiểu dữ liệu.
busukxuan

1
@LuisMendo không, các biểu tượng cần có ý nghĩa, dù chỉ một chút. Chà, bạn có thể sử dụng one = để kiểm tra đẳng thức.
busukxuan

Câu trả lời:


3

05AB1E, 92 87 83 82 77 byte

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

Chia theo hoạt động

>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

Giải trình

Thêm vào

‚˜,}

Đặt một túi khác và làm phẳng chúng vào một túi.

Phép nhân

и˜Qis}

Hãy chắc chắn rằng số nằm trên đỉnh của ngăn xếp. Gọi đây là X.

GD})˜,}

Nhân đôi túi X lần và nối với một túi.

Đếm

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

Đối với mỗi yếu tố trong túi chia, hãy đếm số lần xuất hiện trong túi cổ tức.
Số lượng tối thiểu sẽ là số lượng túi chúng ta có thể làm.

Bình đẳng

 {s{Q,}

Sắp xếp cả hai túi và kiểm tra xem chúng có bằng nhau không.

Bộ phận

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

Đếm số lần mỗi yếu tố duy nhất xảy ra trong túi.
Nếu nó xảy ra ít nhất nhiều lần như là ước. Giữ các bản sao (nr_of_copies_total // divisor) trong túi.

Sự khác biệt

svy†¬yQi¦}} 

Đối với mỗi phần tử trong phần phụ, hãy sắp xếp nó vào phía trước của phần tử.
Nếu phụ đề hiện tại nếu bằng phần tử đầu tiên trong phần khai thác, hãy xóa phần tử đó khỏi phần tử phụ.


9

APL (155)

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

Điều này xác định một 'túi' của toán tử , định nghĩa các hoạt động của túi cho các chức năng nhất định. Tức là +∆sẽ được bổ sung. Sau đó nó đọc một dòng từ bàn phím và đánh giá nó như một biểu thức APL.

Các chức năng là:

  • +∆, thêm vào
  • -∆, phép trừ
  • ×∆, phép nhân
  • ÷∆, bộ phận
  • ⊂∆, đếm
  • ≡∆, tính tương đương (mặc dù do chơi golf, bất kỳ chức năng nào không được công nhận sẽ làm tương đương)

Giải trình:

  • ∆←{... }: xác định toán tử :

    • O←⍺⍺: lưu trữ hàm đã cho trong O( ⎕CRsẽ không hoạt động ⍺⍺trực tiếp)
    • O←⎕CR'O': lấy biểu diễn chuỗi của hàm đó
    • '+'=O... :: ngoài ra,
      • ⍺,⍵: tham gia hai danh sách cùng nhau
      • R[⍋R←... ]: và sắp xếp kết quả
    • '-'=O:: để trừ
      • ⍺{... }⍵: Chạy hàm đệ quy sau:
        • ⍵≡⍬:⍺: nếu subrahend trống, trả về minuend
        • ⍺/⍨(⍳⍴⍺)≢⍺⍳⊃⍵∇1↓⍵: nếu không, hãy xóa phần tử đầu tiên của phần phụ khỏi cả phần phụ và phần tử và thử lại
    • (⍬=⍴⍵)∧K←'×'=O: để nhân, và nếu đối số đúng không phải là một cái túi:
      • ⍵/⍺: sao chép từng phần tử trong đối số bên trái bằng đối số bên phải
    • K:: ... và nếu đối số đúng một cái túi:
      • ⍺/⍵: sao chép từng phần tử trong đối số bên phải bằng đối số bên trái (điều này sao cho phép nhân là giao hoán)
    • '÷'=O:: để phân chia,
      • ⍵≤⍺∘.+⍺: xem phần tử nào trong xảy ra ít nhất lần,
      • ⍺/⍨: chọn những người từ ⍺,
      • : và xóa tất cả các bản sao khỏi danh sách đó
    • '⊂'=O:: để đếm
      • ⍵{... }⍺: Chạy hàm đệ quy sau:
        • (∪⍺)≢∪⍵:0: nếu một danh sách chứa các thành phần khác thì không, kết quả là 0
        • 1+⍺∇⍵-∆⍺: nếu không, hãy trừ cổ tức từ số chia, thử lại và tăng kết quả.
    • : nếu không có điều nào ở trên, hãy làm bài kiểm tra tương đương:
      • ⍺[⍋⍺]≡⍵[⍋⍵]: sắp xếp cả hai danh sách và xem chúng có bằng nhau không
  • : đọc một biểu thức từ bàn phím, đánh giá nó và đưa ra kết quả.

Các trường hợp thử nghiệm:

      ∆←{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

Giải pháp thực sự chuyên nghiệp và viết lên tuyệt vời! +1

Viết và giải thích của bạn là thực sự vững chắc! Mặc dù vậy, có một điều: đối với sự phân chia, tôi tin rằng thông số kỹ thuật được diễn đạt theo cách [2,2,2,2,2,2]/3nên cho [2,2], nhưng dường như bạn cho [2].
Mực giá trị

Bạn không cần mã REPL. Nếu bạn chỉ xác định , người dùng sẽ được chuyển vào REPL gốc của APL, nơi hiện hợp lệ. Tôi nghĩ rằng bạn có thể lưu một số byte bằng cách di chuyển phép trừ đến cuối vì nó là cái duy nhất yêu cầu hai dòng. Thay vì ⎕CR, sử dụng *để tượng trưng cho đếm, và làm O←⍺⍺2, sau đó 2=O:cộng, 1=Ocho nhiều, 0=O:cho đẳng thức, 7<O:cho đếm và 0<O:cho div (với ngụ ý 0>O:cho subtr).
Adám

6

JavaScript (ES6), 260 byte

(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))

Có 3 tham số. Tham số đầu tiên là một mảng, thứ hai là một toán tử, thứ ba phụ thuộc vào toán tử. Túi được yêu cầu để giữ số nguyên không âm.

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

Ung dung:

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 byte

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

Chức năng này phải có trong một tập tin. Để viết hàm trong cửa sổ lệnh, bạn phải sử dụng endfunctionhoặc end.

Cảm ơn Luis Mendo vì đã tiết kiệm 18 byte.

Các hoạt động là:

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

Ví dụ sử dụng:

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

Ung dung:

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

Toán học, 387 347 300 284 byte

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]

Hơi xuống cấp (hay còn gọi là phiên bản cũ), không hỗ trợ đầy đủ cho các bài kiểm tra tính công bằng (trả về các giá trị trung thực, nhưng không được đánh giá cho các túi không phù hợp).

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)

Thực hiện kiểu dữ liệu cần thiết với đầu b.

Đầu tiên bđược xác định là Orderless. Bất kỳ đối tượng nào được truyền vào kernel có head bsẽ tự động điền các đối số của nó. Vì vậy, ngay cả khi b[3,2,1]được gõ vào, người đánh giá sẽ không bao giờ nhìn thấy gì khác ngoài b[1,2,3].

Bổ sung được định nghĩa tầm thường là tham gia các yếu tố.

Một quy tắc đặc biệt cho sự khác biệt của hai túi được xác định (giải thích bên dưới). Phiên bản trước có một biểu tượng phụ cho biểu thức của hình thức -bag.

Sau đó phép nhân (miễn nlà số nguyên dương) được định nghĩa đệ quy vì n*b[...] = b[...] + (n-1)*b[...]cuối cùng sẽ giảm xuống một tổng đơn giản.

Quy tắc đặc biệt để b[...] - b[...]đếm số lượng phần tử riêng biệt trong tổng của các túi và trừ đi túi được trừ hai lần từ kết quả đó. Giải thích dễ dàng hơn:

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

Trên đây là danh sách Keys->Values. KeyValueMapvới việc Tabletạo danh sách mỗi Key Valuelần. (cũng Max[...,0]có ở đó để không cố gắng tạo các bảng có chiều dài âm). Điều này xuất hiện dưới dạng:

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

được làm phẳng và đầu Listđược thay thế bằng b.

Phân chia theo số nguyên có phần giống nhau trong các hàm được sử dụng, nó chỉ đơn giản là phân chia nổi của phần tử được tính theo số nguyên.

Chia theo bộ hoặc đếm Tôi đã thay đổi kể từ khi thực hiện ban đầu. Bây giờ nó được thực hiện đệ quy như sau. Giả sử, chúng ta chia túi b1cho b2(mà trong mã được đánh dấu catương ứng. Nếu (b1-b2) + b2 == b1, sau đó thêm 1 và thêm vào đó là kết quả của phép chia (b1-b2)/b2. Nếu không, trả về 0 và thoát khỏi đệ quy.

Nếu túi phù hợp, tích hợp ==cho True. Dòng cuối cùng buộc Falsenếu họ không.

Các trường hợp thử nghiệm:

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 ký tự

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}

acho phép cộng, scho sự khác biệt (phép trừ), mcho phép nhân, dphép chia, cphép đếm, echo đẳng thức.

Các thuật toán bổ sung là một trong những rõ ràng, chỉ cần tham gia các túi.

Hàm trừ chỉ mục trong túi đầu vào (được biểu diễn dưới dạng một mảng) với toàn bộ phạm vi chỉ mục, ngoại trừ các nchỉ số đầu tiên của mỗi lớp tương đương được hình thành bởi sự bằng nhau cho mỗi phần tử y, trong đó nsố lượng bản sao của đại diện đó trong đó y. Xử lý các bản sao có thể ylàm cho điều này trở thành một con quái vật thực sự của một chức năng.

Hàm nhân có xcác giá trị từ mỗi y, trong trường hợp ylà một giá trị duy nhất, thay vì một mảng, nó chỉ sao chép chúng.

Hàm phân chia tạo ra các giá trị có số đếm trong mảng lớn hơn yvà sau đó loại bỏ các bản sao.

Hàm đếm tính toán số đếm của từng phần tử yvà sau đó trả về mức tối thiểu.

Hai túi bằng nhau nếu biểu diễn mảng được sắp xếp của chúng bằng nhau.


2

Ruby, câu trả lời định nghĩa lớp, 323 291 byte

Hầu như chỉ muốn tạo ra Bagmột lớp học thực sự vì sự linh hoạt của Ruby với các lớp học. Trong trường hợp này, nó kế thừa từ Arrayvì nó ngắn hơn việc phải khởi tạo một mảng bên trong và xử lý các thứ khác.

Có lẽ tôi sẽ làm một câu trả lời golf nghiêm túc hơn, sử dụng một chức năng để đối phó với các hoạt động vào ngày mai. Tôi rất mệt mỏi và tôi đã có quá nhiều niềm vui với điều này mặc dù tôi phải thay đổi định nghĩa lớp số để Number * Baghoạt động đúng. ĐẢM BẢO CHỨC NĂNG TUYỆT VỜI ĐỂ KIẾM ĐƯỢC NHƯ VẬY TÔI KHÔNG CẦN GỬI NHỮNG ĐỊNH NGH DEA SỐ LỚP

Hãy thử trực tuyến! (Khoảng trắng không quan trọng trong Ruby, vì vậy mã hơi bị sai lệch ở đó.)

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

Ruby, 201 byte

Như đã hứa trong câu trả lời khác của tôi, đây là một trong đó sử dụng các hàm thay vì xây dựng một lớp mới. Tôi rất gần với việc vi phạm mốc 200 byte ... Hãy thử trực tuyến

Điều này sử dụng các mã tương tự như @Neil trong câu trả lời JavaScript của anh ấy và cùng thứ tự các đối số (lhs, opcode, rhs)

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

Mật mã:

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

(ngắt dòng được thêm vào để dễ đọc - chỉ có dòng mới đầu tiên được yêu cầu và tính)

#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;}

Giải trình

Chúng tôi thực hiện túi của chúng tôi như một bản đồ (giá trị, tính). Các hoạt động cơ bản có thể được thực hiện bằng cách thao tác đếm; phép trừ và phép chia số nguyên cũng cần loại bỏ bất kỳ phần tử nào có số đếm bằng 0, do đó std::map::operator==sẽ hoạt động như kiểm tra đẳng thức.

Mã mở rộng sau đây là phiên bản chung của phần trên, ít được đánh gôn hơn: chúng tôi sử dụng một mã riêng s()để loại bỏ bất kỳ giá trị số 0 nào và chúng tôi thực hiện các consthoạt động theo các toán tử gán theo cách thức C ++. Chúng tôi cũng sử dụng s()để nhân lên bằng cách 0trả lại một túi thực sự trống (được kiểm tra bằng cách thêm (B{1}*0 != B{})vào main()); bản gốc thất bại trong bài kiểm tra này và không rõ liệu đó có phải là một yêu cầu hay không.

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

Xét nghiệm

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})
        ;
}

Câu trả lời tốt đẹp! +1. Mã của bạn cần định dạng thích hợp trong bài viết.
Yytsi

Tôi cố tình muốn mã để bọc, vì vậy bạn có thể thấy tất cả. Thay thế là thêm ngắt dòng.
Toby Speight

1
Ngắt dòng được thêm vào - Tôi nghĩ rằng điều này là tốt hơn, bởi vì hiện tại prettify hoạt động.
Toby Speight

1

Python 2.7 - 447B (kích thước tệp)

Đây là lần thử đầu tiên của tôi tại Codegolf, tôi hy vọng nó sẽ thỏa mãn. Tôi cần 2h. (Nhưng tôi vẫn là người mới bắt đầu tại Python)

Chỉnh sửa: Cảm ơn "Kevin Lau - không phải Kenny" vì đã chỉ ra những điều này:

  • pythons tự tranh luận trong một lớp có thể được thay thế bởi bất cứ điều gì
  • thụt chỉ phải là một không gian duy nhất
  • phần dựng sẵn được sắp xếp - funktion (tôi biết tôi đã nhìn thấy nó, nhưng tôi nghĩ nó là một phương thức trong danh sách)
  • __ radd __ không cần thiết (tôi chỉ hỗ trợ thêm các đối tượng B (loại Túi)

Chỉnh sửa: Ngoài ra, tôi đã tiết kiệm không gian bằng cách thay thế các chức năng bằng lambdas và các dòng và thụt lề mới bằng nhiều dấu chấm phẩy hơn.

Mã số:

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

kiểm tra:

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

Đầu ra:

True
True
True
True
True
True
True
True
True
False

Tôi có thể thử nó một thời gian khác với thiết lập làm cơ sở một thời gian. Chỉnh sửa: Có lẽ tôi thậm chí sẽ chỉ thử với các chức năng.


Chào mừng đến với PPCG! Một điều cần lưu ý về Python là bạn thực sự không cần phải gọi các tham số đầu tiên trong các hàm của lớp self- một cái gì đó giống như Ssẽ làm tốt như vậy. Một mẹo khác là sortedhàm tích hợp thực hiện chính xác những gì bạn muốn từ hàm mới s, do đó bạn có thể từ bỏ định nghĩa hàm (xem như bạn chỉ sử dụng nó một lần). Bạn không bao giờ cần __radd__bởi vì bạn không bao giờ thêm túi không có túi, mặc dù bạn vẫn cần __rmul__. Cuối cùng, bạn chỉ cần một không gian thụt lề thay vì bốn, làm giảm số byte của bạn xuống một chút
Giá trị Ink
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.