Phân rã hoán vị thành chu kỳ


15

Có một định lý nổi tiếng rằng bất kỳ hoán vị nào cũng có thể bị phân hủy thành một tập hợp các chu kỳ . Công việc của bạn là viết chương trình ngắn nhất có thể để làm như vậy.

Đầu vào:

Hai dòng. Số thứ nhất chứa một số N, số thứ hai chứa Ncác số nguyên riêng biệt trong phạm vi được [0,N-1]phân tách bằng dấu cách. Các số nguyên này đại diện cho một hoán vị của Ncác yếu tố.

Đầu ra:

Một dòng cho mỗi chu kỳ trong hoán vị. Mỗi dòng nên là một danh sách các số nguyên được phân tách bằng dấu cách theo thứ tự chu kỳ.

Chu kỳ có thể là đầu ra theo bất kỳ thứ tự nào, và mỗi chu kỳ có thể là đầu ra bắt đầu ở bất kỳ vị trí nào.

Ví dụ 1:

8
2 3 4 5 6 7 0 1

Đầu vào này mã hóa hoán vị 0-> 2, 1-> 3, 2-> 4, 3-> 5, 4-> 6, 5-> 7, 6-> 0, 7-> 1. Điều này phân hủy thành các chu kỳ như thế này:

0 2 4 6
1 3 5 7

Một đầu ra hợp lệ như nhau sẽ là

5 7 1 3
2 4 6 0

Ví dụ 2:

8
0 1 3 4 5 6 7 2

đầu ra hợp lệ:

0
1
4 5 6 7 2 3

@Keith Giá trị tối đa của N là gì?
fR0DDY 17/03/2016

3
3 ký tự trong J:>C.
Eelvex

Giả sử N <1000.
Keith Randall

Hoán vị thường được tính từ 1, không phải 0.
Tiến sĩ belisarius

6
Các nhà toán học đếm từ 1, các nhà khoa học máy tính đếm từ 0 :)
Keith Randall

Câu trả lời:


4

C 145 134 Ký tự

N,A[999],i,j,f;main(){gets(&i);for(;~scanf("%d",A+N);)N++;for(;j<N;j++,f=f&&!puts(""))while(i=A[j]+1)f=printf("%d ",j),A[j]=-1,j=--i;}

http://www.ideone.com/BrWJT


Có hợp pháp để gọi các hàm matrixdic được khai báo ngầm? Là nó hợp pháp để bỏ qua đầu tiên int?
6502

Nó là hợp pháp để làm bất cứ điều gì miễn là mã hoạt động. Mặc dù nó có thể đưa ra cảnh báo, miễn là nó không đưa ra lỗi, thì nó vẫn ổn.
fR0DDY

Điểm chính là trong ý nghĩa của "công trình". Dù sao, tôi đã thêm một câu trả lời (139 ký tự) sử dụng quy tắc này (nghĩa là "công trình" có nghĩa là "có ít nhất một trình biên dịch C tự khai báo, trong đó, rõ ràng, mã máy được tạo hoạt động")
6502

+1: Tôi thích gets(&i)ý tưởng loại bỏ dòng đầu tiên vô dụng đó, tuy nhiên điều này rõ ràng sẽ không hoạt động trên các hệ thống 16 bit nếu có hơn 10 yếu tố được thông qua. Nhưng một lần nữa, nếu các quy tắc là "tìm ít nhất một chương trình tự xưng là trình biên dịch C tạo ra một tệp thực thi trong đó ít nhất một trường hợp dường như - ít nhất là đối với tôi - để đưa ra phản hồi hợp lệ" thì đây là một cải tiến: - )
6502

2

Python chars 131

input();d=dict((i,int(x))for i,x in enumerate(raw_input().split()))
while d:
 x=list(d)[0]
 while x in d:print x,;x=d.pop(x)
 print

dòng mới kết thúc là không cần thiết


1

Haskell, 131 ký tự

n%l|all(>n)l=(n:l>>=(++" ").show)++"\n"|1<3=""
c(_:a)=a>>=(\n->n%(takeWhile(/=n)$iterate(a!!)$a!!n))
main=interact$c.map read.words
  • Chỉnh sửa: (135 -> 131) >=đã trở thành >, loại bỏ hai tailcuộc gọi mặc dù khớp mẫu & ứng dụng trước a!!.

1

C (sắp xếp), 139 ký tự

n,j,t,a[999];main(){scanf("%*i");for(;scanf("%i",a+n)>0;)n++;while(n--)if(a[j=n]+1){for(;t=a[j]+1;a[j]=-1,j=t)printf("%i ",--t);puts("");}}

Dòng mới cuối cùng không được bao gồm.

