Trocas únicas de uma matriz


19

Inspirado por Retirado de uma pergunta no Stack Overflow .

O desafio

Dado um número inteiro n>1, produza todas as matrizes que podem ser obtidas trocando exatamente duas entradas na matriz [1, 2, ..., n].

As matrizes podem ser produzidas em qualquer ordem.

Você pode usar consistentemente [0, 1, ..., n-1](com base em 0) em vez de [1, 2, ..., n](com base em 1).

Regras adicionais

Casos de teste

Entrada 2fornece saída (assumida com base em 1)

2 1

Entrada 3fornece saída (observe que as três matrizes podem estar em qualquer ordem)

1 3 2
2 1 3
3 2 1

Entrada 4dá saída

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

Entrada 7dá saída

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

Entradas nos índices fornecidas por oeis.org/A211369 mais uma (ou duas se indexação com 0) em uma lista lexicograficamente classificada de todas as permutações de comprimento n.
Jonathan Allan

5
Agradeço a flexibilidade do [0 ... n-1]vs [1 ... n]! Eu sempre me sinto um pouco irritado quando tenho que usar um 1+porque J zero-indexes.
cole

Respostas:


3

Geléia , 11 8 bytes

ŒcżU$y€R

Experimente online!

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

O que exatamente faz y? Sempre foi um mistério para mim.
caird coinheringaahing

Ele realiza substituições. Por exemplo, [1,2],[4,3]y1,2,3substitui cada 1 em [1, 2, 3] por 4 e cada 2 por 3 .
Dennis

8

R , 54 bytes

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

Experimente online!

Retorna uma matriz em que cada coluna é uma permutação.

combn(n,k)gera todas as combinações de tamanho kda lista nou de 1:nse nfor um único inteiro. Opcionalmente, também é necessária uma função FUNa ser aplicada às combinações resultantes. Então, escrevemos uma função que executa a troca e retorna a lista trocada. Os resultados são todos acumulados em um array, que é neste caso bidimensional e, portanto, uma matriz.





5

Wolfram Language (Mathematica) , 43 bytes

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

Experimente online!

Explicação: Subsets[Range@#,{2}]gera todos os subconjuntos de {1,2,...,n}tamanho 2 e, para cada subconjunto, /.alterna essas duas coisas na lista {1,2,...,n}.

Essa abordagem é decepcionantemente semelhante a muitos outros envios, mas aqui está um que é mais exclusivo do Mathematica, por 3 bytes extras:

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

Experimente online!


2
Uma solução Mathematica ainda mais idiomática seria ReplaceList[Range@#,{a___,b_,c___,d_,e___}:>{a,d,c,b,e}]&. Gosto da simplicidade (ou da codificação direta do problema), mas infelizmente a sintaxe de correspondência de padrões é tão detalhada que acaba sendo de 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]

Experimente 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 bytes

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

Experimente online!


Isso adiciona o número atual ao final de todas as permutações de último e calcula todos os swaps que incluem o novo número.


4

MATL , 12 bytes

:2XN!"G:@tP(

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


11
2 bytes mais curtos do que o código que usei para gerar os casos de teste e forma mais effcient :-)
Luis Mendo

@LuisMendo Como você gerou os casos de teste? Eu estava preocupado que o meu fosse mais longo, pois o pedido não era o mesmo!
Giuseppe

11
Eu usei :tY@wy=~!s2=Y). A mesma abordagem que a resposta de oitava de rahnema1, eu acho
Luis Mendo


3

Oitava, 38 bytes

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

Experimente online!

Gera todas as permutações de 1: n e seleciona entre elas aquelas que possuem dois elementos diferentes de 1: n.


2

JavaScript (ES6), 81 bytes

Imprime matrizes indexadas em 0.

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()é substituído por console.log()este trecho para facilitar a utilização.



2

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

Isso pode ser feito em 80 bytes, mas se transforma em uma tradução direta das respostas de Haskell.

Experimente online!


2

05AB1E , 15 9 bytes

LœʒD{αĀO<

Experimente online!

Explicação

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

Casca , 9 bytes

!2§kδ#≠Pḣ

Experimente online!

Explicação

!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

Ruby , 55 53 bytes

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

Experimente online!

Solução baseada em 0

O truque aqui é que o loop interno sempre "ignora" uma iteração: na primeira vez em que não é executado, apenas uma vez na segunda passagem e assim por diante.

Fiquei feliz com 55 bytes até ver que R podia ser reduzido a 54, então tive que chegar a 53.


Uso muito inteligente de restrições de saída flexíveis.
Unihedron


1

Pitão, 9 bytes

t{.rLQ*=U

Demonstração

A maneira mais fácil de trocar dois valores é usar .r, que é a função de translação rotativa de Pyth. .r<list>[A, B]trocará todas as ocorrências de Ae Bdentro list.

Portanto, aplicando a função de tradução a UQ, a lista de0 para n-1com cada lista de dois elementos de números diferentes na lista, geraremos a saída desejada. Qé a entrada, ne Ué a função de alcance.

A maneira mais fácil de fazer isso seria:

.rLUQ.cUQ2

.cUQ2 gera todas as 2 combinações de elementos distintos no intervalo e .rLUQ mapeia a .rfunção sobre eles e a lista UQ.

No entanto, isso seria 10 bytes.

Em vez de fazer .cUQ2, os pares ordenados distintos, podemos fazer todos os pares *=U. Isso é implicitamente equivalente a *=UQQ. Começa sobrescrevendo Qcom UQ, e depois levando o produto cartesiano deUQ eUQ . Isso fornece todos os pares de números no intervalo, não necessariamente ordenados ou distintos.

.rLQswaps usando cada lista. Lembre-se de que Qagora é igual à lista de 0paran-1 , não n.

Como os pares não foram encomendados, existem duplicatas. {remove duplicatas. Como os pares não eram distintos, a lista inalterada está presente. Essa lista sempre será a primeira após a desduplicação, pois {preserva a ordem da primeira aparição e a lista inalterada é produzida pela rotação por [0,0]. tremove o primeiro elemento, fornecendo a lista desejada de trocas.


1

Pitão, 11 bytes

fq2snVTUQ.p

Experimente online
Não é tão curto quanto a abordagem de isaacg, mas diferente o suficiente para postar.

Explicação

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

Rubi , 80 bytes

-12 bytes graças ao 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]}

Experimente online!

Eu tinha uma abordagem em mente que era melhor traduzida para Ruby por algum motivo, então ... eu realmente nem conheço Ruby ...



Não precisa se desculpar! Acho que falo pela maioria dos usuários de PPCG quando digo que a concorrência é o que torna o PPCG legal.
totallyhuman

11
Quanto ao seu código, 1. você pode atribuir 1..na uma variável one-char e reutilizá-la (instruções separadas com nova linha ou ponto e vírgula), 2. sem colchetes nas instruções termary: i==x ?y:i==y ?x:i(observe onde eu tenho espaços para separar o shebang em potencial ) e 3. em uniq[1,n]vez de uniq[1..-1].
Unihedron
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.