Tính chẵn lẻ


14

Lý lịch

Tính chẵn lẻ của một hoán vị , như được định nghĩa bởi wikipedia , như sau:

Dấu hoặc chữ ký của hoán vị được ký hiệu là sgn (σ) và được định nghĩa là +1 nếu σ chẵn và −1 nếu là số lẻ.

Dấu hiệu của một hoán vị có thể được thể hiện rõ ràng như

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

Trong đó N (σ) là số lượng nghịch đảo trong.

Ngoài ra, dấu hiệu của hoán vị có thể được định nghĩa từ sự phân rã của nó thành sản phẩm của các chuyển vị như

sgn (σ) = (1) ^ m

Trong đó m là số lần chuyển vị trong phân rã.

Đối với những người không thích món súp bảng chữ cái Hy Lạp trong toán học của họ, tôi sẽ thử và đơn giản hóa định nghĩa một chút bằng một ví dụ (cũng bị đánh cắp từ wikipedia).

Thí dụ

Hãy xem xét mảng đầu vào {1, 2, 3, 4, 5}và một hoán vị của nó, giả sử , {3, 4, 5, 2, 1}. Để có được từ mảng ban đầu đến hoán vị của nó, bạn phải trao đổi các chỉ số 02, 13, sau đó 24. Mặc dù đây không phải là một giải pháp duy nhất, tính chẵn lẻ được xác định rõ ràng nên điều này hoạt động cho tất cả các trường hợp.

Vì nó yêu cầu 3 lần hoán đổi, chúng tôi dán nhãn hoán vị này với một oddchẵn lẻ. Như bạn có thể mong đợi, một hoán vị đòi hỏi một lượng giao dịch hoán đổi đồng đều được cho là có eventính chẵn lẻ.

Thử thách

Thách thức của bạn là viết một chương trình càng ít byte càng tốt để xác định tính chẵn lẻ của một hoán vị. Chương trình hoặc chức năng của bạn phải:

  • Chấp nhận làm đối số, hai mảng đầu vào (hoặc chuỗi) đại diện cho một tập hợp trước và sau khi hoán vị.
  • Trả lại hoặc in ký tự echo chẵn hoặc olẻ, cho phép hoán vị.
  • Nên giả sử rằng tất cả các chỉ số trong mảng hoặc chuỗi có giá trị duy nhất.

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

Giả sử bạn đã khai báo một hàm có tên f:

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

Đây là , chương trình ngắn nhất trong byte thắng!


4
Mọi người sẽ không thích định dạng đầu ra nghiêm ngặt. Làm thế nào về sự thật cho chẵn và giả cho lẻ? (hoặc ngược lại)
Máy

Tôi đã thực sự hy vọng giữ lại định dạng đầu ra mà tôi đã chỉ định trừ khi có ai đó thực sự bị làm phiền bởi nó. Chỉnh sửa giữ, tôi sẽ thỏa hiệp.
Patrick Roberts

@CatsAreFluffy có tốt hơn không?
Patrick Roberts

Chà, tôi đoán chúng ta sẽ thấy!
Máy

Chúc ngủ ngon! Dưới đây là một số gợi ý khi bạn quay lại vấn đề này (nhưng vui lòng tự kiểm tra): [10], [10] -> e(không chuyển vị). [10 30 20], [30 20 10] -> e(hai lần chuyển vị). [10 30 20 40], [30 20 40 10] -> o(ba lần chuyển vị)
Luis Mendo

Câu trả lời:


5

Thạch, 13 12 byte

żṗ2</€⁺Sị“oe

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

żṗ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
Đó là nhỏ ấn tượng. Thanh danh!
Patrick Roberts

6

MATL , 17 16 byte

Xóa 1 byte nhờ một gợi ý của Dennis

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

Điều này hoạt động trong phiên bản hiện tại (15.0.0) của ngôn ngữ.

Hãy thử trực tuyến !

Giải trình

Điều này sử dụng định nghĩa tương đương về mặt đảo ngược. Đảo ngược là một cặp phần tử trong mảng thứ hai theo thứ tự "sai" so với mảng thứ nhất. Vì mảng đầu tiên không cần được sắp xếp, trước tiên chúng tôi sắp xếp nó và sắp xếp lại tương tự cần thiết cho việc sắp xếp đó được áp dụng cho mảng thứ hai. Sau đó, một nghịch đảo tương ứng với một cặp phần tử không tăng trong mảng thứ hai.

