Xuất ra tất cả các hoán vị riêng biệt của một vectơ


9

Thử thách:

Xuất ra tất cả các hoán vị riêng biệt của một danh sách các số nguyên dương có khả năng dài. Bạn có thể giả sử rằng vectơ có ít hơn 1.000 số khi kiểm tra, nhưng về mặt lý thuyết, quy trình sẽ hoạt động đối với bất kỳ vectơ nào có nhiều hơn một số bất kể kích thước.

Những hạn chế:

  • Bạn phải hạn chế sử dụng bộ nhớ ở O (n ^ 2) , trong đó n là số phần tử trong vectơ đầu vào. Bạn không thể có O (n!) . Điều đó có nghĩa là bạn không thể lưu trữ tất cả các hoán vị trong bộ nhớ.
  • Bạn phải hạn chế độ phức tạp thời gian ở O (kích thước kết quả * n) . Nếu tất cả các số đều bằng nhau, thì đây sẽ là O (n) và nếu tất cả đều khác biệt, thì đây sẽ là O (n! * N) . Điều đó có nghĩa là bạn không thể tạo hoán vị và kiểm tra nó với tất cả các hoán vị khác để đảm bảo tính khác biệt (đó sẽ là O (n! ^ 2 * n) ).
  • Các phép đo thực nghiệm để chỉ ra rằng các giới hạn về thời gian và bộ nhớ được đáp ứng được chấp nhận.
  • Bạn thực sự phải in / xuất các hoán vị (vì không thể lưu trữ chúng).

Nếu bạn chạy chương trình của mình đủ lâu, thì tất cả các hoán vị sẽ được xuất ra (theo lý thuyết)!

Hoán vị riêng biệt:

Danh sách [1, 1, 2] có ba hoán vị, không phải sáu: [1, 1, 2] , [1, 2, 1][2, 1, 1] . Bạn có thể chọn thứ tự của đầu ra.


Các trường hợp kiểm tra quản lý:

Input: 
[1, 2, 1]
Output:
[1, 1, 2]
[1, 2, 1]
[2, 1, 1] 

Input:
[1, 2, 3, 2]
Output:
[1, 2, 2, 3]
[1, 2, 3, 2]
[1, 3, 2, 2]
[2, 1, 2, 3]
[2, 1, 3, 2]
[2, 2, 1, 3]
[2, 2, 3, 1]
[2, 3, 1, 2]
[2, 3, 2, 1]
[3, 1, 2, 2]
[3, 2, 1, 2]
[3, 2, 2, 1]

Input:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
Output:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

Trường hợp thử nghiệm lớn hơn:

Không thể đưa ra tất cả các hoán vị cho cái này, nhưng nó sẽ hoạt động trên lý thuyết nếu bạn cho nó đủ thời gian (nhưng không giới hạn bộ nhớ).

Input:
[1, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900]

Bạn phải giải thích làm thế nào bạn biết rằng tất cả các hoán vị là khác biệt, và cuối cùng tất cả các hoán vị sẽ được in.

Đây là vì vậy mã ngắn nhất tính bằng byte sẽ thắng.


2
Có một triển khai tham chiếu đáp ứng các yêu cầu phức tạp này?
Steven H.

1
Không quá khó để đưa ra một thuật toán đáp ứng các yêu cầu (mặc dù nó có thể không được chơi gôn lắm). Tôi không phải là lập trình viên hay nhà toán học, tôi chẳng là gì ngoài một nhà văn thách thức khiêm tốn. Tôi sẽ để lại những thứ khó khăn cho các bạn / các cô gái :)
Stewie Griffin

6
Tôi nghĩ với các đặc điểm hạn chế, điều này sẽ trở nên tốt hơn vì là mã nhanh nhất, vì golf golf thường được sử dụng thông minh cho các tính năng ngôn ngữ và ngôn ngữ được xây dựng.
Uriel

3
"Không nên quá khó" "điều đó là có thể"
Fatalize 7/11/17

1
Là một chức năng tạo có thể chấp nhận được hay chúng ta phải thêm nồi hơi vào một giải pháp như vậy để in / đầu ra?
Jonathan Allan

Câu trả lời:


6

JavaScript (ES6), 177 169 byte

