反向插入排序


19

目的

根据“ 插入排序”对列表进行排序的动作,生成原始的加扰列表。原始列表将包含从0N-1(包括)的所有数字,其中N输入的大小。

输入项

一个包含对列表进行排序的必要动作的列表。每个值代表由原始数字(加扰的数字)移位到其右位置的插槽数量,请记住,此过程是从左到右。输入列表
中(0索引)位置的值i将介于0和之间i
您不需要处理无效的输入,在这种情况下,任何行为都是可以接受的(崩溃,无限循环等)。

输出量

混乱的名单

逐步生成动作

Scrambled List | Moves to sort
[4,0,2,1,3,5]  | [0, , , , , ] #4 stay in place
[4,0,2,1,3,5]  | [0,1, , , , ] #0 is moved 1 slot to the left
[0,4,2,1,3,5]  | [0,1,1, , , ] #2 is moved 1 slot
[0,2,4,1,3,5]  | [0,1,1,2, , ] #1 is moved 2 slot
[0,1,2,4,3,5]  | [0,1,1,2,1, ] #3 is moved 1 slot
[0,1,2,3,4,5]  | [0,1,1,2,1,0] #5 is in the right place already
[0,1,2,3,4,5]

因此,对于输入,[0,1,1,2,1,0]您的程序需要输出[4,0,2,1,3,5]
请记住,移动不是到(最终)排序列表中的位置,而是到排序的段(粗体部分)中的位置

测试用例

[0,0,0] -> [0,1,2]
[0,1,0,1] -> [1,0,3,2]
[0,0,0,0,0,5] -> [1,2,3,4,5,0]
[0,1,2,3] -> [3,2,1,0]
[0,1,1,1] -> [3,0,1,2]
[0,1,1,2,1,0] -> [4,0,2,1,3,5]

获奖

这是,因此最短的答案将获胜。

code-golf  array-manipulation  code-golf  code-golf  animation  code-golf  restricted-source  code-golf  java  code-golf  decision-problem  graph-theory  code-golf  conversion  electrical-engineering  code-golf  ascii-art  code-golf  string  substitution  code-golf  math  code-golf  string  set-theory  code-golf  code-golf  compile-time  code-golf  kolmogorov-complexity  binary  code-golf  sequence  cops-and-robbers  code-golf  subsequence  card-games  code-golf  sequence  primes  code-golf  code-golf  number  graphical-output  music  code-golf  ascii-art  code-golf  string  lambda-calculus  code-golf  string  code-generation  code-golf  unicode  code-golf  math  combinatorics  code-golf  balanced-string  code-golf  sequence  cops-and-robbers  code-golf  sequence  cops-and-robbers  code-challenge  fastest-code  chess  code-golf  math  graphical-output  code-golf  string  hello-world  animation  code-golf  number  arithmetic  code-golf  integer  code-golf  code-golf  combinatorics  code-golf  kolmogorov-complexity  graphical-output  code-golf  string  code-golf  code-golf  game  code-golf  math  combinatorics  code-golf  ascii-art  popularity-contest  random  code-golf  arithmetic  number-theory  integer  code-golf  tips  underload  code-golf  math  sequence  primes  code-golf  math  path-finding  code-golf  ascii-art  primes  code-golf  kolmogorov-complexity  alphabet 

1
程序是否还可以将列表的长度作为输入?
mbomb007 '17

@ mbomb007不。
Rod

我们可以改用(n-1)个步骤吗?第一个是不必要的,因为它始终为零。
GB

@GB当然,只要输出正确,就可以使用任何算法
Rod Rod

Answers:


14

果冻,12字节

L!_UÆ¡$œ?J’U

在线尝试!

说明

我们基本上可以看到两个列表(输入和输出)都编码为整数。输入以阶乘为单位对整数进行编码,输出将整数作为置换进行编码。幸运的是,Jelly的内建函数已经非常接近这两种编码,因此只需编写一小段代码以转换为整数,然后再转换为另一种编码即可。

L!_UÆ¡$œ?J’U
   U           Reverse {the input}
    Æ¡         and convert from base factorial to integer;
  _   $        subtract that from
L!             the factorial of the length of {the input};
       œ?      then take the nth permutation of
         J     [1,2,...,l], where l is the length of {the input},
          ’    subtract 1 from every elevent,
           U   and reverse it

对于基本阶乘,我们可以观察到列表的第一个元素必须为0,第二个元素可以为0或1,第三个元素必须为0/1/2,依此类推。因此,我们必须反转输入,以使其元素转换为基本转换的正常写入顺序。

另外,为了使阶乘转换和置换转换的相对顺序与插入排序所使用的操作相匹配,我们需要进行两项调整:反转置换的顺序,以及反转输出列表的顺序。反转输出列表非常容易,只需U在程序末尾添加一个即可。要反转排列的顺序,我们从输入长度的阶乘中减去(之所以起作用,是因为基本阶乘会产生一个介于0到(length!-1)范围内的数字,而排列由Jelly从1到长度进行编号! ,产生一个隐式的一对一抵消,当您从阶乘中减去置换索引时,该抵消会抵消您通常会获得的一对一。

Jelly,9个字节,与@JonathanAllan合作

UÆ¡Nœ?J’U

该程序的版本非常相似,但是使用了一种不同的方法来反转排列顺序。简单地将输入与否定N就足以使œ?处理顺序相反。除此之外,它的工作方式与以前的程序相同。

在线尝试!


4
O_O这什么法术?
DLosc

哦,太好了-我知道我Æ¡œ?原子将为此工作(我早些时候已经开始尝试将它们用于此挑战-我是如此接近,只需要L!在那里使用)。
乔纳森·艾伦,

优秀的代码!
格雷格·马丁

1
实际上,您可以用9个字节来完成此操作,UÆ¡Nœ?L’U因为我实现了œ?(以及类似的)模块化操作(就像他们使用的是Jelly列表一样)。在N与负值只是索引。注:我改变JL-这仅仅是因为赋予了许多它使一个范围下引擎罩反正)。
乔纳森·艾伦

