Swap tunggal array

19

Terinspirasi oleh Diambil dari pertanyaan di Stack Overflow .

Tantangan

Diberikan bilangan bulat n>1, output semua array yang dapat diperoleh dengan menukar tepat dua entri dalam array [1, 2, ..., n].

Array dapat diproduksi dalam urutan apa pun.

Anda dapat secara konsisten menggunakan [0, 1, ..., n-1](berbasis-0) alih-alih [1, 2, ..., n](berbasis-1).

Aturan tambahan

Uji kasus

Input 2menghasilkan output (diasumsikan berbasis 1)

2 1

Input 3menghasilkan output (perhatikan bahwa ketiga array bisa dalam urutan apa pun)

1 3 2
2 1 3
3 2 1

Input 4memberi output

1 2 4 3
1 3 2 4
1 4 3 2
2 1 3 4
3 2 1 4
4 2 3 1

Input 7memberi output

1 2 3 4 5 7 6
1 2 3 4 6 5 7
1 2 3 4 7 6 5
1 2 3 5 4 6 7
1 2 3 6 5 4 7
1 2 3 7 5 6 4
1 2 4 3 5 6 7
1 2 5 4 3 6 7
1 2 6 4 5 3 7
1 2 7 4 5 6 3
1 3 2 4 5 6 7
1 4 3 2 5 6 7
1 5 3 4 2 6 7
1 6 3 4 5 2 7
1 7 3 4 5 6 2
2 1 3 4 5 6 7
3 2 1 4 5 6 7
4 2 3 1 5 6 7
5 2 3 4 1 6 7
6 2 3 4 5 1 7
7 2 3 4 5 6 1
Luis Mendo
sumber
Entri pada indeks yang diberikan oleh oeis.org/A211369 ditambah satu (atau dua jika 0-indeks) dalam daftar diurutkan secara leksikografis dari semua permutasi panjang n.
Jonathan Allan
5
Saya menghargai fleksibilitas [0 ... n-1]vs [1 ... n]! Saya selalu merasa sedikit kesal ketika saya harus memperbaiki 1+karena indeks nol.
cole

Jawaban:

3

Jelly , 11 8 byte

ŒcżU$y€R

Cobalah online!

Bagaimana itu bekerja

ŒcżU$y€R  Main link. Argument: n

Œc        Take all 2-combinations of [1, ..., n].
  żU$     Zip the result with the reversed pairs.
       R  Range; yield [1, ..., n].
     y€   For each [[i, j], [j, i]] in the result to the left, yield the result to
          the right, with i replaced by j and vice versa. 
Dennis
sumber
Apa yang sebenarnya ydilakukan? Itu selalu menjadi sedikit misteri bagi saya.
caird coinheringaahing
Ia melakukan penggantian. Misalnya, [1,2],[4,3]y1,2,3ganti masing-masing 1 in [1, 2, 3] dengan 4 , dan masing-masing 2 dengan 3 .
Dennis
8

R , 54 byte

function(n)combn(n,2,function(x){z=1:n
z[x]=rev(x)
z})

Cobalah online!

Mengembalikan matriks di mana setiap kolom adalah permutasi.

combn(n,k)menghasilkan semua kombinasi ukuran kdari daftar n, atau dari 1:njika nbilangan bulat tunggal. Secara opsional juga dibutuhkan fungsi FUNuntuk diterapkan pada kombinasi yang dihasilkan. Jadi kami menulis fungsi yang melakukan swap dan mengembalikan daftar yang ditukar. Hasilnya kemudian semua diakumulasikan menjadi array, yang dalam hal ini 2-dimensi dan karenanya sebuah matriks.

Giuseppe
sumber
6

Haskell , 62 byte

f n=[[1..x-1]++y:[x+1..y-1]++x:[y+1..n]|x<-[1..n],y<-[x+1..n]]

Cobalah online!

Saya hanya menghasilkan permutasi, mengingat xdan yuntuk swap, masing-masingx,y

H.Piz
sumber
5

Bahasa Wolfram (Mathematica) , 43 byte

