백 작동 구현


20

가방 또한 MULTISET라고는 정렬되지 않은 모음입니다. 중복을 허용하는 세트 또는 순서 / 인덱싱되지 않은 목록 (또는 배열)을 호출 할 수 있습니다. 이 과제에서는 덧셈, 차이, 곱셈, 나눗셈, 계산 및 평등 테스트와 같은 백 연산을 구현해야합니다.

운영

지정된 작업이 일반적인 작업이 아닐 수 있습니다.

  • 또한 두 개의 백을 하나로 결합하여 각 값의 총 수를 보존합니다.
    [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]
  • 나눗셈 은 드문 일입니다. 각 n 개의 동일한 요소는 n 개의 동일한 새 백에 넣고 n 그룹을 형성 할 수없는 요소는 백에 남아 있습니다. 새 가방 중 하나를 반환하십시오.
    [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
  • 동등성 테스트 는 두 개의 백에 각 요소의 개수가 같은지 확인합니다
    [1,2,2,3] == [3,2,1,2] = truthy [1,2,3] == [1,2,2,3] = falsy(이에 사용할 수도 있음 =)

연산자에 고유 한 기호를 사용하는 경우 지정하십시오.

체재

가방이 양식 목록으로 표시됩니다 [1,1,2,3,4]. 정사각형 이외의 대괄호를 사용하거나 따옴표를 사용하거나 전혀 사용할 수 없습니다. int이 질문의 목적을 위해 요소는 (수학적으로, 반드시는 아니지만 ) 정수 입니다. 가방을 분류 할 필요는 없습니다.

입력 형식은 오퍼레이터 두 가방 또는 주머니와 정수 것이다. 이 세 가지가 포함되어 있으면 원하는 형식을 지정할 수 있습니다.

출력 형식 과 동일한 형식의 단일 부대이어야한다.

규칙

  • 이미 구현 한 내장 함수, 작업 또는 라이브러리 (표준 라이브러리 포함)를 사용할 수 없습니다. 비록리스트 연산과 곱셈을 사용하는 것은 괜찮습니다. 그것들은 백 연산이 아닌 정의 목록 연산에 의한 것입니다 (기본적으로 같은 일을합니다)
  • 표준 허점 적용
  • 최단 답변 승리

테스트 사례

[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
입력 형식을 완화 하시겠습니까? 예를 들어, bag, bag / number 및 operator를 별도의 인수로 또는 자유 형식으로 사용하십시오. 그렇지 않으면 도전의 중요한 부분은 입력을 파싱하는 것인데, 특히 흥미롭지는 않습니다.
Luis Mendo

@LuisMendo 공간 분할은 이것을 구문 분석하기에 충분합니다. 문자열을 목록으로 평가할 수있는 언어가 있다면 생각하지 않습니까? 도전 과제를 게시 한 경험이 없으니 제발
깨달아

관련 메타 게시물을 찾을 수 없지만 여기 에서 단어를 참조 하십시오 : 정수를 10 진수 표현, 단항 표현 (선택한 문자 사용), 바이트 배열 (큰 또는 작은 엔디안) 또는 단일 바이트로 읽을 수 있습니다 (이 언어가 가장 큰 데이터 유형 인 경우) . 또는 여기에서 : 입력 및 출력 형식은 평소처럼 유연합니다 (배열, 목록, 목록 목록, 적절한 구분 기호가있는 문자열 등 ).
Luis Mendo

@LuisMendo 기본적으로 무료입니다. 그리고 정수에 관해서는 데이터 형식이 아니라 수학적 의미에서 의미했습니다.
busukxuan

1
@LuisMendo 아니, 조금이라도 기호가 의미가 있어야합니다. 음, 등식 테스트에 하나 =를 사용할 수 있습니다.
busukxuan

답변:


3

05AB1E, 92 87 83 82 77 바이트

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

작업 별 분할

>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

설명

부가

‚˜,}

한 봉지를 다른 봉지에 넣고 한 봉지로 납작하게 만듭니다.

곱셈

и˜Qis}

숫자가 스택 상단에 있는지 확인하십시오. 이것을 X라고 부릅니다.

GD})˜,}

가방을 X 번 복제하고 하나의 가방에 합류하십시오.

카운트

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

제수 백의 각 요소에 대해 배당 백의 발생 횟수를 계산합니다.
최소 개수는 우리가 만들 수있는 가방의 수입니다.