Cũng lưu ý rằng hai mảng đầu vào có thể được hoán đổi và kết quả là như nhau. Vì vậy, không quan trọng mảng nào được coi là "bản gốc" và "mảng" nào.

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
Đây là một giải pháp thực sự thông minh!
Alex A.

@AlexA. Cảm ơn! Tôi đã chỉnh sửa câu trả lời để làm rõ phần đặt hàng trước làm gì: chúng tôi sắp xếp một mảng và sau đó sắp xếp lại tương tự cần thiết cho việc sắp xếp đó được áp dụng cho mảng khác.
Luis Mendo

1
Bạn nên thêm lập chỉ mục mô-đun vào MATL. Điều đó sẽ tiết kiệm 3 byte ở đây.
Dennis

@Dennis Có, tôi thường nghĩ về điều đó ... nhưng hiện tại nó sử dụng định dạng trong đó các giá trị âm có ý nghĩa khác. Tôi đã chọn rằng để có các chỉ mục của biểu mẫu, x(1:end-2)vv mà không chỉ rõ ràng kích thước của x. Không chắc đó có phải là một lựa chọn tốt hay không, nhưng tôi đoán bây giờ đã quá muộn để thay đổi :-) Có lẽ tôi sẽ tìm một cách tương thích để thêm lập chỉ mục mô-đun
Luis Mendo

... và các chỉ số vượt quá độ dài hiện tại được sử dụng để gán giá trị mới. Nhưng chỉ mục 0có nghĩa là "mục nhập cuối cùng", vì vậy tôi có thể lưu một byte (loại bỏ gia số). Cảm ơn ý kiến!
Luis Mendo

5

Octave, 56 52 byte

Dường như không ai đang sử dụng phương pháp này cho đến nay: Về cơ bản, tôi chỉ sử dụng các yếu tố quyết định của ma trận hoán vị tương ứng. Biểu thức det(eye(nnz(a))(a,:))trả về định thức của ma trận hoán vị được xác định bởi vectơ a. Sau đó, nó chỉ là một vấn đề trích xuất đúng ký tự từ chuỗi, tùy thuộc vào kết quả.

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

2
Ý tưởng tốt để sử dụng các yếu tố quyết định. Ôi!
Luis Mendo

5

Haskell, 58 byte

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

Sử dụng:

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

Phương pháp tương tự như câu trả lời Python của tôi . haskeller tự hào đã lưu một byte với cycle.


1
Bạn có thể viết cycle"eo"!!...Thay vì "eo"!!mod(...)2, lưu một byte.
tự hào 20/03/2016

4

Python 2, 68 byte

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

Sử dụng:

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

Đếm số lượng cặp đảo ngược của hai danh sách được nén, i, e. các giá trị (a,A)(b,B)từ mỗi danh sách tại cùng một chỉ mục với a<bA>B. Các so sánh này được kết hợp như a<b<M>A>B, sử dụng thuộc tính mà danh sách Mlớn hơn bất kỳ số nào. Tổng sau đó được lấy modulo 2 và biến thành ehoặc o.


3

JavaScript (ES6), 73 byte

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

Vì chúng tôi chỉ quan tâm đến tính chẵn lẻ, bất kỳ chuyển vị trùng lặp nào chỉ cần hủy bỏ. Đăng ký mảng của JavaScript thuận tiện không phải là đa chiều.


1
Nơi thú vị cho một dấu phẩy .. không biết bạn có thể làm điều đó. Đừng quên việc cà ri cho -1 byte
Patrick Roberts

2

Toán học, 77 byte

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

Tôi đồng ý!


Chức năng tiện dụng, tiếc tên dài!
Patrick Roberts

Khó chịu, phải không? Tôi ghét Cycles. Nó tăng kích thước của PermutationCyclestên, và thậm chí PermutationCycleslà ngu ngốc, trả lại một Cyclesđối tượng! `
Máy

2

Toán học, 31 byte

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

Chữ ký [danh sách] cung cấp chữ ký của hoán vị cần thiết để đặt các yếu tố của danh sách theo thứ tự chính tắc

Chúng ta có thể sắp xếp lại một danh sách này sang danh sách khác, bằng cách sắp xếp lại một danh sách theo bất kỳ thứ tự nào (trong trường hợp này là thứ tự chính tắc) và sắp xếp lại danh sách này vào danh sách cuối cùng. Dấu hiệu của hoán vị tổng thể là chẵn, nếu các dấu của hai hoán vị phụ là bằng nhau.

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.