Swaps simples d'un tableau

19

Inspiré de Taken from a question at Stack Overflow .

Le défi

Étant donné un entier n>1, affichez tous les tableaux qui peuvent être obtenus en échangeant exactement deux entrées dans le tableau [1, 2, ..., n].

Les tableaux peuvent être produits dans n'importe quel ordre.

Vous pouvez toujours utiliser [0, 1, ..., n-1](basé sur 0) au lieu de [1, 2, ..., n](basé sur 1).

Règles supplémentaires

Cas de test

L'entrée 2donne la sortie (supposée basée sur 1)

2 1

L'entrée 3donne la sortie (notez que les trois tableaux peuvent être dans n'importe quel ordre)

1 3 2
2 1 3
3 2 1

L'entrée 4donne la sortie

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'entrée 7donne la sortie

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
la source
Entrées aux index données par oeis.org/A211369 plus un (ou deux si indexation 0) dans une liste triée lexicographiquement de toutes les permutations de longueur n.
Jonathan Allan
5
J'apprécie la flexibilité de [0 ... n-1]vs [1 ... n]! Je me sens toujours un peu ennuyé quand je dois virer sur un 1+index J parce que nul.
cole

Réponses:

3

Gelée , 11 8 octets

ŒcżU$y€R

Essayez-le en ligne!

Comment ça fonctionne

Œ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
la source
Que fait exactement y? Ça a toujours été un peu un mystère pour moi.
caird coinheringaahing
Il effectue des remplacements. Par exemple, [1,2],[4,3]y1,2,3remplace chaque 1 dans [1, 2, 3] par 4 et chaque 2 par 3 .
Dennis
8

R , 54 octets

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

Essayez-le en ligne!

Renvoie une matrice où chaque colonne est une permutation.

combn(n,k)génère toutes les combinaisons de taille à kpartir de la liste nou à partir de 1:nsi nest un seul entier. Il prend également éventuellement une fonction FUNà appliquer aux combinaisons résultantes. Nous écrivons donc une fonction qui effectue l'échange et renvoie la liste échangée. Les résultats sont ensuite tous accumulés dans un array, qui est dans ce cas bidimensionnel et donc une matrice.

Giuseppe
la source
6

Haskell , 62 octets

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

Essayez-le en ligne!

Je viens de générer la permutation, étant donné le xet ypour permuter, pour chaquex,y

H.PWiz
la source
5

Wolfram Language (Mathematica) , 43 octets

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

Essayez-le en ligne!

