Intercambios individuales de una matriz

19

Inspirado en Tomado de una pregunta en Stack Overflow .

El reto

Dado un número entero n>1, genera todas las matrices que se pueden obtener intercambiando exactamente dos entradas en la matriz [1, 2, ..., n].

Las matrices se pueden producir en cualquier orden.

Puede usar constantemente [0, 1, ..., n-1](basado en 0) en lugar de [1, 2, ..., n](basado en 1).

Reglas adicionales

Casos de prueba

La entrada 2da salida (se supone basada en 1)

2 1

La entrada 3da salida (tenga en cuenta que las tres matrices podrían estar en cualquier orden)

1 3 2
2 1 3
3 2 1

La entrada 4da salida

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

La entrada 7da salida

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
fuente
Entradas en los índices dados por oeis.org/A211369 más uno (o dos si indexa 0) en una lista ordenada lexicográficamente de todas las permutaciones de longitud n.
Jonathan Allan
55
Agradezco la flexibilidad de [0 ... n-1]vs [1 ... n]! Siempre me siento un poco molesto cuando tengo que añadir un 1+porque J índices cero.
cole

Respuestas:

3

Jalea , 11 8 bytes

ŒcżU$y€R

Pruébalo en línea!

Cómo funciona

Œ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
fuente
¿Qué hace exactamente y? Siempre ha sido un misterio para mí.
caird coinheringaahing
Realiza reemplazos. Por ejemplo, [1,2],[4,3]y1,2,3reemplaza cada 1 en [1, 2, 3] con 4 , y cada 2 con 3 .
Dennis
8

R , 54 bytes

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

Pruébalo en línea!

Devuelve una matriz donde cada columna es una permutación.

combn(n,k)genera todas las combinaciones de tamaño kde la lista n, o de 1:nsi nes un solo entero. También opcionalmente toma una función FUNpara ser aplicada a las combinaciones resultantes. Entonces escribimos una función que realiza el intercambio y devuelve la lista intercambiada. Los resultados se acumulan en una array, que en este caso es bidimensional y, por lo tanto, una matriz.

Giuseppe
fuente
6

Haskell , 62 bytes

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

Pruébalo en línea!

Solo genero la permutación, dada la xy ypara intercambiar, para cadax,y

H.PWiz
fuente
5

Wolfram Language (Mathematica) , 43 bytes

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

Pruébalo en línea!

Explicación: Subsets[Range@#,{2}]genera todos los subconjuntos de {1,2,...,n}tamaño 2, luego, para cada subconjunto, /.intercambia esas dos cosas en la lista {1,2,...,n}.

Ese enfoque es decepcionantemente similar a muchos de los otros envíos, pero aquí hay uno que es más exclusivo de Mathematica, para 3 bytes adicionales:

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

Pruébalo en línea!

No un arbol
fuente
2
Una solución de Mathematica aún más idiomática sería ReplaceList[Range@#,{a___,b_,c___,d_,e___}:>{a,d,c,b,e}]&. Me gusta lo simple que es (o qué tan directamente codifica el problema), pero desafortunadamente la sintaxis de coincidencia de patrones es tan detallada que termina siendo 57 bytes.
Martin Ender
5

Haskell, 62 bytes

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

Pruébalo en línea!

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
fuente
4

Haskell , 71 bytes

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

Pruébalo en línea!


Esto agrega el número actual al final de todas las permutaciones de último y luego calcula todos los intercambios que incluyen el nuevo número.

Asistente de trigo
fuente
4

MATL , 12 bytes

:2XN!"G:@tP(

Pruébalo en línea!

            %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
fuente
1
2 bytes más corto que el código que usé para generar los casos de prueba, y mucho más eficiente :-)
Luis Mendo
@LuisMendo ¿Cómo generó los casos de prueba? ¡Me preocupaba que el mío fuera más largo ya que el pedido no era el mismo!
Giuseppe
1
He utilizado :tY@wy=~!s2=Y). El mismo enfoque que la respuesta Octave de rahnema1, creo
Luis Mendo el
3

C, 93 bytes

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

Pruébalo en línea!

Steadybox
fuente
3

Octava, 38 bytes

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

Pruébalo en línea!

Genera todas las permutaciones de 1: ny selecciona de ellas aquellas que tienen dos elementos diferentes de 1: n.

