指针跳


21

假设我们有一个长度为n的数组ps,其中的指针指向该数组中的某个位置:“ 指针跳跃 ”过程将把每个指针都设置为其指向的指针所指向的位置。n

出于此挑战的目的,指针是数组元素的(从零开始)索引,这意味着数组中的每个元素都将大于或等于0且小于n。使用此表示法,可以将过程表述为:

for i = 0..(n-1) {
  ps[i] = ps[ps[i]]
}

这意味着(针对此挑战),指针将按顺序进行就地更新(即,先降低索引)。

让我们来看一个例子,ps = [2,1,4,1,3,2]

i = 0:the element at position ps[0] = 2 points to 4ps = [4,1,4,1,3,2]i = 1:the element at position ps[1] = 1 points to 1ps = [4,1,4,1,3,2]i = 2:the element at position ps[2] = 4 points to 3ps = [4,1,3,1,3,2]i = 3:the element at position ps[3] = 1 points to 1ps = [4,1,3,1,3,2]i = 4:the element at position ps[4] = 3 points to 1ps = [4,1,3,1,1,2]i = 5:the element at position ps[5] = 2 points to 3ps = [4,1,3,1,1,3]

因此,在“ 指针跳跃迭代之后,我们得到数组[4,1,3,1,1,3][4,1,3,1,1,3]

挑战

给定具有索引的数组,则输出通过迭代上述指针跳转获得的数组,直到该数组不再更改为止。

规则

您的程序/函数将采用并返回/输出相同的类型,列表/向量/数组等。

  • 保证是非空的
  • 是保证仅包含条目0p<n

变体:您可以选择

  • 使用基于1的索引或
  • 使用实际的指针,

但是,您应该在提交的内容中提及这一点。

测试用例

[0]  [0]
[1,0]  [0,0]
[1,2,3,4,0]  [2,2,2,2,2]
[0,1,1,1,0,3]  [0,1,1,1,0,1]
[4,1,3,0,3,2]  [3,1,3,3,3,3]
[5,1,2,0,4,5,6]  [5,1,2,5,4,5,6]
[9,9,9,2,5,4,4,5,8,1,0,0]  [1,1,1,1,4,4,4,4,8,1,1,1]

相关阅读:跳转阵列
ბიმო

我们可以将长度n作为附加输入吗?
凯文·克鲁伊森

2
@KevinCruijssen,请参阅此元讨论
毛茸茸的

需要按顺序更新条目太糟糕了;如果可以同时更新它们,则Mathematica将具有21个字符的解决方案#[[#]]&~FixedPoint~#&
格雷格·马丁

Answers:



6

Haskell,56个字节