r/.{#->#2,#2->#}&@@@Subsets[r=Range@#,{2}]&

Cobalah online!

Penjelasan: Subsets[Range@#,{2}]menghasilkan semua himpunan bagian {1,2,...,n}ukuran 2, kemudian untuk setiap himpunan bagian, /.menukar dua hal dalam daftar {1,2,...,n}.

Pendekatan itu sangat mirip dengan banyak kiriman lainnya, tapi inilah yang lebih unik dari Mathematica, untuk 3 byte tambahan:

r~Permute~Cycles@{#}&/@Subsets[r=Range@#,{2}]&

Cobalah online!

Bukan pohon
sumber
2
Solusi Mathematica yang bahkan lebih idiomatis adalah ReplaceList[Range@#,{a___,b_,c___,d_,e___}:>{a,d,c,b,e}]&. Saya suka betapa sederhananya (atau bagaimana langsung mengkodekan masalah), tetapi sayangnya sintaks pencocokan pola sangat verbose bahwa ini akhirnya menjadi 57 byte.
Martin Ender
5

Haskell, 62 byte

g n|b<-[1..n]=[[last$k:[j|k==i]++[i|k==j]|k<-b]|i<-b,j<-b,j<i]

Cobalah online!

i<-b                -- loop 'i' through [1..n]
     j<-b           -- loop 'j' through [1..n]
          j<i       -- consider only cases where j<i 
 [            k<-b] -- make a list by looping 'k' through [1..n] 
  last              -- pick
          [i|k==j]  -- 'i' if k==j
       [j|k==i]     -- 'j' if k==i
     k              -- 'k' else   
nimi
sumber
4

Haskell , 71 byte

f 0=[]
f x=map(++[x])(f$x-1)++[[1..y-1]++x:[y+1..x-1]++[y]|y<-[1..x-1]]

Cobalah online!


Ini menambahkan nomor saat ini ke akhir semua permutasi terakhir dan kemudian menghitung semua swap yang menyertakan nomor baru.

Wisaya Gandum
sumber
4

MATL , 12 byte

:2XN!"G:@tP(

Cobalah online!

            %implicit input, say, 4
:           %range, stack is {[1,2,3,4]}
2           %push 2
XN          %nchoosek, compute all combinations of [1,2,3,4] taken 2 at a time
            %this results in a matrix where each row is a combination, i.e.,
            %[1, 2;
              1, 3;
              1, 4;
              2, 3;
              2, 4;
              3, 4]
!           %transpose, because "for" iterates over columns
"           %begin for loop
G:          %push input and range, stack is now [1,2,3,4]
@t          %push "for" index (the column), say, [1;2], twice
P           %flip array, so stack is now: {[1,2,3,4],[1;2],[2;1]}
(           %assignment index, sets [1,2,3,4]([1;2])=[2;1],
            %resulting in [2,1,3,4]
            %implicit end of loop, implicit end of program, print the stack implicitly.

Giuseppe
sumber
1
2 byte lebih pendek dari kode yang saya gunakan untuk menghasilkan kasus uji, dan jauh lebih efisien :-)
Luis Mendo
@LuisMendo Bagaimana Anda menghasilkan kasus uji? Saya khawatir milik saya lebih lama karena pesanannya tidak sama!
Giuseppe
1
Saya menggunakan :tY@wy=~!s2=Y). Pendekatan yang sama dengan jawaban oktaf rahnema1, saya pikir
Luis Mendo
3

C, 93 byte

i,j,k;f(n){for(i=0;i++<n;)for(j=i;j++<n;puts(""))for(k=0;k++<n;)printf("%d ",k-i?k-j?k:i:j);}

Cobalah online!

Steadybox
sumber
3

Oktaf, 38 byte

@(n)(p=perms(k=1:n))(sum(p~=k,2)==2,:)

Cobalah online!

Hasilkan semua permutasi 1: n dan pilih dari mereka yang memiliki dua elemen berbeda dari 1: n.

rahnema1
sumber
2

JavaScript (ES6), 81 byte

Mencetak 0 array yang diindeks.

n=>(a=[...Array(n).keys()]).map(i=>a.map(j=>i>j&&alert(a.map(k=>k-i?k-j?k:i:j))))

Demo

alert()diganti dengan console.log()dalam cuplikan ini untuk ramah pengguna.

Arnauld
sumber
2

Bersih , 90 82 byte

import StdEnv
$n#n=[1..n]
=tl(removeDup[[if(c<>b)if(c<>a)c b a\\c<-n]\\b<-n,a<-n])

Itu dapat dilakukan dalam 80 byte, tetapi itu berubah menjadi terjemahan langsung dari jawaban Haskell.

Cobalah online!

Suram
sumber
2

05AB1E , 15 9 byte

LœʒD{αĀO<

Cobalah online!

Penjelasan

L            # push range [1 ... input]
 œ           # get all permutations
  ʒ          # filter, keep only elements that are true when
     α       # absolute value is taken with
   D{        # a sorted copy
      Ā      # each non-zero value in the resulting array is converted to 1
       O     # the array is summed
        <    # and the sum is decremented
Emigna
sumber
2

Sekam , 9 byte

!2§kδ#≠Pḣ

Cobalah online!

Penjelasan

!2§kδ#≠Pḣ  Input is an integer n.
        ḣ  Range: r=[1,2,..,n]
       P   Permutations of r.
   k       Classify by
     #     number of elements
      ≠    that are different from
  § δ      the corresponding element of r.
!2         Take the second class.
Zgarb
sumber
2

Ruby , 55 53 byte

->n{n.times{|x|x.times{|y|(w=*0...n)[w[x]=y]=x;p w}}}

Cobalah online!

Solusi berbasis 0

Kuncinya di sini adalah bahwa loop dalam selalu "melompati" iterasi: pertama kali itu tidak dieksekusi sama sekali, maka hanya sekali pada lintasan kedua, dan seterusnya.

Saya senang dengan 55 byte sampai saya melihat bahwa R bisa di-golf menjadi 54, jadi saya harus mendapatkannya sampai 53.

GB
sumber
Penggunaan batasan output fleksibel yang sangat pintar.
Unihedron
1

Python 2 , 90 byte

f=lambda n,r=range:n*[n]and[a+[n]for a in f(n-1)]+[r(1,i)+[n]+r(i+1,n)+[i]for i in r(1,n)]

Cobalah online!

ovs
sumber
1

Pyth, 9 byte

t{.rLQ*=U

Demonstrasi

Cara termudah untuk menukar dua nilai adalah dengan menggunakan .r, yang merupakan fungsi terjemahan putar Pyth. .r<list>[A, B]akan menukar semua kemunculanA dan Bdalam list.

Oleh karena itu, dengan menerapkan fungsi terjemahan ke UQ, daftar dari 0ke n-1dengan setiap dua elemen daftar angka yang berbeda dalam daftar, kami akan menghasilkan output yang diinginkan. Qadalah input,n ,, dan Ufungsi rentang.

Cara mudah untuk melakukan ini adalah:

.rLUQ.cUQ2

.cUQ2menghasilkan semua 2 kombinasi elemen elemen yang berbeda dalam rentang, dan .rLUQmemetakan.r fungsi di atasnya dan daftar UQ.

Namun, itu akan menjadi 10 byte.

Alih-alih membuat .cUQ2, pasangan terurut berbeda, kita bisa membuat semua pasangan dengan *=U. Ini secara implisit setara dengan *=UQQ. Dimulai dengan Timpa Qdengan UQ, kemudian mengambil produk Cartesian UQdan UQ. Ini memberikan semua pasangan angka dalam kisaran, tidak harus dipesan atau berbeda.

.rLQswap menggunakan setiap daftar. Ingat bahwa Qsekarang sama dengan daftar dari 0ke n-1, bukan n.

Karena pasangan tidak dipesan, ada duplikat. {menghapus duplikat. Karena pasangan tidak berbeda, daftar tidak berubah hadir. Daftar ini akan selalu menjadi yang pertama setelah deduplikasi, karena {mempertahankan urutan tampilan pertama dan daftar yang tidak berubah dihasilkan oleh rotasi oleh [0,0]. tmenghapus elemen pertama, memberikan daftar swap yang diinginkan.

isaacg
sumber
1

Pyth, 11 byte

fq2snVTUQ.p

Cobalah secara online
Tidak sesingkat pendekatan isaacg, tetapi cukup berbeda untuk diposkan.

Penjelasan

fq2snVTUQ.p
         .pQ  Take the permutations of the (implicit) range [0,...,input].
f     T       Filter to get the permutations...
   snV UQ     ... where the number of differences with [0,...,input]...
 q2           ... is 2.

sumber
1

Java 8, 109 105 byte

n->{String r="";for(int i=0,j,k;i++<n;)for(j=i;j++<n;r+="\n")for(k=0;k++<n;)r+=k!=i?k!=j?k:i:j;return r;}

Saya berkarat .. Belum kode-golf dalam beberapa bulan .. Akhirnya porting @Steadybox 'C jawaban .. Mungkin bisa golf lagi.

Coba di sini.

Kevin Cruijssen
sumber
1

Ruby , 66 byte

->n{a=*1..n
a.permutation.select{|b|b.zip(a).count{|c,d|c!=d}==2}}

Cobalah online!

Unihedron
sumber
1

Ruby , 80 byte

-12 byte terima kasih kepada Unihedron.

->n{(r=1..n).map{|x|r.map{|y|r.map{|i|i==x ?y:i==y ?x:i}}}.flatten(1).uniq[1,n]}

Cobalah online!

Saya memiliki pendekatan dalam pikiran yang paling baik diterjemahkan ke Ruby untuk beberapa alasan, jadi ... Saya bahkan tidak benar-benar tahu Ruby ...

benar-benar manusiawi
sumber
Saya mengungguli ini: codegolf.stackexchange.com/a/152652/21830 . Maaf!
Unihedron
Tidak perlu meminta maaf! Saya pikir saya berbicara untuk sebagian besar pengguna PPCG ketika saya mengatakan bahwa kompetisi itulah yang membuat PPCG keren.
manusiawi
1
Adapun kode Anda, 1. Anda dapat menetapkan 1..nke variabel satu-char dan menggunakannya kembali (pernyataan terpisah dengan baris baru atau titik koma), 2. lakukan tanpa tanda kurung dalam pernyataan termary: i==x ?y:i==y ?x:i(perhatikan di mana saya memiliki ruang untuk memisahkan potensi shebang ) dan 3. uniq[1,n]bukannya uniq[1..-1].
Unihedron