Pojedyncze zamiany tablicy

19

Zainspirowany przez Taken z pytania w Stack Overflow .

Wyzwanie

Biorąc pod uwagę liczbę całkowitą n>1, wypisz wszystkie tablice, które można uzyskać, zamieniając dokładnie dwa wpisy w tablicy [1, 2, ..., n].

Tablice mogą być produkowane w dowolnej kolejności.

Możesz konsekwentnie używać [0, 1, ..., n-1](w oparciu o 0) zamiast [1, 2, ..., n](w oparciu o 1).

Dodatkowe zasady

Przypadki testowe

Wejście 2daje wynik (zakładany na podstawie 1)

2 1

Dane wejściowe 3dają dane wyjściowe (zauważ, że trzy tablice mogą być w dowolnej kolejności)

1 3 2
2 1 3
3 2 1

Wejście 4daje wyjście

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

Wejście 7daje wyjście

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
źródło
Wpisy o indeksach podanych przez oeis.org/A211369 plus jeden (lub dwa, jeśli indeksowanie 0) na leksykograficznie posortowanej liście wszystkich permutacji o długości n.
Jonathan Allan
5
Doceniam elastyczność [0 ... n-1]vs [1 ... n]! Zawsze czuję się trochę zirytowany, gdy muszę się przyczepić z 1+powodu indeksów zerowych J.
cole

Odpowiedzi:

3

Galaretka , 11 8 bajtów

ŒcżU$y€R

Wypróbuj online!

Jak to działa

Œ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
źródło
Co dokładnie robi y? To zawsze było dla mnie trochę tajemnicą.
caird coinheringaahing
Dokonuje wymiany. Na przykład, [1,2],[4,3]y1,2,3zastępuje każdy 1 w [1, 2, 3] do 4 , a każdy z 2 z 3 .
Dennis
8

R , 54 bajty

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

Wypróbuj online!

Zwraca macierz, w której każda kolumna jest permutacją.

combn(n,k)generuje wszystkie kombinacje wielkości kz listy nlub z, 1:njeśli njest pojedynczą liczbą całkowitą. Opcjonalnie przyjmuje również funkcję, FUNktóra ma być zastosowana do powstałych kombinacji. Piszemy więc funkcję, która wykonuje zamianę i zwraca listę zamienionych. Wyniki są następnie sumowane w postaci array, która w tym przypadku jest dwuwymiarowa, a zatem macierzy.

Giuseppe
źródło
6

Haskell , 62 bajty

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

Wypróbuj online!

Po prostu generuję permutację, biorąc pod uwagę xi ydo zamiany, dla każdegox,y

H.PWiz
źródło
5

Wolfram Language (Mathematica) , 43 bajty

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

Wypróbuj online!

Objaśnienie: Subsets[Range@#,{2}]generuje wszystkie podzbiory o {1,2,...,n}rozmiarze 2, a następnie dla każdego podzbioru /.zamienia te dwie rzeczy na liście {1,2,...,n}.

To podejście jest rozczarowująco podobne do wielu innych zgłoszeń, ale oto jedno, które jest bardziej unikalne dla Mathematica, dla 3 dodatkowych bajtów:

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

Wypróbuj online!

Nie drzewo
źródło
2
Byłoby jeszcze bardziej idiomatyczne rozwiązanie Mathematica ReplaceList[Range@#,{a___,b_,c___,d_,e___}:>{a,d,c,b,e}]&. Podoba mi się, jak to jest proste (lub jak bezpośrednio koduje problem), ale niestety składnia dopasowywania wzorców jest tak pełna, że ​​kończy się to na 57 bajtach.
Martin Ender
5

Haskell, 62 bajty

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

Wypróbuj 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
źródło
4

Haskell , 71 bajtów

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

Wypróbuj online!


To dodaje bieżącą liczbę na końcu wszystkich permutacji ostatniego, a następnie oblicza wszystkie swapy, które zawierają nowy numer.

Kreator pszenicy
źródło
4

MATL , 12 bajtów

:2XN!"G:@tP(

Wypróbuj 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
źródło
1
2 bajty krótsze niż kod, którego użyłem do wygenerowania przypadków testowych, i znacznie bardziej wydajne :-)
Luis Mendo
@LuisMendo Jak wygenerowałeś przypadki testowe? Martwiłem się, że mój był dłuższy, ponieważ kolejność nie była taka sama!
Giuseppe,
1
Kiedyś :tY@wy=~!s2=Y). Wydaje mi się, że to samo podejście, co odpowiedź Octave rahnema1
Luis Mendo,
3

C, 93 bajty

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);}

Wypróbuj online!

Steadybox
źródło
3

Oktawa, 38 bajtów

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

Wypróbuj online!

Generuje wszystkie permutacje 1: n i wybiera z nich te, które mają dwa elementy różne od 1: n.

rahnema1
źródło
2

JavaScript (ES6), 81 bajtów

Drukuje tablice 0-indeksowane.

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