6

Mathematica,92个字节

Permute[Range[l=Length@#]-1,(c=Cycles@{#}&)@{}©##&@@c[i-0~Range~#[[i]]]~Table~{i,l,1,-1}]&

将非负整数列表作为输入并返回非负整数列表的纯函数。上面的代码包含一个©,这是不正确的:它是3字节符号U + F3DE的占位符,Mathematica用一个带点的圆表示该Mathematica,并表示置换的组成。

c=Cycles@{#}&定义一个将整数列表转换为Cycles表示置换的对象的函数;例如,c[{3,4}]是列表的换位交换元素3和4。c[i-0~Range~#[[i]]]~Table~{i,l,1,-1}]获取输入列表并生成撤消插入排序所需的排列。然后c@{}©##&@@从标识置换开始,将所有这些置换组合在一起c@{}。最后,Permute[Range[l=Length@#]-1,...]将此置换应用于适当长度的0索引列表。


1
什么没有内置的?!当然...
Jonathan Allan

3
@{#}&)@{}©##&@@看起来很吓人。
Yytsi

6

Python 2,79 68字节

感谢Krazor节省了10个字节

感谢TuukkaX节省了1个字节

a=input();b=range(len(a));print[b.pop(j-a[j])for j in b[::-1]][::-1]

通过反向生成动作来工作


2
使那个66!如何:a=input();b=range(len(a));print[b.pop(j-a[j]) for j in b[::-1]][::-1]。清单理解!
FMaz '17

1
@Krazor您之前有一个可以删除的空间for,所以让65我猜:D
Yytsi

@Krazor事实证明列表理解并不太奏效,但是我喜欢使用b [::-1]的想法!
数学迷

没门?我用手机发表了评论,也许我输错了一些。哪一部分不起作用?对我来说,它正确解释并满足了所有测试用例。
FMaz '17

@Krazor哦,糟糕,您是对的。我是在测试时输入错误的人。
数学迷

5

JavaScript(ES6),69 65 63字节

a=>a.reverse(b=[...a.keys()]).map(o=>+b.splice(~o,1)).reverse()

令人讨厌的是,输入和输出的顺序都不正确。编辑:由于@Arnauld,节省了4个字节。@ETHproductions节省了2个字节。


我仍在尝试寻找更好的方法,但是您的速度更快。好一个!
Arnauld

1
您不需要i,是吗?
Arnauld

@Arnauld显然不是。我首先尝试理解Python的答案,但我只是注意到它实际上并没有使用i……
Neil

1
简易-2:o=>+b.splice(~o,1)
ETHproductions '17

3

JavaScript(ES6),73 71字节

ETHproductions节省了2个字节

m=>(a=m.map((_,i)=>j=i)).map(_=>a.splice(j,0,+a.splice(j-m[j--],1)))&&a

测试用例


同时获取长度和范围的好方法。我会建议a=m.map(_=>j++,j=0),但是长度是一样的,我确定您已经尝试过了。
ETHproductions '17

@ETHproductions你是对的:我也尝试过。:-)(可能值得注意的是,这并不等效:这将设置ja.length而不是a.length-1并且将需要a.splice(--j,0,a.splice(j-m[j],1)[0])
Arnauld

嘿,我也想到了这一点,但我认为不值得一提,因为它的长度是一样的
ETHproductions'Bug 18''17

1
简易-2:+a.splice(j-m[j--],1)
ETHproductions '17

2

Haskell,85个字节

f x|n<-length x-1=reverse x#[n,n-1..0]
(n:r)#l=r#(take n l++drop(n+1)l)++[l!!n]
x#l=x

在线尝试!用法示例:f [0,1,1,2,1,0]yields [4,0,2,1,3,5]

f x调用#list x反向和list 的函数[length x - 1, length x - 2, ... , 0](n:r)#l通过递归地从nth中取出第th个元素来执行反向插入排序l,其中l!!n产生第nth个元素并take n l++drop(n+1)l产生删除ln第th个元素的列表。


哈斯克尔,真漂亮。
FMaz '17

1

perl,61个字节

@o=@p=0..@ARGV-1;splice@o,$_,0,splice@o,$_-pop,1for reverse@p

输出以数组@o结尾。输入数组作为命令行参数的示例:

perl -le'@o=@p=0..@ARGV-1;splice@o,$_,0,splice@o,$_-pop,1for reverse@p;print@o' 0 1 1 2 1 0
402135

1

Ruby,49个字节

->l{(w=l.size).times{l.insert(l.shift+w-=1,w)};l}

从最大数量开始,在列表内的适当位置执行“反向插入”。

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.