Xây dựng một Permuter


9

Đối với thử thách này, bạn sẽ tạo một hàm (hàm của bạn có thể là một chương trình hoàn chỉnh) lấy một danh sách làm đầu vào và trả về một hoán vị của danh sách đó. Chức năng của bạn phải tuân theo các yêu cầu sau.

  • Nó phải mang tính quyết định.

  • Kết hợp chức năng của bạn với số lần thay đổi sẽ có khả năng nhận được danh sách cho bất kỳ hoán vị nào của nó.

Đây là một câu hỏi golf-code vì vậy câu trả lời sẽ được tính bằng byte, với ít byte hơn sẽ tốt hơn.

Quy tắc khác

  • Bạn có thể dùng bất cứ loại danh sách, ( [Integer], [String], [[Integer]]) miễn là nó

    • Có thể không trống
    • Có thể chứa các đối tượng riêng biệt với ít nhất 16 giá trị có thể. (Bạn không thể sử dụng Haskell [()]và khẳng định chức năng của mình là id)
    • Có thể chứa các đối tượng trùng lặp (không có bộ)
  • Bạn có thể viết một chương trình hoặc một chức năng, nhưng phải tuân theo IO tiêu chuẩn.


Nhưng S_nchỉ là chu kỳ chon<3
Leaky Nun

@LeakyNun, nó không yêu cầu một hoán vị duy nhất tạo ra nhóm đối xứng: nó yêu cầu một next_permutationhàm.
Peter Taylor

Nó có đủ để chỉ hoán vị danh sách của 0 và 1 không?
xnor

Tôi không chắc là tôi hiểu điểm hạn chế này. Nếu bạn cho phép danh sách Booleans, thì điểm nào không cho phép lặp trên bất kỳ hai mục riêng biệt nào?
Dennis

@Dennis Bạn làm cho một điểm tốt. Tôi sẽ không cho phép danh sách booleans. Hoặc các loại có ít hơn 16 giá trị có thể.
Ad Hoc Garf Hunter

Câu trả lời:


4

CJam (11 byte)

