순열의 패리티


14

배경

순열의 패리티 , 위키에 의해 정의 된 다음이다 :

순열 σ의 부호 또는 부호는 sgn (σ)로 표시되며 σ가 짝수이면 +1로, σ가 홀수이면 -1로 정의됩니다.

순열의 부호는 다음과 같이 명시 적으로 표현할 수 있습니다.

sgn (σ) = (−1) ^ N (σ)

여기서 N (σ)는 σ의 반전 수입니다.

대안 적으로, 순열 σ의 부호는 그것의 분해로부터 전이의 곱으로 정의 될 수있다.

sgn (σ) = (−1) ^ m

여기서 m은 분해에서 전치의 수입니다.

수학에서 그리스 알파벳 수프를 좋아하지 않는 사람들을 위해, 나는 예제 (wikipedia에서 도난당한)로 정의를 약간 단순화하고 시도 할 것입니다.

입력 배열 {1, 2, 3, 4, 5}과 그것의 순열을 생각해 봅시다 {3, 4, 5, 2, 1}. 그 순열 원래 배열에서 취득하기 위하여는, 당신은 인덱스를 교환해야 0하고 2, 1그리고 3, 다음 24. 이것이 고유 한 솔루션은 아니지만 패리티가 잘 정의되어 있으므로 모든 경우에 적용됩니다.

3 개의 스왑이 필요하므로이 순열에 odd패리티 레이블을 붙입니다 . 예상 한대로 짝수의 스왑이 필요한 순열에는 even패리티 가 있다고합니다 .

도전

당신의 도전은 순열의 패리티를 결정하기 위해 가능한 한 적은 바이트로 프로그램을 작성하는 것입니다. 프로그램 또는 기능은 다음과 같아야합니다.

  • 순열 전후의 집합을 나타내는 두 개의 입력 배열 (또는 문자열)을 인수로 받아들입니다.
  • 순열이 주어지면 짝수 e또는 o홀수로 문자 를 반환하거나 인쇄하십시오 .
  • 배열 또는 문자열의 모든 인덱스에 고유 한 값이 있다고 가정해야합니다.

테스트 사례

다음과 같은 함수를 선언했다고 가정합니다 f.

f([10], [10]) == "e"
f([10, 30, 20], [30, 20, 10]) == "e"
f([10, 30, 20, 40], [30, 20, 40, 10]) == "o"

이것은 바이트 단위의 가장 짧은 프로그램 인 !


4
사람들은 엄격한 출력 형식을 좋아하지 않습니다. 짝수에 대한 진실과 홀수에 대한 거짓은 어떻습니까? (또는 다른 방법으로)
CalculatorFeline

실제로 다른 사람이 실제로 방해하지 않는 한 지정한 출력 형식을 유지하기를 바랐습니다. 수정 보류, 타협하겠습니다.
Patrick Roberts

@CatsAreFluffy가 더 낫습니까?
Patrick Roberts

글쎄, 우리가 볼 것 같아요!
CalculatorFeline

안녕히 주무세요! 여기에 다시 올 때의 제안 사항이 있습니다 (그러나 직접 확인하십시오) : [10], [10] -> e(조옮김 없음). [10 30 20], [30 20 10] -> e(2 개의 전치). [10 30 20 40], [30 20 40 10] -> o(3 개의 조옮김)
Luis Mendo

답변:


5

젤리, 13 12 바이트

żṗ2</€⁺Sị“oe

온라인으로 사용해보십시오!

작동 원리

żṗ2</€⁺Sị“oe  Main link. Arguments: A, B (lists)

ż             Zip A with B. Yields an array of pairs [x, σ(x)].
 ṗ2           Generate all pairs [[x, σ(x)], [y, σ(y)]].
   </€        Reduce each pair by </€.
              This maps [[x, σ(x)], [y, σ(y)]] to [x < y, σ(x) < σ(y)].
      ⁺       Repeat the previous link, i.e., execute </€ once more.
              This maps [x < y, σ(x) < σ(y)] to ((x < y) < (σ(x) < σ(y))), which is
              true if and only if x > y and σ(x) < σ(y).
       S      Sum. This counts the number of inversions.
        ị“oe  Retrieve the letter at the corresponding index.
              Indexing is 1-based and modular, so an odd sum retrieves the first
              letter, an even sum the second.

1
그것은 매우 작습니다. 명성!
Patrick Roberts

6

MATL , 17 16 바이트

Dennis의 제안으로 1 바이트가 제거되었습니다.

2$St!<Rz2\'oe'w)

이 언어의 현재 버전 (15.0.0) 에서 작동 합니다.

온라인으로 사용해보십시오 !

설명

이것은 역의 관점에서 패리티의 정의를 사용합니다. 반전은 첫 번째 배열과 비교하여 "잘못된"순서로있는 두 번째 배열의 요소 쌍입니다. 첫 번째 배열은 정렬 할 필요가 없으므로 먼저 정렬하고 해당 정렬에 필요한 동일한 재 배열이 두 번째 배열에 적용됩니다. 그런 다음 반전은 두 번째 배열에서 증가하지 않는 한 쌍의 요소에 해당합니다.

또한 두 입력 배열을 교체 할 수 있으며 결과는 동일합니다. 따라서 어떤 배열이 "원본"배열로 간주되고 "순환 된"배열인지는 중요하지 않습니다.