Tôi đã nói "sắp xếp" vì AFAIK chẳng hạn

  1. Sẽ không hợp pháp khi bỏ qua khai báo cho các hàm matrixd (ANSI C89: 3.3.2.2)
  2. intkhông thể được bỏ qua cho khai báo biến (ví dụ tôi không tìm thấy nó có thể được bỏ qua và khai báo kiểu ẩn chỉ được mô tả cho các hàm. Ví dụ, đặc tả ngữ pháp trong tiêu chuẩn là vô dụng vì chấp nhận nhiều hơn so với khai báo C hợp lệ double double void volatile x;)
  3. một dòng mới ở cuối tệp nguồn không trống là bắt buộc (ANSI C89: A.6.2)

nhưng đoạn mã trên được biên dịch với gcc -ocycles cycles.chình thức rõ ràng vẫn hoạt động.


Đây là một chương trình C hợp lệ, nhưng đây không phải là C99.
Quixotic

@Debanjan: Không, đó không phải là ANSI C (thậm chí không phải 89). Ví dụ, tiêu chuẩn nói (3.3.2.2) rằng nếu một hàm sử dụng một số lượng đối số biến đổi thì nó không thể được khai báo ngầm tại trang gọi hàm (nói cách khác bạn không thể gọi scanfmà không cần #include <stdio.h>ngay cả khi các tham số là chính xác và không yêu cầu chuyển đổi ):<<If the function is defined with a type that includes a prototype, and the types of the arguments after promotion are not compatible with the types of the parameters, or if the prototype ends with an ellipsis ( ", ..." ), the behavior is undefined.>>
6502

1

J (từ 2 đến 32)

Tôi không rõ lắm về định dạng i / o, nhưng tôi nghĩ C.sẽ làm được, nếu đầu ra sau đây được chấp nhận:

   C. 0 1 3 4 5 6 7 2
┌─┬─┬───────────┐
│0│1│7 2 3 4 5 6│
└─┴─┴───────────┘

(Có vẻ tốt hơn trong thiết bị đầu cuối J.)

Nếu nó cần phải là một hàm được đặt tên tuân theo sự hiểu biết tốt nhất của tôi về định dạng i / o, thì đó là 32 ký tự, trong đó 30 ký tự để chuyển đổi định dạng đầu ra ...

g=:>@(":L:0)@(C.@".@}.~>:@i.&LF)

Trong hành động:

   g=:>@(":L:0)@(C.@".@}.~>:@i.&LF)
   g
>@(":L:0)@(C.@".@}.~ >:@i.&(10{a.))
   t
8
0 1 3 4 5 6 7 2
   g t
0          
1          
7 2 3 4 5 6

Giải trình:

J được thực hiện từ phải sang trái (thực tế). @là một 'chức năng' (về mặt kỹ thuật không phải là một chức năng, nhưng đủ gần) để kết hợp các chức năng.

  • i.&LF- tìm chỉ mục đầu tiên của LF, một biến được xác định trước có chứa ký tự ASCII số 10, nguồn cấp dữ liệu.
  • >:- tìm cái đầu tiên LFvà tăng chỉ số của nó lên một. Chúng tôi thực sự không muốn linefeed, chúng tôi muốn mảng theo sau nó.
  • }.~ - Chọn một phần của đầu vào mà chúng ta muốn.
  • ".- Vì định dạng đầu vào là hợp lệ J ( * \ õ / * ), chúng tôi chỉ có thể sử dụng evalđộng từ (tôi biết nó không thực sự được gọi eval.) Để biến nó thành một mảng
  • C.- Ma thuật thuần túy. Tôi thực sự không biết những gì nó làm, nhưng nó dường như làm việc!
  • ":L:0- Đại diện. Biến đầu ra của C.chuỗi thành chuỗi
  • >- Bỏ hộp. Đầu ra thực tế thực sự là một mảng chuỗi (có khoảng trắng phía sau số đầu tiên của số của ví dụ).

0

Clojure, 145

(let[v(vec(repeatedly(read)read))](loop[a(set v)b 0](cond(a(v b))(do(print" "b)(recur(disj a(v b))(v b)))(seq a)(do(prn)(recur a(first a)))1"")))

Hơi vô dụng và được chia thành một hàm (đầu vào phải là một vectơ, đó là những gì (vec (lặp đi lặp lại (đọc) đọc)) từ trên tạo ra):

(defn p [v]
  (loop [a (set v) b 0]
    (cond
     (a (v b)) (do (print" "b) (recur (disj a (v b)) (v b)))
     (seq a) (do (prn) (recur a (first a)))
     1 "")))

(Wow, chỉ cần nhận thấy thử thách này đã hơn 3 tuổi. Ồ tốt, dù sao cũng rất vui khi làm điều đó!)

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.