rahnema1
fuente
2

JavaScript (ES6), 81 bytes

Imprime matrices indexadas en 0.

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

Manifestación

alert()se reemplaza con console.log()en este fragmento para facilitar su uso.

Arnauld
fuente
2

Limpio , 90 82 bytes

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

Se puede hacer en 80 bytes, pero se convierte en una traducción directa de las respuestas de Haskell.

Pruébalo en línea!

Οurous
fuente
2

05AB1E , 15 9 bytes

LœʒD{αĀO<

Pruébalo en línea!

Explicación

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
fuente
2

Casco , 9 bytes

!2§kδ#≠Pḣ

Pruébalo en línea!

Explicación

!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
fuente
2

Ruby , 55 53 bytes

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

Pruébalo en línea!

Solución basada en 0

El truco aquí es que el bucle interno siempre "omite" una iteración: la primera vez que no se ejecuta, luego solo una vez en la segunda pasada, y así sucesivamente.

Estaba contento con 55 bytes hasta que vi que R podía reducirse a 54, así que tuve que llegar a 53.

GB
fuente
Uso muy inteligente de restricciones de salida flexibles.
Unihedron
1

Pyth, 9 bytes

t{.rLQ*=U

Demostración

La forma más fácil de intercambiar dos valores es usar .r, que es la función de traducción rotativa de Pyth. .r<list>[A, B]intercambiará todas las ocurrencias de Ay Ben list.

Por lo tanto, al aplicar la función de traducción a UQ, la lista de 0a n-1con cada lista de dos elementos de diferentes números en la lista, generaremos el resultado deseado. Qes la entrada, ny Ues la función de rango.

La manera fácil de hacer esto sería:

.rLUQ.cUQ2

.cUQ2genera las 2 combinaciones de elementos de elementos distintos en el rango y .rLUQasigna la .rfunción sobre ellos y la lista UQ.

Sin embargo, eso sería 10 bytes.

En lugar de hacer .cUQ2los distintos pares ordenados, podemos hacer todos los pares con *=U. Esto es implícitamente equivalente a *=UQQ. Comienza sobrescribiendo Qcon UQ, luego tomando el producto cartesiano de UQy UQ. Esto proporciona todos los pares de números en el rango, no necesariamente ordenados o distintos.

.rLQintercambia utilizando cada lista. Recuerde que Qahora es igual a la lista de 0a n-1, no n.

Debido a que los pares no fueron ordenados, hay duplicados. {elimina duplicados Debido a que los pares no eran distintos, la lista sin cambios está presente. Esta lista siempre será la primera después de la deduplicación, porque {conserva el orden de la primera aparición y la lista sin cambios se produce al rotar por [0,0]. telimina el primer elemento, dando la lista deseada de intercambios.

isaacg
fuente
1

Pyth, 11 bytes

fq2snVTUQ.p

Pruébelo en línea
No tan corto como el enfoque de Isaac, pero lo suficientemente diferente como para publicar.

Explicación

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.

fuente
1

Java 8, 109105 bytes

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

Estoy oxidado ... No he codificado golf en meses ... Terminé portando la respuesta de @Steadybox 'C ... Probablemente se pueda jugar un poco más.

Pruébalo aquí

Kevin Cruijssen
fuente
1

Rubí , 80 bytes.

-12 bytes gracias 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]}

Pruébalo en línea!

Tenía un enfoque en mente que se traducía mejor a Ruby por alguna razón, así que ... Ni siquiera conozco a Ruby ...

totalmente humano
fuente
Superé esto: codegolf.stackexchange.com/a/152652/21830 . ¡Lo siento!
Unihedron
¡No necesitas disculparte! Creo que hablo por la mayoría de los usuarios de PPCG cuando digo que la competencia es lo que hace que PPCG sea genial.
Totalmente humano el
1
En cuanto a su código, 1. podría asignar 1..na una variable de un carácter y reutilizarla (declaraciones separadas con nueva línea o punto y coma), 2. sin corchetes en las declaraciones de termary: i==x ?y:i==y ?x:i(tenga en cuenta dónde tengo los espacios para separar el shebang potencial ) y 3. en uniq[1,n]lugar de uniq[1..-1].
Unihedron