평등

 {s{Q,}

두 봉지를 정렬하고 같은지 확인하십시오.

분할

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

백에서 각 고유 요소가 몇 번이나 발생하는지 계산합니다.
그것이 제수보다 적어도 여러 번 발생하는 경우. 가방에 (nr_of_copies_total // divisor) 사본을 보관하십시오.

svy†¬yQi¦}} 

소호의 각 요소에 대해 minuend의 앞에 정렬하십시오.
현재가 소급 요소의 첫 번째 요소와 같으면 소급 요소에서 제거합니다.


9

APL (155)

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

주어진 함수에 대한 백 연산을 정의하는 운영자 '백'을 정의합니다. 즉 +∆추가 될 것입니다. 그런 다음 키보드에서 행을 읽고 APL 표현식으로 평가합니다.

기능은 다음과 같습니다.

  • +∆, 추가
  • -∆, 빼기
  • ×∆곱셈
  • ÷∆부서
  • ⊂∆, 계산
  • ≡∆, 동등성 (골프로 인해 인식되지 않은 기능이 동등성을 수행함)

설명:

  • ∆←{... }: 연산자 정의 :

    • O←⍺⍺: 주어진 기능을 저장하십시오 O( 직접 ⎕CR작동하지 않습니다 ⍺⍺)
    • O←⎕CR'O': 해당 함수의 문자열 표현을 가져옵니다.
    • '+'=O... :: 추가
      • ⍺,⍵: 두 목록을 함께 결합
      • R[⍋R←... ]: 결과 정렬
    • '-'=O:: 빼기
      • ⍺{... }⍵: 다음과 같은 재귀 함수를 실행하십시오.
        • ⍵≡⍬:⍺subtrahend가 비어 있으면 minuend를 반환하십시오.
        • ⍺/⍨(⍳⍴⍺)≢⍺⍳⊃⍵∇1↓⍵: 그렇지 않으면, 서브 트라 렌드와 MINUEND에서 서브 트라 렌드의 첫 번째 요소를 제거하고 다시 시도하십시오.
    • (⍬=⍴⍵)∧K←'×'=O: 곱셈과 올바른 주장이 가방이 아닌 경우 :
      • ⍵/⍺: 왼쪽 인수의 각 요소를 오른쪽 인수로 복제
    • K:: ... 그리고 올바른 주장 가방 이라면 :
      • ⍺/⍵: 오른쪽 인수의 각 요소를 왼쪽 인수로 복제합니다 (이는 곱셈이 교환되도록하기위한 것입니다)
    • '÷'=O:: 부서,
      • ⍵≤⍺∘.+⍺: ⍺의 어떤 요소가 ⍵ 번 이상 나타나는지 확인합니다.
      • ⍺/⍨: ⍺에서 항목을 선택하고
      • : 해당 목록에서 모든 중복 항목을 제거하십시오.
    • '⊂'=O:: 계산
      • ⍵{... }⍺: 다음과 같은 재귀 함수를 실행하십시오.
        • (∪⍺)≢∪⍵:0: 한 목록에 다른 목록에 포함 된 요소가 없으면 결과는 0입니다.
        • 1+⍺∇⍵-∆⍺: 그렇지 않으면 제수에서 피제수를 빼고 다시 시도한 후 결과를 증가시킵니다.
    • : 위의 어느 것도 없으면 동등성 테스트를 수행하십시오.
      • ⍺[⍋⍺]≡⍵[⍋⍵]: 두 목록을 정렬하고 동일한 지 확인하십시오.
  • : 키보드에서 표현식을 읽고 평가하여 결과를 출력합니다.

테스트 사례 :

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

정말 전문적인 솔루션과 훌륭한 글쓰기! +1

당신의 글쓰기와 설명은 정말 견고합니다! 그러나 한 가지 : 분할의 경우 사양이 제시 [2,2,2,2,2,2]/3해야하는 방식으로 표현되어 있다고 생각 [2,2]하지만 귀하의 것으로 보입니다 [2].
가치 잉크

REPL을 코딩 할 필요는 없습니다. 방금 정의 하면 사용자가 APL의 기본 REPL로 덤프되며 이제 유효합니다. 뺄셈을 두 줄이 필요한 유일한 것이므로 뺄셈을 끝까지 이동하여 바이트를 절약 할 수 있다고 생각합니다. 대신의 ⎕CR사용 *을 상징 수, 그리고 할 O←⍺⍺2다음 2=O:플러스, 1=O멀티 포트에 대한 0=O:당량에 대한, 7<O:카운트, 그리고 0<O:(묵시적으로의 div 0>O:subtr에 대한).
Adám