foldr(\_->([]#))=<<id
x#a@(b:c)=(x++[(x++a)!!b])#c
x#_=x

Haskell和就地更新是不匹配的。

在线尝试!




5

迅捷68 53字节

{a in for _ in a{var i=0;a.forEach{a[i]=a[$0];i+=1}}}

在线尝试!

-15感谢BMO


2
欢迎来到PPCG!我不了解Swift,但是在codegolf.SE上,默认设置是接受类型化的lambda函数,我猜这将算作一个闭包。因此,它可以是53个字节(您无需计数f=)。在这里过得愉快!
ბიმო

感谢您提供的欢迎和建议,这些都是我用来更新答案的建议。
肖恩

如何使用map而不是forEach使其更短?
jaeyong唱

4

JavaScript(ES6),41个字节

f=a=>a+''==a.map((x,i)=>a[i]=a[x])?a:f(a)

在线尝试!


加!我一直在等待这个挑战,所以我可以发布完全相同的解决方案:\该死的忍者技能!:p
毛茸茸的

2
@shaggy 🐱‍👤(应该是忍者猫……但到处都可能不支持它)
Arnauld


4

Japt,15 13 7字节

修改原始输入数组。

££hYXgU

尝试一下(其他字节用于将修改后的输入写入控制台)

££hYXgU
£           :Map
 £          :  Map each X at index Y
  hY        :    Replace the element at index Y
    XgU     :    With the element at index X

4

Java 8,105 54字节

a->{for(int l=a.length,i=0;i<l*l;)a[i%l]=a[a[i++%l]];}

修改输入数组,而不是返回一个新的数组以节省字节。

只需修改数组即可-51字节 ËñGŤH2 次,而不是直到它不再改变。

在线尝试。

说明:

a->{                // Method with integer-array parameter and no return-type
  int l=a.length,   //  Length of the input-array
  i=0;i<l*l;)       //  Loop `i` in the range [0, length squared):
    a[i%l]=         //   Set the (`i` modulo-length)'th item in the array to:
      a[            //    The `p`'th value of the input-array,
        a[i++%l]];} //    where `p` is the (`i` modulo-length)'th value of the array

3

Japt,17个字节


®
£hYUgX
eV ?U:ß

尝试所有测试用例

感觉应该短一些,但是不幸的是我最初的想法UmgU没有用,因为每个人都g可以访问原始的U而不是在每个步骤中对其进行修改。适当地保留不同的组件也会花费少量的字节。

说明:

           #Blank line preserves input in U long enough for the next line

®          #Copy U into V to preserve its original value

£hY        #Modify U in-place by replacing each element X with...
   UgX     #The value from the current U at the index X

eV ?U      #If the modified U is identical to the copy V, output it
     :ß    #Otherwise start again with the modified U as the new input




2

R60 58字节

-2个字节,感谢@digEmAll读取规则。

function(x,n=sum(x|1)){for(i in rep(1:n,n))x[i]=x[x[i]];x}

在线尝试!

1个索引。

n 是输入数组的长度。

rep(1:n,n)复制1:n n时间(例如n=3 => 1,2,3,1,2,3,1,2,3

遍历数组n时间。到那时,我肯定会达到稳态,实际上是在第n-1次结束之前。证明留给读者。


1
我认为您可以删除+1并仅接受基于1的输入,该帖子指出:您可以选择使用基于1的索引
digEmAll

通过切换到-4 scan()作为输入。我总是觉得我的scan()解决方案不是最理想的,所以请留意一种较短的分配方式xn在一起的方式:n=length(x<-scan());for(i in rep(1:n,n))x[i]=x[x[i]];x 在线尝试!
刑事



2

Clojure,136字节

(defn j[a](let[f(fn[a](loop[i 0 a a](if(= i(count a))a(recur(inc i)(assoc a i(a(a i)))))))](loop[p nil a a](if(= p a)a(recur a(f a))))))

在线尝试!


您好,欢迎来到PPCG。您是否可以提供到在线口译员的链接,以便一个人可以轻松地验证您的解决方案?再者,loop [不能成为loop[
乔纳森·弗雷奇

1
最近的编辑修复测试失败。不便之处,敬请原谅。
伊桑·麦考



1

木炭,16字节

FθFLθ§≔θκ§θ§θκIθ

在线尝试!链接是详细版本的代码。可悲的是,所有常规映射函数仅对数组的副本进行操作,结果是它们只是置换元素而不是跳转元素,因此代码必须手动完成所有操作。说明:

Fθ

对每个元素重复一次内部循环。这只是确保结果稳定。

FLθ

循环遍历数组索引。

§≔θκ§θ§θκ

获取当前索引处的数组元素,使用该元素索引数组,然后用该值替换当前元素。

Iθ

将元素强制转换为字符串,然后将其隐式打印在各自的行上。


1

F#,74 73字节

fun(c:'a[])->let l=c.Length in(for i in 0..l*l do c.[i%l]<-c.[c.[i%l]]);c

没什么特别的。使用在其他答案中看到的模数想法。


1

K,27字节

{{@[x;y;:;x x y]}/[x;!#x]}/
  • {..}/ 在arg上应用lambda {..}(直到收敛)

  • 内部外部lambda:

    • {..}/[x;y]在x(每次迭代时更新)和y项(y是值列表,并在每次迭代中使用一个项)上迭代地应用lambda。在这种情况下,arg y是!#x(直到计数x,即数组的索引)

    • @[x;y;:;x x y] 修改数组x(在索引y处分配x [x [y]])


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.