Próbny

alert()został zastąpiony przez console.log()w tym fragmencie dla wygody użytkownika.

Arnauld
źródło
2

Czysty , 90 82 bajtów

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

Można to zrobić w 80 bajtach, ale zamienia się w bezpośrednie tłumaczenie odpowiedzi Haskella.

Wypróbuj online!

Obrzydliwe
źródło
2

05AB1E , 15 9 bajtów

LœʒD{αĀO<

Wypróbuj online!

Wyjaśnienie

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
źródło
2

Łuska , 9 bajtów

!2§kδ#≠Pḣ

Wypróbuj online!

Wyjaśnienie

!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
źródło
2

Rubinowy , 55 53 bajtów

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

Wypróbuj online!

Rozwiązanie oparte na 0

Sztuczka polega na tym, że wewnętrzna pętla zawsze „pomija” iterację: za pierwszym razem wcale nie jest wykonywana, a potem tylko raz przy drugim przejściu i tak dalej.

Byłem zadowolony z 55 bajtów, dopóki nie zobaczyłem, że R można zagrać w golfa do 54, więc musiałem uzyskać 53.

GB
źródło
Bardzo sprytne użycie elastycznych ograniczeń wyników.
Unihedron
1

Python 2 , 90 bajtów

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)]

Wypróbuj online!

ovs
źródło
1

Pyth, 9 bajtów

t{.rLQ*=U

Demonstracja

Najłatwiejszym sposobem zamiany dwóch wartości jest użycie .r, która jest funkcją tłumaczenia obrotowego Pytha. .r<list>[A, B]będzie zamienić wszystkie wystąpienia Ai Bwlist .

Dlatego poprzez zastosowanie funkcji tłumaczenia do UQlisty od 0do n-1z każdą listą dwóch elementów o różnych liczbach na liście wygenerujemy pożądany wynik. Qjest wejściem ni Ufunkcją zakresu.

Najłatwiejszym sposobem na to byłoby:

.rLUQ.cUQ2

.cUQ2generuje wszystkie 2 kombinacje elementów odrębnych elementów w zakresie i .rLUQmapuje .rfunkcję nad nimi i listą UQ.

Będzie to jednak 10 bajtów.

Zamiast tworzyć .cUQ2odrębne uporządkowane pary, możemy wykonać wszystkie pary *=U. Jest to domyślnie równoważne z *=UQQ. Zaczyna się od nadpisania za Qpomocą UQ, a następnie wzięcia iloczynu kartezjańskiego z UQi UQ. Daje to wszystkie pary liczb z zakresu, niekoniecznie uporządkowane lub odrębne.

.rLQzamienia za pomocą każdej listy. Przypomnijmy, że Qjest teraz równa liście od 0do n-1, a nie n.

Ponieważ pary nie zostały zamówione, istnieją duplikaty. {usuwa duplikaty. Ponieważ pary nie były różne, obecna jest lista bez zmian. Ta lista zawsze będzie pierwsza po deduplikacji, ponieważ {zachowuje kolejność pierwszego pojawienia się, a niezmieniona lista jest tworzona przez obracanie przez [0,0]. tusuwa pierwszy element, dając pożądaną listę zamian.

isaacg
źródło
1

Pyth, 11 bajtów

fq2snVTUQ.p

Wypróbuj online
Nie tak krótki, jak podejście Isaacga, ale wystarczająco inny, aby opublikować.

Wyjaśnienie

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.

źródło
1

Java 8, 109 105 bajtów

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;}

Jestem zardzewiały ... Nie grałem w golfa od miesięcy ... Skończyło się na portowaniu @Steadybox 'C odpowiedź .. Prawdopodobnie można jeszcze grać w golfa.

Wypróbuj tutaj.

Kevin Cruijssen
źródło
1

Rubin , 66 bajtów

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

Wypróbuj online!

Unihedron
źródło
1

Rubinowy , 80 bajtów

-12 bajtów dzięki 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]}

Wypróbuj online!

Miałem na myśli podejście, które najlepiej tłumaczy się na Ruby z jakiegoś powodu, więc ... nawet tak naprawdę nie znam Ruby ...

całkowicie ludzki
źródło
Wygrałem go w golfa: codegolf.stackexchange.com/a/152652/21830 . Przepraszam!
Unihedron
Nie ma potrzeby przepraszać! Myślę, że mówię w imieniu większości użytkowników PPCG, kiedy mówię, że konkurencja sprawia, że ​​PPCG jest fajne.
całkowicieludzki
1
Jeśli chodzi o kod, 1. możesz przypisać 1..nzmienną jednoznakową i użyć jej ponownie (osobne instrukcje z znakiem nowej linii lub średnikami), 2. nie używaj nawiasów w instrukcjach termicznych: i==x ?y:i==y ?x:i(zwróć uwagę, że mam spacje, aby oddzielić potencjalny shebang ) i 3. uniq[1,n]zamiast uniq[1..-1].
Unihedron