a=>{s=''+a
do{console.log(a)
k=a.findIndex((e,i)=>a[i-1]>e)
if(~k)t=a[k],a[k]=a[l=a.findIndex(e=>e>t)],a[l]=t,a=a.map((e,i)=>i<k?a[k+~i]:e)
else a.reverse()}while(a!=s)}

Sử dụng thuật toán tạo hoán vị từ vựng tiếp theo nổi tiếng, mà tôi tin rằng có bộ nhớ O (len (mảng)) và thời gian O (len (mảng) * len (đầu ra)). (Lưu ý rằng các phần tử mảng được coi là theo thứ tự ngược lại, do đó, ví dụ như 2, 2, 1, 1sẽ liệt kê 2, 1, 2, 1; 1, 2, 2, 1v.v.


5

Python 3 với sympy , (50?) 81 byte

lambda a:[print(v)for v in sympy.iterables.multiset_permutations(a)]
import sympy

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

50 byte nếu một hàm tạo được chấp nhận:

import sympy
sympy.iterables.multiset_permutations

Việc triển khai là mã nguồn mở và hiện có sẵn trên trung tâm git , tại thời điểm viết hàm là ở dòng 983 .

Tôi nghĩ là có, nhưng hãy cho tôi biết nếu không, hãy hoàn thành các giới hạn tiệm cận.


Python 2, (411?) 439 byte

Một phiên bản được đánh gôn (cũng bỏ qua các trường hợp chúng tôi không bắt buộc phải trình bày) trong Python 2 (vẫn sử dụng tích hợp sẵn itertools.permutations function) có 439 byte hoặc 411 không có bản tóm tắt bổ sung để in thay vì tạo (the for v in h(input()):print v):

from itertools import*
def h(a,z=-1,g=1):
 x=[v for v in[g,[[v,a.count(v)]for v in set(a)]][g==1]if 0<v[1]];S=sum([v[1]for v in x])
 if x==x[:1]:k,v=x[0];yield[k for i in range([[0,z][z<=v],v][z<1])]
 elif all(v<2for k,v in x):
    for p in permutations([v[0]for v in x],[z,None][z<0]):yield list(p)
 else:
    z=[S,z][z>-1];i=0
    for k,v in x:
     x[i][1]-=1
     for j in h([],z-1,x):
        if j:yield[k]+j
     x[i][1]+=1;i+=1
for v in h(input()):print v

(lưu ý: điều này sử dụng gôn Python 2 của tab xen kẽ và khoảng trắng để thụt lề)


Không cần phải viết "tại thời điểm viết hàm nằm ở dòng 983" , bạn có thể liên kết với cam kết mới nhất: github.com/sympy/sympy/blob/ .
orlp

@orlp Không có permalink ở đó phải không?
Erik the Outgolfer

@EriktheOutgolfer Tôi đã liên kết với một cam kết cụ thể, không phải là 'phiên bản mới nhất', vì vậy điều đó có nghĩa là liên kết của tôi sẽ không bị lỗi thời bởi những thay đổi trong tương lai.
orlp

2

C ++ (gcc) , 203 byte

Rõ ràng C ++ có chức năng này như là một hàm dựng sẵn ...

#import<bits/stdc++.h>
using namespace std;main(){vector<int>v;int x;while(cin>>x)v.push_back(x);sort(v.begin(),v.end());do{for(int y:v)cout<<y<<' ';puts("");}while(next_permutation(v.begin(),v.end()));}

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

Mã Ungolfed: liên kết TIO.

Điều này sử dụng O(n)bộ nhớ (được đảm bảo bởi std::vector) và thời gian chạy tối ưu.

Một số tối ưu hóa trong mã:

  • Sử dụng importthay vì include(phần mở rộng không dùng G ++)
  • Sử dụng bits/stdc++.h(tiêu đề được biên dịch trước chứa tất cả các tiêu đề khác) thay vì nhiều tiêu đề cần thiết. Thường thì điều này làm cho thời gian biên dịch chậm hơn.
  • using namespace stdđược biết đến là một ý tưởng tồi .
  • Sử dụng puts("")thay vì cout<<'\n'để viết một dòng mới. Điều này là bình thường đối với chương trình C, nhưng cảm thấy kỳ lạ đối với tôi. Vì vậy, tôi nghĩ rằng điều này nên được đề cập.
  • maingiá trị trả về ( int) có thể được bỏ qua.

Mặt khác (ngoài việc xóa khoảng trắng), nó giống như cách tôi thường lập trình trong C ++.

Một số tối ưu hóa có thể có: (Tôi không biết nếu điều đó được cho phép theo mặc định):

  • Nhập kích thước mảng trước khi nhập các phần tử. Điều này sẽ cho phép mảng kích thước động, tổng thể tiết kiệm 30 byte .
  • Không tách các đầu ra bằng dấu phân cách. Vì vậy, đầu ra sẽ thích 1 1 2 3 1 1 3 2 1 2 1 3 1 2 3 1 1 3 1 2 1 3 2 1 2 1 1 3 2 1 3 1 2 3 1 1 3 1 1 2 3 1 2 1 3 2 1 1cho 1 2 1 3. Điều này cho phép tiết kiệm hơn 9 byte.
  • Mặc dù trong C, nó được phép bỏ qua các tiêu đề, tôi không biết liệu có cách nào ngắn hơn để sử dụng các chức năng đó mà không có #importcác tiêu đề trong C ++ hay tên tiêu đề ngắn hơn.

Có lẽ bạn nên đề cập đến lý do tại sao std::sortkhông làm cho thời gian phức tạp tràn ra
l4m2

Cũng lưu 2 byteusing namespace std;main(){vector<int>v;for(int x;cin>>x;v.push_back(x));sort(v.begin(),v.end());do for(int y:v)cout<<y<<' ';while(puts(""),next_permutation(v.begin(),v.end()));}
l4m2

#import<bits/stdc++.h>@#define Q v.begin(),v.end())@using namespace std;main(){vector<int>v;for(int x;cin>>x;v.push_back(x));sort(Q;do for(int y:v)cout<<y<<' ';while(puts(""),next_permutation(Q);}@ là dòng mới
l4m2


2

JavaScript (Node.js) , 137 128 123 byte

s=>f(x=c=[],s.map(g=i=>g[i]=-~g[i]));f=i=>Object.keys(g).map(i=>g(i,--g[i]||delete g[i],f(x[c++]=i),c--))<1&&console.log(x)

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

s=>
    f(
        x=c=[],
        s.map(g=i=>g[i]=-~g[i]) // O(n) if all same, <=O(n^2) if different
    )
;
f=i=>
    Object.keys(g).map( // for(i in g) breaks when other items get removed
        i=>g(
            i,
            --g[i]||delete g[i], // O(left possible numbers)<O(child situations)
            f(x[c++]=i),
            c--
        )
    )<1
&&
    console.log(x)

0

APL (NARS), 156 ký tự, 312 byte

r←d F w;i;k;a;m;j;v
r←w⋄→0×⍳1≥k←↑⍴w⋄a←⍳k⋄j←i←1⋄r←⍬⋄→C
A: m←i⊃w⋄→B×⍳(i≠1)∧j=m
   v←m,¨(d,m)∇w[a∼i]
   →H×⍳0=↑⍴v⋄⎕←∊d,v
H: j←m
B: i+←1
C: →A×⍳i≤k

G←{⍬F⍵[⍋⍵]}

Chúng, F và G sẽ là 2 hàm để sử dụng togheter ... G trước tiên sắp xếp thứ tự mảng hơn là áp dụng cho mảng được sắp xếp đó là hàm F và viết hoán vị bằng cách sử dụng quan sát rằng nếu phần tử đã được tìm thấy, tốt nhất không nên đi đệ quy (bởi vì tất cả các kết quả sẽ được tìm thấy). Tôi không biết điều này có phù hợp với tất cả các lần phục hồi không ... Kiểm tra:

  G 1 1 2
1 1 2 
1 2 1 
2 1 1 

  G 1 2 3 2
1 2 2 3 
1 2 3 2 
1 3 2 2 
2 1 2 3 
2 1 3 2 
2 2 1 3 
2 2 3 1 
2 3 1 2 
2 3 2 1 
3 1 2 2 
3 2 1 2 
3 2 2 1 

  G 'abb'
abb
bab
bba
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.