Swap singoli di un array


19

Ispirato da Tratto da una domanda in overflow dello stack .

La sfida

Dato un numero intero n>1, genera tutti gli array che possono essere ottenuti scambiando esattamente due voci nell'array [1, 2, ..., n].

Le matrici possono essere prodotte in qualsiasi ordine.

È possibile utilizzare in modo coerente [0, 1, ..., n-1](basato su 0) anziché [1, 2, ..., n](basato su 1).

Regole aggiuntive

Casi test

Input 2fornisce output (presupposto 1 basato)

2 1

Input 3fornisce output (si noti che i tre array potrebbero essere in qualsiasi ordine)

1 3 2
2 1 3
3 2 1

L'input 4fornisce 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

L'input 7fornisce 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

Voci agli indici fornite da oeis.org/A211369 più una (o due se 0-indicizzazione) in un elenco lessicografico di tutte le permutazioni di lunghezza n.
Jonathan Allan,

5
Apprezzo la flessibilità di [0 ... n-1]vs [1 ... n]! Mi sento sempre un po 'seccato quando devo puntare su un 1+indice zero perché J.
Cole

Risposte:


3

Gelatina , 11 8 byte

ŒcżU$y€R

Provalo online!

Come funziona

Œ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. 

Che cosa fa esattamente y? È sempre stato un po 'un mistero per me.
caird coinheringaahing

Esegue sostituzioni. Ad esempio, [1,2],[4,3]y1,2,3sostituisce ogni 1 in [1, 2, 3] con 4 e ogni 2 con 3 .
Dennis

8

R , 54 byte

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

Provalo online!

Restituisce una matrice in cui ogni colonna è una permutazione.

combn(n,k)genera tutte le combinazioni di dimensioni kdall'elenco no da 1:nif nè un singolo numero intero. Opzionalmente accetta anche una funzione FUNda applicare alle combinazioni risultanti. Quindi scriviamo una funzione che esegue lo scambio e restituisce l'elenco scambiato. I risultati vengono quindi tutti accumulati in un array, che in questo caso è bidimensionale e quindi una matrice.



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

Provalo online!

Genero solo la permutazione, dato il xe yscambiare, per ciascunox,y



5

Wolfram Language (Mathematica) , 43 byte

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

Provalo online!

Spiegazione: Subsets[Range@#,{2}]genera tutti i sottoinsiemi di {1,2,...,n}dimensione 2, quindi per ciascun sottoinsieme, /.scambia queste due cose nell'elenco {1,2,...,n}.

Questo approccio è deludentemente simile a quello di molti altri invii, ma eccone uno più unico di Mathematica, per 3 byte extra:

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

Provalo online!


2
Una soluzione Mathematica ancora più idiomatica sarebbe ReplaceList[Range@#,{a___,b_,c___,d_,e___}:>{a,d,c,b,e}]&. Mi piace quanto sia semplice (o in che modo codifica direttamente il problema), ma sfortunatamente la sintassi del pattern matching è così dettagliata che finisce per essere 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]

Provalo 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   

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

Provalo online!


Ciò aggiunge il numero corrente alla fine di tutte le permutazioni dell'ultimo e quindi calcola tutti gli swap che includono il nuovo numero.


4

MATL , 12 byte

:2XN!"G:@tP(

Provalo 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.


1
2 byte in meno del codice che ho usato per generare i casi di test e molto più efficace :-)
Luis Mendo

@LuisMendo Come hai generato i casi di test? Ero preoccupato che il mio fosse più lungo poiché l'ordine non era lo stesso!
Giuseppe,

1
Ho usato :tY@wy=~!s2=Y). Lo stesso approccio della risposta Octave di rahnema1, credo
Luis Mendo il


3

Ottava, 38 byte

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

Provalo online!

Genera tutte le permutazioni di 1: n e seleziona da esse quelle che hanno due elementi diversi da 1: n.


2

JavaScript (ES6), 81 byte

Stampa array con indice 0.

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

dimostrazione

alert()viene sostituito con console.log()in questo frammento per facilità d'uso.



2

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

Può essere fatto in 80 byte, ma si trasforma in una traduzione diretta delle risposte di Haskell.

Provalo online!


2

05AB1E , 15 9 byte

LœʒD{αĀO<

Provalo online!

Spiegazione

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

2

Buccia , 9 byte

!2§kδ#≠Pḣ

Provalo online!

Spiegazione

!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.

2

Rubino , 55 53 byte

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

Provalo online!

Soluzione basata su 0

Il trucco qui è che il ciclo interno "salta" sempre un'iterazione: la prima volta non viene eseguito affatto, quindi solo una volta al secondo passaggio e così via.

Sono stato felice con 55 byte fino a quando ho visto che R poteva essere golfato a 54, quindi ho dovuto portarlo a 53.


Uso molto intelligente dei vincoli di uscita flessibili.
Unihedron,


1

Pyth, 9 byte

t{.rLQ*=U

Dimostrazione

Il modo più semplice per scambiare due valori è usare .r, che è la funzione di traduzione rotativa di Pyth. .r<list>[A, B]scambia tutte le occorrenze di Ae Bin list.

Pertanto, applicando la funzione di traduzione a UQ, l'elenco da 0a n-1con ciascun elenco di due elementi di numeri diversi nell'elenco, genereremo l'output desiderato. Qè l'input, ned Uè la funzione range.

Il modo semplice per farlo sarebbe:

.rLUQ.cUQ2

.cUQ2genera tutte le 2 combinazioni di elementi di elementi distinti nell'intervallo e .rLUQmappa la .rfunzione su di essi e l'elenco UQ.

Tuttavia, sarebbero 10 byte.

Invece di creare .cUQ2, le distinte coppie ordinate, possiamo fare tutte le coppie con *=U. Questo è implicitamente equivalente a *=UQQ. Si inizia sovrascrivendo Qcon UQ, quindi prendendo il prodotto cartesiano di UQe UQ. Ciò fornisce tutte le coppie di numeri nell'intervallo, non necessariamente ordinati o distinti.

.rLQscambia usando ogni lista. Ricordiamo che Qora è uguale all'elenco da 0a n-1, no n.

Poiché le coppie non sono state ordinate, ci sono duplicati. {rimuove i duplicati. Poiché le coppie non erano distinte, è presente l'elenco invariato. Questo elenco sarà sempre il primo dopo la deduplicazione, perché {conserva l'ordine del primo aspetto e l'elenco invariato viene prodotto ruotando di [0,0]. trimuove il primo elemento, fornendo l'elenco desiderato di swap.


1

Pyth, 11 byte

fq2snVTUQ.p

Provalo online
Non breve come l'approccio di isaacg, ma abbastanza diverso da pubblicare.

Spiegazione

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.



1

Rubino , 80 byte

-12 byte grazie a 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]}

Provalo online!

Avevo in mente un approccio che si traduceva meglio in Ruby per qualche motivo, quindi ... non conosco nemmeno Ruby ...


Ho superato questo: codegolf.stackexchange.com/a/152652/21830 . Scusate!
Unihedron,

Non c'è bisogno di scusarsi! Penso di parlare per la maggior parte degli utenti di PPCG quando dico che la concorrenza è ciò che rende cool PPCG.
totalmente umano il

1
Per quanto riguarda il tuo codice, 1. potresti assegnare 1..nuna variabile a un carattere e riutilizzarla (istruzioni separate con newline o punti e virgola), 2. fare senza parentesi nelle dichiarazioni temporanee: i==x ?y:i==y ?x:i(nota dove ho gli spazi per separare il potenziale shebang ) e 3. uniq[1,n]anziché uniq[1..-1].
Unihedron,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.