ตัวชี้กระโดด


21

สมมติว่าเรามีอาเรย์ของความยาวพร้อมพอยน์เตอร์ที่ชี้ไปยังตำแหน่งบางอย่างในอาเรย์: กระบวนการของ " การกระโดดตัวชี้ " จะตั้งค่าตัวชี้ทุกตำแหน่งที่ตัวชี้ไปยังจุดPSn

สำหรับวัตถุประสงค์ของการท้าทายนี้เป็นตัวชี้เป็น (zero-based) ดัชนีขององค์ประกอบของอาร์เรย์นี้แสดงให้เห็นว่าองค์ประกอบในอาร์เรย์ทุกคนจะมีค่ามากกว่าหรือเท่ากับและน้อยกว่าn การใช้สัญกรณ์นี้สามารถกำหนดสูตรได้ดังนี้:0n

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

ซึ่งหมายความว่า (สำหรับการท้าทายนี้) ที่พอยน์เตอร์ได้รับการอัปเดตในลำดับตามลำดับ (เช่น. ดัชนีที่ต่ำกว่าก่อน)

ตัวอย่าง

ลองทำตัวอย่างps = [2,1,4,1,3,2] :

i = 0:องค์ประกอบที่ตำแหน่ง 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:องค์ประกอบที่ตำแหน่ง ps [5] = 2 ชี้ไปที่ 3ps = [4,1,3,1,1,3]

ดังนั้นหลังจากที่หนึ่งในการทำซ้ำของ " ตัวชี้กระโดด " เราได้รับอาร์เรย์[4,1,3,1,1,3]{[4,1,3,1,1,3]}

ท้าทาย

รับอาร์เรย์ที่มีดัชนีเอาท์พุทอาร์เรย์ที่ได้รับจากการวนซ้ำตัวชี้ที่อธิบายไว้ข้างต้นการกระโดดจนกว่าอาร์เรย์จะไม่เปลี่ยนอีกต่อไป

กฎระเบียบ

โปรแกรม / ฟังก์ชั่นของคุณจะรับและส่งคืน / ส่งออกชนิดเดียวกันรายการ / เวกเตอร์ / อาร์เรย์เป็นต้น

  • รับประกันว่าจะไม่ว่างเปล่าและ
  • รับประกันได้ว่าจะมีเพียงรายการ0p<n<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เป็นอินพุตเพิ่มเติมหรือไม่
Kevin Cruijssen

2
@KevinCruijssen ดูการสนทนาเมตานี้
Shaggy

มันแย่มากที่รายการจะต้องได้รับการอัพเดตตามลำดับ; ถ้าพวกเขาสามารถได้รับการปรับปรุงพร้อมกัน Mathematica #[[#]]&~FixedPoint~#&จะมีวิธีการแก้ปัญหา
เกร็กมาร์ติ

คำตอบ:






5

สวิฟต์ , 68 53 ไบต์

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

ลองออนไลน์!

-15 ขอบคุณ BMO


2
ยินดีต้อนรับสู่ PPCG! ฉันไม่รู้สวิฟท์ แต่ใน codegolf.SE ค่าเริ่มต้นคือการยอมรับฟังก์ชั่นแลมบ์ดาซึ่งฉันเดาว่าการปิดจะนับเป็น ดังนั้นนี่อาจเป็น53 ไบต์ (คุณไม่จำเป็นต้องนับf=) เพลิดเพลินกับการพักที่นี่!
ბიმო

ขอบคุณสำหรับการต้อนรับและคำแนะนำที่ฉันใช้เพื่ออัปเดตคำตอบของฉัน
ฌอน

วิธีการเกี่ยวกับการใช้mapแทนที่จะforEachทำให้มันสั้นลง?
jaeyong ร้อง

4

JavaScript (ES6), 41 ไบต์

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

ลองออนไลน์!


Gah! ฉันกำลังรอความท้าทายนี้ที่จะโพสต์เพื่อให้ฉันสามารถโพสต์โซลูชั่นเดียวกันที่แน่นอน: \ Damn ทักษะนินจาของคุณ! : p
Shaggy

2
@shaggy 🐱‍👤 (ควรจะเป็น Ninja Cat ... แต่มันอาจจะไม่ได้รับการสนับสนุนในทุกที่)
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]];}

ปรับเปลี่ยนอินพุตอาร์เรย์แทนที่จะส่งคืนใหม่เพื่อบันทึกไบต์

ล.อีnก.เสื้อชั่วโมง2

ลองออนไลน์

คำอธิบาย:

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

R , 60 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-1st ครั้งที่ฉันคิด หลักฐานจะถูกทิ้งไว้ที่เครื่องอ่าน


1
ฉันคิดว่าคุณสามารถลบ+1และเพียงแค่ใส่ 1 ตามรัฐโพสต์: คุณอาจเลือกที่จะใช้การจัดทำดัชนี 1 ตาม
digEmAll

-4 โดยเปลี่ยนเป็นscan()อินพุต ฉันมักจะรู้สึกว่าscan()การแก้ปัญหาของฉันไม่ดีนักดังนั้นให้จับตาดูวิธีที่สั้นกว่าในการมอบหมายxและnเข้าด้วยกัน: 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[?
Jonathan Frech

1
การแก้ไขล่าสุดควรแก้ไขความล้มเหลวในการทดสอบ ขออภัยในความไม่สะดวกทุกคน
Ethan McCue



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 (จนกระทั่งลู่เข้าหากัน)

  • ภายในแลมบ์ดาภายนอก:

    • {..}/[x;y]ใช้แลมบ์ดาซ้ำมากกว่า x (อัปเดตในแต่ละรอบซ้ำ) และรายการของ y (y คือรายการของค่าและใช้รายการในแต่ละรอบซ้ำ) ในกรณีนี้ arg y คือ!#x(จนกระทั่งนับ x, นั่นคือ, ดัชนีของอาร์เรย์)

    • @[x;y;:;x x y] แก้ไขอาร์เรย์ x (ที่ดัชนี y มอบหมาย x [x [y]])


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.