{_e!_@a#(=}

Bản demo trực tuyến hiển thị chu trình đầy đủ cho danh sách bốn yếu tố với một yếu tố trùng lặp.

Mổ xẻ

{      e# Define a block
  _e!  e#   Find all permutations of the input. Note that if there are duplicate
       e#   elements in the input then only distinct permutations are produced.
       e#   Note also that the permutations are always generated in lexicographic
       e#   order, so the order is independent of the input.
  _@a# e#   Find the index of the input in the list
  (=   e#   Decrement and get the corresponding element of the list
       e#   Incrementing would also have worked, but indexing by -1 feels less
       e#   wrong than indexing by the length, and makes this more portable to
       e#   GolfScript if it ever adds a "permutations" built-in
}

2

Mathematica + Combinatorica (Gói tích hợp) 34 Byte

19 byte để tải gói và 15 cho hàm.

<<"Combinatorica`";NextPermutation

Sử dụng:

%@{c, b, a}

Không có tích hợp, 61 Byte

Extract[s=Permutations[Sort@#],Mod[s~Position~#+1,Length@s]]&

Combinatorica được cho là sẽ được tích hợp hoàn toàn vào Mathicala, nhưng tôi nghĩ rằng chức năng NextPermuting đã bị bỏ qua.



2

C ++, 42 byte

#include <algorithm>
std::next_permutation

Hoạt động chính xác này là một nội dung trong C ++.


2
Tại sao không gian sau #include?
Yytsi

2

JavaScript (ES6), 145 139 137 134 108 byte

Đã tiết kiệm được 25 byte nhờ @Neil!

Đưa đầu vào như một mảng các ký tự chữ cái. Trả về hoán vị tiếp theo như một mảng khác.

a=>(t=x=y=-1,a.map((v,i)=>v<a[i+1]?(t=v,x=i):y=i>x&v>t?i:y),a[x]=a[y],a[y]=t,a.concat(a.splice(x+1).sort()))

Làm sao?

Đây là một thế hệ theo thứ tự từ điển xử lý 4 bước sau ở mỗi lần lặp:

  1. Tìm chỉ số X lớn nhất sao cho [X] <a [X + 1]

    a.map((v, i) => v < a[i + 1] ? (t = v, x = i) : ...)
  2. Tìm chỉ số lớn nhất Y lớn hơn X sao cho [Y]> a [X]

    a.map((v, i) => v < a[i + 1] ? ... : y = i > x & v > t ? i : y)
  3. Hoán đổi giá trị của [X] với giá trị của [Y]

    a[x] = a[y], a[y] = t
  4. Sắp xếp chuỗi từ [X + 1] đến và bao gồm phần tử cuối cùng, theo thứ tự từ điển tăng dần

    a.concat(a.splice(x + 1).sort())

Thí dụ:

các bước

Bản giới thiệu


Bạn không thể sắp xếp chứ không phải đảo ngược? Ngoài ra tôi nghĩ v<a[i+1]&&(t=v,x=i)tiết kiệm một byte và bạn có thể tiết kiệm nhiều hơn bằng cách sử dụng splicethay vì hai slicegiây.
Neil

@Neil Bắt tốt!
Arnauld

Tôi nghĩ rằng tôi cũng có thể hợp nhất hai maps, với 112 byte:a=>(t=x=y=-1,a.map((v,i)=>v<a[i+1]?(t=v,x=i):y=i>x&v>t?i:y),a[x]=a[y],a[y]=t,t=a.splice(++x).sort(),a.concat(t))
Neil

Tôi phải thừa nhận rằng tôi đã không nghĩ rằng a.concat(a.splice(++x).sort())sẽ đi làm nếu không tôi đã thử nó ...
Neil

@Neil Cảm ơn! Cập nhật. (Với 4 byte được lưu thêm vì chúng tôi thực sự không cần t để concat () ).
Arnauld

1

Thạch , 6 byte

Œ¿’œ?Ṣ

Chu kỳ thông qua các hoán vị theo thứ tự từ điển giảm dần.

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

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

Œ¿’œ?Ṣ  Main link. Argument: A (array)

Œ¿      Compute the permutation index n of A, i.e., the index of A in the
        lexicographically sorted list of permutations of A.
  ’     Decrement the index by 1, yielding n-1.
     Ṣ  Sort A.
   œ?   Getthe (n-1)-th permutation of sorted A.

1

C, 161 byte

Thuật toán O (n) thực tế.

#define S(x,y){t=x;x=y;y=t;}
P(a,n,i,j,t)int*a;{for(i=n;--i&&a[i-1]>a[i];);for(j=n;i&&a[--j]<=a[i-1];);if(i)S(a[i-1],a[j])for(j=0;j++<n-i>>1;)S(a[i+j-1],a[n-j])}

Ví dụ sử dụng:

int main(int argc, char** argv) {
    int i;
    int a[] = {1, 2, 3, 4};

    for (i = 0; i < 25; ++i) {
        printf("%d %d %d %d\n", a[0], a[1], a[2], a[3]);
        P(a, 4);
    }

    return 0;
}

1

Python 2 , 154 byte

x=input()
try:exec'%s=max(k for k in range(%s,len(x))if x[%s-1]<x[k]);'*2%tuple('i1kjii');x[i-1],x[j]=x[j],x[i-1];x[i:]=x[:i-1:-1]
except:x.sort()
print x

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


Tôi nghĩ rằng nó ngắn hơn như là một chức năng cho phép danh sách tại chỗ.
orlp

Tôi đã thử điều đó, nhưng execđã cho tôi tất cả các loại lỗi trong một chức năng
Dennis

0

Thạch , 10 byte

ṢŒ!Q©i⁸‘ị®

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

Sắp xếp> tất cả hoán vị> tìm đầu vào> thêm 1> chỉ mục vào "tất cả hoán vị


@PeterTaylor Tôi đã sửa nó.
Rò rỉ Nun

Có các nội dung cụ thể cho hoán vị (tức là bạn chỉ có thể làm Œ¿‘œ?Ṣ). Tôi đã không cảm thấy như ăn cắp kể từ, tốt, cùng một thuật toán.
Erik the Outgolfer 14/07/17

@EriktheOutgolfer có thể hơi lộn xộn cho các đầu vào có chứa các bản sao.
Rò rỉ Nun

Hmm ... tôi đoán vậy, tôi đã có một phiên bản hoạt động cho điều đó trước đây nhưng bạn dường như sử dụng điều đó Q. Bạn vẫn có thể chơi gôn ṢŒ!Qµi³‘ị.
Erik the Outgolfer


0

PHP , 117 byte

Lấy đầu vào / đầu ra dưới dạng danh sách chuỗi các chữ cái thấp hơn

$a=str_split($s=$argn);rsort($a);if(join($a)!=$s)for($n=$s;($c=count_chars)(++$n)!=$c($s););else$n=strrev($s);echo$n;

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

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.