6

자바 스크립트 (ES6), 260 바이트

(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 개의 매개 변수를 사용합니다. 첫 번째 매개 변수는 배열이고 두 번째 매개 변수는 연산자이며 세 번째 매개 변수는 연산자에 따라 다릅니다. 음수가 아닌 정수를 보유하려면 백이 필요합니다.

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

언 골프 드 :

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

옥타브 253 244 226 바이트

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

이 기능은 파일에 있어야합니다. 당신이 사용해야합니다 명령 창에서 함수 작성하려면 endfunction또는를 end.

18 바이트를 절약 한 Luis Mendo 에게 감사 합니다.

작업은 다음과 같습니다

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

사용 예 :

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

언 골프 드 :

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

수학, 387 347 300 284 바이트

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]

약간 degolfed (일명 이전 버전), 동등성 테스트 (진실한 값을 반환하지만 일치하지 않는 가방에 대해서는 평가되지 않음)를 완벽하게 지원하지 않았습니다.

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)

head를 사용하여 필요한 데이터 유형을 구현합니다 b.

먼저 b로 정의됩니다 Orderless. head와 함께 커널에 전달 된 모든 객체 b는 인수를 자동 정렬합니다. 따라서 b[3,2,1]입력 하더라도 평가자는 이외의 다른 것을 볼 수 없습니다 b[1,2,3].

추가는 사소한 요소 결합으로 정의됩니다.

두 백의 차이점에 대한 특별한 규칙이 정의되어 있습니다 (아래 설명). 이전 버전에는 form 표현식에 대한 보조 기호가있었습니다 -bag.

그런 다음 ( n양의 정수인 한) 곱셈 은 재귀 적으로 정의되어 n*b[...] = b[...] + (n-1)*b[...]결국 단순한 합으로 줄어 듭니다.

특수 규칙 b[...] - b[...]은 백 합계에서 고유 한 요소 수 를 계산하고 해당 결과에서 백을 빼도록 백을 뺍니다. 더 쉽게 설명 :

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

위의 목록입니다 Keys->Values. KeyValueMapTableKey Value시간의 목록을 만듭니다 . ( Max[...,0]음수 길이 테이블 작성을 시도하지 않아도 됨). 이것은 다음과 같이 나온다 :

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

평평 해지고 머리 List가로 바뀝니다 b.

정수로 나누는 기능은 사용 된 기능이 다소 비슷하며 정수로 요소 수를 나눈 값입니다.

세트 또는 수로 나누기 원래 구현 이후로 변경되었습니다. 이제 다음과 같이 재귀 적으로 수행됩니다. 예를 들어 bag b1b2(골프 코드에서 각각 ca로 분류합니다. if 이면 (b1-b2) + b2 == b11을 더한 다음 나누기 결과에 더 (b1-b2)/b2합니다. 그렇지 않으면 0을 반환하고 재귀를 종료하십시오.

가방이 일치하면 내장형이 ==제공 True됩니다. 마지막 줄은 False그렇지 않은 경우 a를 강제합니다 .

테스트 사례 :

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 자

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}

a덧셈, s뺄셈, m곱셈, d나눗셈, c계산, e평등.

추가 알고리즘은 명백한 것입니다.

전체 인덱스 범위 (배열로 표시), 입력 가방 감산 함수 인덱스, 제 제외한 n각 요소에 평등 의해 형성된 각 등가 클래스의 인덱스 y, n에 해당 대리인의 매수이다 y. 가능한 중복을 처리하면 y함수의 실제 괴물이됩니다.

곱셈 함수는 배열 대신 단일 값인 경우 xy에서 값을 가져 와서 y복제합니다.

나누기 함수는 배열의 개수가보다 큰 값을 생성 y한 다음 중복을 제거합니다.

counting 함수는의 각 요소 개수를 계산 y한 다음 최소값을 반환합니다.

정렬 된 배열 표현이 같으면 두 개의 백이 같습니다.


2

루비, 클래스 정의 답변, 323 291 바이트

Bag루비의 클래스 유연성으로 인해 실제 클래스 를 만들고 싶었습니다 . 이 경우 Array내부 배열을 초기화하고 다른 것들을 처리하는 것보다 짧기 때문에 상속 합니다.

