数组的一次交换


19

灵感来自Stack Overflow上的一个问题

挑战

给定一个整数n>1,输出可以通过恰好交换阵列中的两个条目而获得的所有阵列[1, 2, ..., n]

阵列可以以任何顺序生产。

您可以始终使用[0, 1, ..., n-1](从0开始)代替[1, 2, ..., n](从1开始)。

附加规则

测试用例

输入2给出输出(假设从1开始)

2 1

输入3给出输出(请注意,三个数组可以按任意顺序排列)

1 3 2
2 1 3
3 2 1

输入4给出输出

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

输入7给出输出

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

oeis.org/A211369给出的索引条目加上按字典顺序排序的所有长度为n的列表中的一个(如果为0 ,则为两个)。
乔纳森·艾伦

5
我感谢[0 ... n-1]vs 的灵活性[1 ... n]!当我不得不使用a时,总是感到有些烦恼,1+因为J的零索引。
科尔

Answers:


3

果冻11 8字节

ŒcżU$y€R

在线尝试!

怎么运行的

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

到底是y做什么的?对我来说一直都是一个谜。
Caird coinheringaahing

它执行替换。例如,[1,2],[4,3]y1,2,3替换每个1[1,2,3]4,并且每个23
丹尼斯,

8

R,54个字节

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

在线尝试!

返回一个矩阵,其中每一列都是一个排列。

combn(n,k)k从list n或从1:nif n是单个整数生成size的所有组合。它也可选地具有FUN要应用于所得组合的功能。因此,我们编写了一个执行交换并返回交换列表的函数。然后将结果全部累加到一个array,在这种情况下为2维,因此为一个矩阵。





5

Wolfram语言(Mathematica),43个字节

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

在线尝试!

说明:Subsets[Range@#,{2}]生成{1,2,...,n}大小为2的所有子集,然后为每个子集/.交换list中的这两件事{1,2,...,n}

令人失望的是,这种方法与其他许多提交方法相似,但是这是Mathematica所特有的,额外增加了3个字节:

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

在线尝试!


2
甚至更惯用的Mathematica解决方案将是ReplaceList[Range@#,{a___,b_,c___,d_,e___}:>{a,d,c,b,e}]&。我喜欢它的简单程度(或它如何直接编码问题),但是不幸的是,模式匹配语法过于冗长,最终只有57个字节。
Martin Ender '18

5

Haskell,62个字节

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

在线尝试!

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个字节

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

在线尝试!


这会将当前数字添加到last的所有排列的末尾,然后计算包括新数字的所有交换。


4

MATL,12字节

:2XN!"G:@tP(

在线尝试!

            %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个字节,而且效率更高:-)
Luis Mendo

@LuisMendo您是如何生成测试用例的?我担心我的时间会更长,因为订单不一样!
朱塞佩

1
我用过:tY@wy=~!s2=Y)。我认为与rahnema1的八度答案相同的方法
Luis


3

八度,38字节

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

在线尝试!

生成1:n的所有排列,并从中选择具有两个不同于1:n的元素的排列。


2

JavaScript(ES6),81个字节

打印索引为0的数组。

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

演示版

alert()console.log()在此代码段中被替换为便于用户使用。



2

干净90个 82字节

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

它可以用80个字节来完成,但是可以直接转换为Haskell答案。

在线尝试!


2

05AB1E15 9字节

LœʒD{αĀ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

外壳,9个字节

!2§kδ#≠Pḣ

在线尝试!

说明

!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

红宝石55 53字节

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

在线尝试!

基于0的解决方案

这里的窍门是内部循环总是“跳过”一个迭代:第一次完全不执行,然后在第二遍只执行一次,依此类推。

我对55个字节感到满意,直到我看到R可以降低到54,所以我不得不将其降低到53。


非常灵活地使用灵活的输出约束。
Unihedron


1

Pyth,9个字节

t{.rLQ*=U

示范

交换两个值的最简单方法是使用.r,这是Pyth的旋转转换功能。.r<list>[A, B]将交换AB中的所有匹配项list

因此,通过将转换函数应用于UQ,从0到的n-1列表以及列表中具有不同编号的每两个元素列表,我们将生成所需的输出。Q是输入,n以及U在该范围函数。

执行此操作的简单方法是:

.rLUQ.cUQ2

.cUQ2生成范围内不同元素的所有2个元素组合,并将函数.rLUQ映射到.r它们和list上UQ

但是,那将是10个字节。

.cUQ2我们可以使用来制作所有对,而不必制作不同的有序对*=U。这隐含等效于*=UQQ。它首先覆盖QUQ,然后采取的笛卡尔乘积UQUQ。这给出了范围内的所有数字对,不一定是有序的或不同的。

.rLQ使用每个列表进行交换。回想一下,Q现在等于from 0到list的列表n-1,不是n

因为没有对,所以有重复项。{删除重复项。因为这对没有区别,所以存在未更改的列表。重复数据删除后,此列表将始终排在第一位,因为{保留了第一个外观的顺序,并且通过旋转产生了未更改的列表[0,0]t删除第一个元素,提供所需的交换列表。


1

Pyth,11个字节

fq2snVTUQ.p

在线尝试
不像isaacg的方法那么短,但是可以发布得足够不同。

说明

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

红宝石,80个字节

-12个字节感谢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]}

在线尝试!

我想到的一种方法是出于某种原因最好翻译为Ruby,所以...我什至都不真正了解Ruby ...


我对此不满意:codegolf.stackexchange.com/a/152652/21830。抱歉!
Unihedron

不用道歉!当我说竞争使PPCG变得很酷时,我想代表大多数PPCG用户。
–totalhuman

1
对于您的代码,1.您可以分配1..n一个单字符变量并重用它(用换行符或分号分隔的语句),2.在termterm语句中不带括号:(i==x ?y:i==y ?x:i请注意,我在此处有空格来分隔潜在的shebang )和3. uniq[1,n]代替uniq[1..-1]
Unihedron
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.