Explication: Subsets[Range@#,{2}]génère tous les sous-ensembles de {1,2,...,n}taille 2, puis pour chaque sous-ensemble, /.échange ces deux éléments dans la liste {1,2,...,n}.

Cette approche est malheureusement similaire à la plupart des autres soumissions, mais en voici une qui est plus spécifique à Mathematica, pour 3 octets supplémentaires:

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

Essayez-le en ligne!

Pas un arbre
la source
2
Une solution Mathematica encore plus idiomatique serait ReplaceList[Range@#,{a___,b_,c___,d_,e___}:>{a,d,c,b,e}]&. J'aime sa simplicité (ou la façon dont il encode directement le problème), mais malheureusement, la syntaxe de filtrage est si verbeuse que cela finit par être de 57 octets.
Martin Ender
5

Haskell, 62 octets

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

Essayez-le en ligne!

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
la source
4

Haskell , 71 octets

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

Essayez-le en ligne!


Cela ajoute le numéro actuel à la fin de toutes les permutations de la dernière, puis calcule tous les swaps qui incluent le nouveau numéro.

Assistant de blé
la source
4

MATL , 12 octets

:2XN!"G:@tP(

Essayez-le en ligne!

            %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
la source
1
2 octets de moins que le code que j'ai utilisé pour générer les cas de test, et bien plus efficace :-)
Luis Mendo
@LuisMendo Comment avez-vous généré les cas de test? J'avais peur que la mienne soit plus longue car la commande n'était pas la même!
Giuseppe
1
J'ai utilisé :tY@wy=~!s2=Y). Même approche que la réponse d'Octave de rahnema1, je pense
Luis Mendo
3

C, 93 octets

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

Essayez-le en ligne!

Steadybox
la source
3

Octave, 38 octets

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

Essayez-le en ligne!

Génère toutes les permutations de 1: n et en sélectionne celles qui ont deux éléments différents de 1: n.

rahnema1
la source
2

JavaScript (ES6), 81 octets

Imprime des tableaux indexés 0.

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

Démo

alert()est remplacé par console.log()dans cet extrait pour plus de convivialité.

Arnauld
la source
2

Nettoyer , 90 82 octets

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

Cela peut être fait en 80 octets, mais cela se transforme en une traduction directe des réponses Haskell.

Essayez-le en ligne!

Οurous
la source
2

05AB1E , 15 9 octets

LœʒD{αĀO<

Essayez-le en ligne!

Explication

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
la source
2

Coque , 9 octets

!2§kδ#≠Pḣ

Essayez-le en ligne!

Explication

!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
la source
2

Rubis , 55 53 octets

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

Essayez-le en ligne!

Solution basée sur 0

L'astuce ici est que la boucle interne «saute» toujours une itération: la première fois, elle n'est pas exécutée du tout, puis une seule fois lors du deuxième passage, et ainsi de suite.

J'étais satisfait de 55 octets jusqu'à ce que je voie que R pouvait être joué à 54, donc j'ai dû le faire à 53.

GB
la source
Utilisation très intelligente des contraintes de sortie flexibles.
Unihedron
1

Python 2 , 90 octets

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

Essayez-le en ligne!

ovs
la source
1

Pyth, 9 octets

t{.rLQ*=U

Manifestation

La façon la plus simple d'échanger deux valeurs est d'utiliser .r, qui est la fonction de traduction rotative de Pyth. .r<list>[A, B]permutera toutes les occurrences de Aet Bdans list.

Par conséquent, en appliquant la fonction de traduction à UQ, la liste de 0à n-1avec chaque liste de deux éléments de nombres différents dans la liste, nous générerons la sortie souhaitée. Qest l'entrée n, etU est la fonction de plage.

La façon la plus simple de procéder serait:

.rLUQ.cUQ2

.cUQ2génère les 2 combinaisons d'éléments d'éléments distincts de la plage et .rLUQmappe la .rfonction sur eux et la liste UQ.

Cependant, ce serait 10 octets.

Au lieu de faire .cUQ2, les paires ordonnées distinctes, nous pouvons faire toutes les paires avec *=U. Ceci est implicitement équivalent à *=UQQ. Il commence par écraser Qavec UQ, puis prend le produit cartésien de UQet UQ. Cela donne toutes les paires de nombres dans la plage, pas nécessairement ordonnées ou distinctes.

.rLQswaps utilisant chaque liste. Rappelez-vous que Qc'est maintenant égal à la liste de 0à n-1, non n.

Parce que les paires n'ont pas été commandées, il y a des doublons. {supprime les doublons. Parce que les paires n'étaient pas distinctes, la liste inchangée est présente. Cette liste sera toujours la première après la déduplication, car elle {préserve l'ordre de la première apparition et la liste inchangée est produite par rotation par [0,0]. tsupprime le premier élément, donnant la liste désirée de swaps.

isaacg
la source
1

Pyth, 11 octets

fq2snVTUQ.p

Essayez-le en ligne
Pas aussi court que l'approche de isaacg, mais assez différent pour poster.

Explication

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.

la source
1

Java 8, 109 105 octets

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

Je suis rouillé .. Je n'ai pas joué au code depuis des mois .. J'ai fini par porter la réponse @Steadybox 'C .. Peut probablement être joué au golf encore plus.

Essayez-le ici.

Kevin Cruijssen
la source
1

Rubis , 66 octets

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

Essayez-le en ligne!

Unihedron
la source
1

Ruby , 80 octets

-12 octets grâce à 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]}

Essayez-le en ligne!

J'avais une approche en tête qui se traduisait le mieux en Ruby pour une raison quelconque ... Je ne connais même pas vraiment Ruby ...

totalement humain
la source
J'ai dépassé ceci: codegolf.stackexchange.com/a/152652/21830 . Pardon!
Unihedron
Inutile de s'excuser! Je pense que je parle pour la plupart des utilisateurs de PPCG quand je dis que la concurrence est ce qui rend PPCG cool.
totalement humain le
1
Quant à votre code, 1. vous pouvez attribuer 1..nà une variable à un caractère et la réutiliser (instructions séparées avec un retour à la ligne ou des points-virgules), 2. se passer de crochets dans les instructions terminales: i==x ?y:i==y ?x:i(notez où j'ai les espaces pour séparer le shebang potentiel ) et 3. uniq[1,n]au lieu de uniq[1..-1].
Unihedron