아마도 내일의 작업을 처리하는 기능을 사용하는 더 심각한 골프 답변을 할 것입니다. 나는 매우 피곤하고 숫자 클래스 정의에Number * Bag 얽매여서 제대로 작동 해야했지만 너무 재미 있었습니다. 수업을 위한 강제 기능을 찬양하십시오. 그래서 숫자 클래스 정의를 작성 하지 않아도됩니다

온라인으로 사용해보십시오! (루비에서는 공백이 중요하지 않으므로 코드가 약간 압축 해제되어 있습니다.)

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

루비, 201 바이트

다른 대답에서 약속했듯이 새 클래스를 작성하는 대신 함수를 사용하는 것이 있습니다. 나는 200 바이트 마크를 위반하는 것에 너무 가깝습니다 ... 온라인으로 사용해보십시오

이것은 JavaScript 응답에서 @Neil과 동일한 opcode 및 동일한 순서의 인수 (lhs, opcode, rhs)를 사용합니다.

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

코드:

->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 바이트

(가독성을 위해 줄 바꿈이 추가됨-첫 번째 줄 바꿈 만 필요하고 계산 됨)

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

설명

우리는 (가치, 개수)의지도로 가방을 구현합니다. 기본 조작은 카운트를 조작하여 구현할 수 있습니다. 빼기와 정수 나누기는 또한 카운트가 0에 도달하는 요소를 제거해야하므로 std::map::operator==등식 테스트로 작동합니다.

다음의 확장 코드는 위의 일반적인 버전으로 훨씬 덜 골라집니다. 우리는 s()0 카운트 값을 짜기 위해 별도의 것을 사용 const하고 관용적 C ++ 방식으로 할당 연산자 측면에서 연산을 구현 합니다. 또한 빈 백 s()0반환하여 곱셈을하는 데 사용 합니다 (에 추가 (B{1}*0 != B{})하여 테스트 main()). 원본은이 테스트에 실패하며 요구 사항인지 확실하지 않습니다.

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

테스트

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

좋은 대답입니다! +1. 게시물에 올바른 형식의 코드가 필요합니다.
Yytsi

고의로 코드를 감싸고 싶었으므로 모든 것을 볼 수 있습니다. 대안은 줄 바꿈을 추가하는 것이 었습니다.
Toby Speight

1
줄 바꿈 추가-prettify가 작동하기 때문에 이것이 더 낫다고 생각합니다.
Toby Speight

1

Python 2.7-447B (파일 크기)

이것이 Codegolf에서 처음 시도한 것입니다. 나는 2 시간이 필요했다. (그러나 나는 여전히 파이썬 초보자입니다)

편집 : 다음을 지적 해준 "Kevin Lau-Kenny가 아님":

  • 클래스의 파이썬 자체 인수는 무엇이든 대체 될 수 있습니다.
  • 들여 쓰기는 하나의 공백이어야합니다.
  • 내장 정렬 - funktion (나는 알고 있었다 나는 그것을 보았다,하지만 난 목록의 방법으로 그것을 생각)
  • __ radd __은 필요하지 않습니다 (어쨌든 B 객체 (가방 유형) 추가 만 지원합니다)

편집 : 또한 함수를 람다 및 줄 바꿈으로 바꾸고 들여 쓰기를 더 세미콜론으로 대체하여 공간을 절약했습니다.

암호:

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

체크 무늬:

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

산출:

True
True
True
True
True
True
True
True
True
False

시간을 기준으로 설정하여 다른 시간에 시도 할 수 있습니다. 편집 : 아마도 기능 만 사용해 볼 수도 있습니다.


PPCG에 오신 것을 환영합니다! 파이썬에 대해 알아야 할 것은 실제로 클래스 함수에서 첫 번째 매개 변수를 호출 할 필요가 없다는 것입니다self - 뭔가를 같은 S단지뿐만 아니라 할 것입니다. 또 다른 트릭은 내장 sorted함수가 새 함수 s에서 원하는 것을 정확하게 수행 하므로 함수 정의를 잊을 수 있습니다 (한 번만 사용하는 경우 참조). 당신은 __radd__여전히 필요하지만 가방이 아닌 가방을 추가하지 않기 때문에 절대 필요하지 않습니다 __rmul__. 마지막으로, 4 개가 아닌 1 개의 들여 쓰기 공간 만 있으면 바이트 수가 상당히 줄어 듭니다
Value Ink
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.