2$S     % implicitly take two row vectors. Sort second and apply the indices
        % of that sorting to the first
t!      % duplicate. Transpose into column vector
<       % true for elements of the column vector that exceed those of the 
        % row vector. Gives a 2D array with all pairs of comparisons
R       % keep only upper triangular part of that array
z       % number of nonzero elements. This is the number of inversions
2\      % parity of that number: gives 0 or 1
'oe'w   % push string 'eo' below the top of the stack
)       % apply index to produce 'e' or 'o'. An index 1 refers to the first
        % element, whereas 0 refers to the last. Implicitly display 

1
이것은 정말 영리한 솔루션입니다!
Alex A.

@AlexA. 감사! 사전 주문 부분의 기능을 명확히하기 위해 답을 편집했습니다. 하나의 배열을 정렬 한 다음 해당 정렬에 필요한 동일한 재 배열이 다른 배열에 적용됩니다.
Luis Mendo

1
MATL에 모듈 식 인덱싱을 추가해야합니다. 여기에 3 바이트가 절약됩니다.
Dennis

@Dennis 예, 나는 종종 그것에 대해 생각했습니다 ...하지만 현재 음수 값이 다른 형식을 사용하는 형식을 사용합니다. x(1:end-2)의 크기를 명시 적으로 표시하지 않고 양식 등의 색인을 갖기 위해 선택했습니다 x. 좋은 선택인지 확실하지 않지만 지금 변경하기에는 너무 늦었다 고 생각합니다 :-) 어쩌면 모듈 형 색인을 추가하는 호환 가능한 방법을 찾을 수 있습니다
Luis Mendo

... 현재 길이를 초과하는 인덱스를 사용하여 새 값을 할당합니다. 그러나 인덱스 0에는 "마지막 항목"의 의미가 있으므로 바이트를 절약 할 수 있습니다 (증분 제거). 아이디어 주셔서 감사합니다!
Luis Mendo

5

옥타브, 56 52 바이트

지금까지 아무도이 접근법을 사용하지 않는 것 같습니다. 기본적으로 나는 해당 순열 행렬의 결정자를 사용하고 있습니다. 이 식은 det(eye(nnz(a))(a,:))vector로 정의 된 순열 행렬의 행렬식을 반환합니다 a. 그런 다음 결과에 따라 문자열에서 올바른 문자를 추출하면됩니다.

p=@(v)eye(nnz(v))(v,:);@(a,b)'ole'(det(p(a)*p(b))+2)

2
결정자를 사용하는 것이 좋습니다. 올레!
Luis Mendo

5

하스켈, 58 바이트

k%l|m<-zip k l=cycle"eo"!!sum[1|(a,b)<-m,(c,d)<-m,a<c,b>d]

용법:

*Main> [8,3,5]%[5,3,8]
'o'

내 파이썬 답변 과 같은 방법 입니다. 자랑스러운 haskeller는로 바이트를 절약했습니다 cycle.


1
cycle"eo"!!...대신 "eo"!!mod(...)21 바이트를 절약 하면서 쓸 수 있습니다 .
자랑스런 Haskeller

4

파이썬 2, 68 바이트

lambda*M:"eo"[sum(a<b<M>A>B for a,A in zip(*M)for b,B in zip(*M))%2]

용법:

>>> f=lambda*M:"eo"[sum(a<b<M>A>B for a,A in zip(*M)for b,B in zip(*M))%2]
>>> f([8,3,5],[5,3,8])
'o'

두 압축 목록의 반전 쌍 수를 계산합니다. 값 (a,A)(b,B)각각의리스트에서와 같은 인덱스에서 a<bA>B. 이러한 비교는 a<b<M>A>B목록 M이 임의의 수보다 큰 속성을 사용하여 로 조합됩니다 . 그런 다음 합은 모듈로 2를 취하여 e또는 로 바뀝니다 o.


3

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

(a,b)=>"eo"[r=0,g=a=>a.map((e,i)=>a.slice(i).map(d=>r^=d<e)),g(a),g(b),r]

우리는 패리티에만 관심이 있기 때문에 중복 조옮김은 단순히 취소됩니다. 편리하게 JavaScript의 배열 첨자는 다차원 적이 지 않습니다.


1
쉼표에 대한 재미있는 곳. -1 바이트를 카레하는 것을 잊지 마십시오
Patrick Roberts

2

Mathematica, 77 바이트

If[Mod[Plus@@Length/@(Join[{0},#]&)/@PermutationCycles[#][[1]],2]==0,"e","o"]&

나는 동의한다!


편리한 기능, 불행히도 긴 이름!
Patrick Roberts

성 가시지? 나는 싫어 Cycles. 그것은 PermutationCycles이름 의 크기를 높이고 심지어 PermutationCycles어리석은 Cycles물건을 반환 합니다! `
CalculatorFeline

2

Mathematica, 31 바이트

If[Tr[Signature/@{##}]==0,o,e]&

서명 [목록]은 목록의 요소를 정식 순서로 배치하는 데 필요한 순열의 서명을 제공합니다.

우선 하나의 목록을 임의의 순서 (이 경우 정식 순서)로 재정렬하고이 목록을 최종 목록으로 재정렬하여 하나의 목록을 다른 목록으로 재정렬 할 수 있습니다. 두 순열의 부호가 같으면 전체 순열의 부호는 짝수입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.