อายุการใช้งานของ Worm


28

ข้อตกลงและเงื่อนไข

หนอนคือรายการของจำนวนเต็มไม่เป็นลบใด ๆ และขวาสุด (เช่นที่ผ่านมา ) องค์ประกอบที่เรียกว่าหัว ถ้าหัวไม่ได้เป็น 0, หนอนมีส่วนที่ใช้งานซึ่งประกอบด้วยบล็อกที่ต่อเนื่องกันยาวที่สุดขององค์ประกอบที่มีหัวและมีทุกองค์ประกอบอย่างน้อยมีขนาดใหญ่เท่าหัว ส่วนที่ใช้งานลดลงเป็นส่วนที่ใช้งานกับหัว decremented โดย 1 ตัวอย่างเช่นหนอน3 1 2 3 2มีส่วนที่ใช้งานและในส่วนของการใช้งานลดลงคือ2 3 22 3 1

กฎของวิวัฒนาการ

หนอนวิวัฒนาการทีละขั้นตอนดังนี้:

ในขั้นตอน t (= 1, 2, 3, ... )
    หากส่วนหัวเป็น 0: ลบส่วนหัว
    อื่น: แทนที่ส่วนที่ใช้งานอยู่ด้วย t + 1 ที่ต่อกันกับสำเนาของส่วนที่ทำงานลดลง

ความเป็นจริง : หนอนใด ๆ ในที่สุดก็วิวัฒนาการเป็นรายการที่ว่างเปล่าและจำนวนของขั้นตอนในการทำเช่นนั้นเป็นหนอนของอายุการใช้งาน

(รายละเอียดสามารถพบได้ในหลักการหนอนกระดาษโดย LD Beklemishev การใช้ "รายการ" เพื่อหมายถึงลำดับที่แน่นอนและ "หัว" เพื่อหมายถึงองค์ประกอบสุดท้ายของมันถูกนำมาจากบทความนี้ - มันไม่ควรสับสน กับการใช้งานทั่วไปสำหรับรายการเป็นชนิดข้อมูลนามธรรมที่หัวมักจะหมายถึงแรกองค์ประกอบ.)

ตัวอย่าง (ส่วนที่ใช้งานอยู่ในวงเล็บ)

หนอน: 0,1

step    worm
         0(1)
1        0 0 0
2        0 0 
3        0
4           <- lifetime = 4

หนอน: 1,0

step    worm
         1 0
1       (1)
2        0 0 0
3        0 0 
4        0
5           <- lifetime = 5

หนอน: 1,1

step    worm
        (1 1)
1        1 0 1 0 
2        1 0(1) 
3        1 0 0 0 0 0
4        1 0 0 0 0
5        1 0 0 0
...
8       (1) 
9        0 0 0 0 0 0 0 0 0 0
10       0 0 0 0 0 0 0 0 0
...
18       0
19           <- lifetime = 19

หนอน: 2

step    worm
        (2)
1       (1 1)
2        1 0 1 0 1 0
3        1 0 1 0(1)
4        1 0 1 0 0 0 0 0 0
5        1 0 1 0 0 0 0 0
6        1 0 1 0 0 0 0
...
10       1 0(1)
11       1 0 0 0 0 0 0 0 0 0 0 0 0 0
12       1 0 0 0 0 0 0 0 0 0 0 0 0
...
24      (1)
25       0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
...
50       0
51          <- lifetime = 51

หนอน: 2,1

        (2 1)
1        2 0 2 0
2        2 0(2)
3        2 0(1 1 1 1)
4        2 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0
5        2 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0(1 1 1)
6        2 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0
7        2 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0(1 1)
8        2 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0{1 0}^9
...
??          <- lifetime = ??      

หนอน: 3

step    worm
        (3)
1       (2 2)
2       (2 1 2 1 2 1)
3        2 1 2 1 2 0 2 1 2 1 2 0 2 1 2 1 2 0 2 1 2 1 2 0 
4        2 1 2 1 2 0 2 1 2 1 2 0 2 1 2 1 2 0 2 1 2 1(2)
5        2 1 2 1 2 0 2 1 2 1 2 0 2 1 2 1 2 0(2 1 2 1 1 1 1 1 1 1)
6        2 1 2 1 2 0 2 1 2 1 2 0 2 1 2 1 2 0{2 1 2 1 1 1 1 1 1 0}^7
7        2 1 2 1 2 0 2 1 2 1 2 0 2 1 2 1 2 0{2 1 2 1 1 1 1 1 1 0}^6 (2 1 2 1 1 1 1 1 1) 
...      ...
??          <- lifetime = ??


นอกเหนือ

โดยทั่วไปแล้วอายุการใช้งานของหนอนมีขนาดใหญ่มากดังแสดงในขอบเขตล่างต่อไปนี้ในแง่ของลำดับชั้นของฟังก์ชัน f αที่เติบโตอย่างรวดเร็วมาตรฐาน:

worm                lower bound on lifetime
----------------    ------------------------------------------
11..10 (k 1s)       f_k(2)
2                   f_ω(2)
211..1 (k 1s)       f_(ω+k)(2)
2121..212 (k 2s)    f_(ωk)(2)
22..2 (k 2s)        f_(ω^k)(2)
3                   f_(ω^ω)(2)
...
n                   f_(ω^ω^..^ω)(2) (n-1 ωs)  >  f_(ε_0) (n-1)

อย่างน่าทึ่งหนอน [3] มีชีวิตที่เกินจำนวนของเกรแฮม G:

ω ω (2) = f ω 2 (2) = f ω2 (2) = f ω + 2 (2) = f ω + 1 (ฉω + 1 (2)) >> ฉω + 1 (64) > G.


ท้าทายรหัสกอล์ฟ

เขียนฟังก์ชั่นโปรแกรมย่อยที่สั้นที่สุดที่เป็นไปได้ด้วยพฤติกรรมดังต่อไปนี้:

อินพุต : เวิร์มใดก็ได้
ผลลัพธ์ : อายุการใช้งานของหนอน

ขนาดรหัสวัดเป็นไบต์


นี่คือตัวอย่าง (Python เล่นกอล์ฟได้ถึง 167 ไบต์):

from itertools import *
def T(w):
    w=w[::-1]
    t=0
    while w:
        t+=1
        if w[0]:a=list(takewhile(lambda e:e>=w[0],w));a[0]-=1;w=a*(t+1)+w[len(a):]
        else:w=w[1:]
    return t


หมายเหตุ : หาก T (n) เป็นชีวิตของหนอน [N] แล้วอัตราการเติบโตของ T (n) คือประมาณว่าฟังก์ชั่น Goodstein ดังนั้นหากสิ่งนี้สามารถเล่นกอล์ฟได้ต่ำกว่า 100 ไบท์มันอาจให้คำตอบที่ดีที่สุดสำหรับคำถามที่พิมพ์ได้จำนวนมากที่สุด (สำหรับคำตอบนั้นอัตราการเติบโตนั้นสามารถเร่งได้อย่างมหาศาลโดยเริ่มต้นขั้นตอนที่เคาน์เตอร์ที่ n - ค่าเดียวกับเวิร์ม [n] - แทนที่จะเริ่มต้นที่ 0)


ฉันสับสนรหัสของคุณ คุณบอกว่าหัวเป็นขวาสุดองค์ประกอบ แต่ในตัวอย่างหลามของคุณที่คุณปฏิบัติต่อหัวเป็นw[0]ซึ่งเป็นองค์ประกอบ * ซ้ายสุดของรายการที่?

@LegoStormtroopr หากคุณสามารถพิจารณารายการว่ามีซ้ายและขวา หากคุณเพิ่งจะพิจารณาข้อแรกและสุดท้ายคุณสามารถแมปขวาสุดไปสุดหรืออันดับสุดท้ายเมื่ออ่านสตริงเริ่มต้นซึ่งไม่ได้เป็นส่วนหนึ่งของคำถาม แต่ฟังก์ชั่นอินพุตไม่ได้ถูกกำหนดอย่างเคร่งครัดเช่นกัน
Bob

@LegoStormtroopr - จับได้ดี; ฉันแก้ไขโค้ดด้วยการเพิ่มบรรทัดเพื่อย้อนกลับเวิร์มอินพุตซึ่งหัวของมันควรจะอยู่ทางขวา (นั่นคือองค์ประกอบสุดท้ายในรายการ w) เพื่อประสิทธิภาพที่โปรแกรมทำงานบนเวิร์มที่กลับด้าน
res

การเดินทางที่ถูกต้องคำตอบสำหรับ2 1อาจจะมากเกินไปที่จะขอในเวลาที่เหมาะสม แต่การทดสอบที่เป็นประโยชน์ว่าลำดับควรเริ่มต้น(2 1), 2 0 2 0, 2 0 (2), 2 0 (1 1 1 1)...
ปีเตอร์เทย์เลอร์

1
@ThePlasmaRailgun - ถอดความฮาร์วีย์ฟรีดแมน, ตัวเลขที่ได้มาจากฟังก์ชั่นที่ε_0ระดับในลำดับชั้นที่เติบโตอย่างรวดเร็ว (เช่นหนอนชีวิต) จะสังเกตได้อย่างสมบูรณ์ในการเปรียบเทียบกับ TREE (3)
res

คำตอบ:


15

GolfScript ( 56 54 ตัวอักษร)

{-1%0\{\)\.0={.0+.({<}+??\((\+.@<2$*\+}{(;}if.}do;}:L;

การสาธิตออนไลน์

ฉันคิดว่าเคล็ดลับสำคัญที่นี่อาจทำให้หนอนอยู่ในลำดับที่กลับกัน นั่นหมายความว่ามันค่อนข้างกะทัดรัดในการหาความยาวของเซ็กเมนต์ที่แอคทีฟ: .0+.({<}+??(ซึ่ง0มีการเพิ่มเข้าไปในการ์ดเพื่อให้แน่ใจว่าเราพบองค์ประกอบที่เล็กกว่าหัว)


นอกจากการวิเคราะห์อายุการใช้งานของเวิร์มแล้ว ฉันจะแสดงว่าหนอนเป็นage, head tail(เช่นในลำดับที่กลับจากสัญกรณ์คำถามของ) โดยใช้เลขยกกำลังที่จะบ่งบอกถึงการทำซ้ำในหัวและหาง: เช่นเป็น2^32 2 2

แทรก : สำหรับส่วนที่ใช้งานใด ๆ ที่xsมีฟังก์ชั่นf_xsดังกล่าวที่เปลี่ยนไปage, xs 0 tailf_xs(age), tail

พิสูจน์: ไม่มีส่วนที่ใช้งานเคยได้มีเพื่อให้อายุตามเวลาที่เราทุกอย่างก่อนที่จะลบหางเป็นอิสระจากหางและด้วยเหตุนี้ฟังก์ชั่นเฉพาะของที่0xs

บทแทรก : สำหรับเซ็กเมนต์ใด ๆ ที่แอคทีxsฟเวิร์มage, xsจะตายเมื่ออายุf_xs(age) - 1มากขึ้น

พิสูจน์: โดยแทรกก่อนหน้านี้เปลี่ยนเป็นage, xs 0 f_xs(age), []ขั้นตอนสุดท้ายคือการลบสิ่ง0นั้นซึ่งไม่ได้สัมผัสมาก่อนเพราะไม่สามารถเป็นส่วนหนึ่งของส่วนที่ใช้งานได้

ด้วยบทแทรกสองชุดนี้เราสามารถศึกษากลุ่มที่ใช้งานง่ายบางส่วน

สำหรับn > 0,

age, 1^n 0 xs -> age+1, (0 1^{n-1})^{age+1} 0 xs
              == age+1, 0 (1^{n-1} 0)^{age+1} xs
              -> age+2, (1^{n-1} 0)^{age+1} xs
              -> f_{1^{n-1}}^{age+1}(age+2), xs

ดังนั้นf_{1^n} = x -> f_{1^{n-1}}^{x+1}(x+2)(กับกรณีฐานf_{[]} = x -> x+1หรือถ้าคุณต้องการf_{1} = x -> 2x+3) เราจะเห็นว่าf_{1^n}(x) ~ A(n+1, x)ที่Aเป็นฟังก์ชัน Ackermann-Peter

age, 2 0 xs -> age+1, 1^{age+1} 0 xs
            -> f_{1^{age+1}}(age+1)

เพียงพอที่จะรับการจัดการ1 2( 2 1ในสัญกรณ์ของคำถาม):

1, 1 2 -> 2, 0 2 0 2
       -> 3, 2 0 2
       -> f_{1^4}(4), 2
       -> f_{1^{f_{1^4}(4)+1}}(f_{1^4}(4)+1) - 1, []

ดังนั้นการป้อนข้อมูลให้2 1เราคาดว่าการส่งออก A(A(5,4), A(5,4))~

1, 3 -> 2, 2 2
     -> 3, 1 2 1 2 1 2
     -> 4, 0 2 1 2 1 2 0 2 1 2 1 2 0 2 1 2 1 2 0 2 1 2 1 2
     -> 5, 2 1 2 1 2 0 2 1 2 1 2 0 2 1 2 1 2 0 2 1 2 1 2
     -> f_{21212}^4(5) - 1

age, 2 1 2 1 2 -> age+1, (1 1 2 1 2)^{age+1}
               -> age+2, 0 1 2 1 2 (1 1 2 1 2)^age
               -> age+3, 1 2 1 2 (1 1 2 1 2)^age

และฉันสามารถเริ่มเข้าใจว่าทำไมฟังก์ชันนี้โตขึ้นอย่างบ้าคลั่ง


เด็ดมาก ผมคิดว่าโปรแกรมนี้จะให้คำตอบที่ชนะกับโปรแกรมยุติที่สั้นที่สุดที่มีเอาท์พุทขนาดเกินกว่าจำนวนของเกรแฮม (ผู้ชนะปัจจุบันมีรหัส Haskell 63 ไบต์) ตัวอย่างเช่นที่ 55 ไบต์บางอย่างเช่น (เนื่องจากฉันมีแนวโน้มที่จะเกิดข้อผิดพลาดทางไวยากรณ์) 9{-1%0\{\)\.0={.0+.({<}+??\((\+.@<2$*\+}{(;}if.}do;}:L~คำนวณอายุการใช้งานของหนอน [9] ซึ่งเกินจำนวน Graham - และสามารถ golfed เพิ่มเติม
res

9

GolfScript, 69 62 ตัวอักษร

{0:?~%{(.{[(]{:^0=2$0+0=<}{\(@\+}/}{,:^}if;^?):?)*\+.}do;?}:C;

ฟังก์ชันCคาดว่าเวิร์มในสแต็กและแทนที่ด้วยผลลัพธ์

ตัวอย่าง:

> [1 1]
19

> [2]
51

> [1 1 0]
51

Fantastic! แน่นอนคุณสามารถแก้ไขเล็กน้อยเพื่อให้ผู้ชนะแน่นอนสำหรับคำถาม"พิมพ์จำนวนมากที่สุด"
res

ฉันไม่เห็นคุณโพสต์อะไรที่นั่นดังนั้นฉันจึงไปข้างหน้าและโพสต์การดัดแปลงของรหัสนี้เป็นสิ่งที่ฉันเชื่อว่าเป็นคำตอบที่ชนะมี - สมมติว่า*และ^ไม่ได้ถูกใช้เป็นตัวดำเนินการทางคณิตศาสตร์ของทวีคูณ และเลขยกกำลัง แน่นอนถ้าคุณต้องการส่งคำตอบของคุณเอง (อย่างไม่ต้องสงสัย) ให้ฉันจะลบของฉันอย่างมีความสุข
res

7

Ruby - 131 ตัวอักษร

ฉันรู้ว่าสิ่งนี้ไม่สามารถแข่งขันกับโซลูชั่น GolfScript ด้านบนและฉันค่อนข้างแน่ใจว่าสิ่งนี้สามารถลดคะแนนหรือตัวละครได้มากกว่า แต่โดยสุจริตฉันมีความสุขที่ได้แก้ปัญหาที่ไม่ได้รับการแก้ไข ปริศนาที่ยอดเยี่ยม!

f=->w{t=0;w.reverse!;until w==[];t+=1;if w[0]<1;w.shift;else;h=w.take_while{|x|x>=w[0]};h[0]-=1;w.shift h.size;w=h*t+h+w;end;end;t}

วิธีแก้ไขปัญหาก่อนเล่นกอล์ฟของฉันซึ่งได้มาจากข้างต้น:

def life_time(worm)
  step = 0
  worm.reverse!
  until worm.empty?
    step += 1
    if worm.first == 0
      worm.shift
    else
      head = worm.take_while{ |x| x >= worm.first }
      head[0] -= 1
      worm.shift(head.size)
      worm = head * (step + 1) + worm
    end
  end
  step
end

เคล็ดลับทั่วไป: ปัญหากอล์ฟจำนวนมากทำงานกับจำนวนเต็มที่ไม่เป็นลบซึ่งในกรณีนี้if foo==0สามารถตัดif foo<1ได้ ที่สามารถช่วยคุณประหยัดถ่านหนึ่งตัวที่นี่
ปีเตอร์เทย์เลอร์

บังเอิญฉันพบว่ามันน่าทึ่งที่ใช้งานได้ในไม่reverseช้า
ปีเตอร์เทย์เลอร์

มันไม่ได้ มันใช้งานได้ในกรณีทดสอบเท่านั้นเพราะมีกลุ่มที่ใช้งานแบบ palindromic เท่านั้น
Peter Taylor

ขอบคุณสำหรับเคล็ดลับกอล์ฟ @PeterTaylor นอกจากนี้ยังมีการจับที่ดีในการย้อนกลับที่สองที่หายไป ฉันได้เพิ่มเข้าไปแล้วฉันจะพยายามเขียนใหม่อีกวิธีหนึ่งโดยไม่ต้องใช้ย้อนกลับในภายหลัง ฉันค่อนข้างมั่นใจว่าฉันจะได้รับelseอนุประโยคลงไปที่หนึ่งบรรทัดแล้วสลับif..else..endสำหรับคำสั่งที่ประกอบไปด้วยสาม ฉันยังสามารถใช้แลมบ์ดาเพื่อบันทึกตัวละครสองสามตัวฉันคิดว่า
OI

6

Sclipting (43 ตัวอักษร)

글坼가⑴감套擘終長①加⒈丟倘⓶增⓶가采⓶擘❷小終⓷丟❶長貶❷가掊貶插①增復合감不가終終

สิ่งนี้คาดว่าอินพุตเป็นรายการที่คั่นด้วยช่องว่าง ผลลัพธ์นี้ได้คำตอบที่ถูกต้องสำหรับ1 1และ2แต่ใช้เวลา2 1หรือ3นานเกินไปดังนั้นฉันจึงรอให้เสร็จ

ด้วยความเห็น:

글坼 | split at spaces
가⑴ | iteration count = 0

감套 | while:
  擘終長①加⒈丟 | remove zeros from end and add to iteration count
  倘 | if the list is not empty:
    ⓶增⓶ | increment iteration count
    가采⓶擘❷小終⓷丟 | separate out active segment
    ❶長貶❷가掊貶插 | compute reduced active segment
    ①增復合 | repeat reduced active segment and concat
    감 | continue while loop
  不 | else
    가 | stop while loop
  終 | end if
終 | end while

2
ลิงก์ไปยังล่ามจะสะดวก ... นอกจากนี้ 86 ไบต์โดยใช้ UTF-16
ปีเตอร์เทย์เลอร์

@PeterTaylor: ขอบคุณเพิ่มลิงค์ไปยังล่ามไปยังบทความ และใช่อักขระ BMP 43 ตัวแปลเป็น 86 ไบต์ใน UTF-16
Timwi

5

k (83)

worm:{-1+*({x,,(,/((x+:i)#,@[y@&w;(i:~~#y)#0;-1+]),y@&~w:&\~y<*y;1_y)@~*y}.)/(1;|,/x)}

สิ่งนี้อาจจะสามารถเล่นกอล์ฟต่อไปได้เนื่องจากมันเพิ่งจะเกิดขึ้นซ้ำ ๆ

ฟังก์ชั่นวิวัฒนาการขั้นพื้นฐาน{x,,(,/((x+:i)#,@[y@&w;(i:~~#y)#0;-1+]),y@&~w:&\~y<*y;1_y)@~*y}คือ 65 ตัวอักษรและใช้เทคนิคบางอย่างเพื่อหยุดการเพิ่มอายุเมื่อหนอนตาย wrapper จะรวมอินพุตของจำนวนเต็มเดียวให้กับรายการย้อนกลับอินพุต (สั้นกว่าเพื่อเขียนการเกิดซ้ำในแง่ของเวิร์มที่ย้อนกลับจากสัญกรณ์ของคุณ) ถาม Fixpoint เลือกอายุเป็นผลลัพธ์และปรับผลลัพธ์ เพื่อบัญชีสำหรับการเกินกำหนดในรุ่นที่ผ่านมา

ถ้าฉันบังคับและกลับด้วยตนเองมันจะลดลงถึง 80 ({-1+*({x,,(,/((x+:i)#,@[y@&w;(i:~~#y)#0;-1+]),y@&~w:&\~y<*y;1_y)@~*y}.)/(1;x)} )

ตัวอย่างบางส่วน:

  worm 1 1 0
51
  worm 2
51
  worm 1 1
19

น่าเสียดายที่มันอาจไม่ได้ใช้สำหรับพิมพ์ที่ใหญ่ที่สุดจำนวนมากยกเว้นในทางทฤษฎีแล้วมันค่อนข้างช้า จำกัด จำนวนเต็ม 64 บิตและอาจไม่ได้ใช้ประสิทธิภาพหน่วยความจำมากนัก

โดยเฉพาะอย่างยิ่งworm 2 1และworm 3ปั่นป่วน (และอาจจะโยน'wsfull(ออกจากหน่วยความจำ) ถ้าฉันปล่อยให้พวกเขาไป)


ฉันพยายามเรียกใช้โปรแกรมของคุณด้วยล่ามออนไลน์นี้แต่มันไม่แสดงผลลัพธ์ใด ๆ (การส่งไฟล์ข้อความที่มีนามสกุล. k น่าจะเรียกล่าม K) คุณรู้หรือไม่ว่าสิ่งที่ควรทำเพื่อส่งออกไปยัง stdout?
res

ดูเหมือนว่ากำลังทำงานโคนาโคลนโอเพนซอร์ซของ k3 รหัสของฉันเขียนเป็น k4 และไม่น่าจะเข้ากันได้กับ k3 คุณสามารถขอรับสำเนา q / k4 แบบไม่ จำกัด เวลาได้ที่kx.com/software-download.php ; เมื่อคุณได้แล้วให้เริ่ม REPL พิมพ์` to switch from q` ไปยังkและวางรหัสของฉันหรือคุณสามารถบันทึกรหัสของฉันในไฟล์ที่มี.kนามสกุลและโหลดลงในล่าม
Aaron Davies

2

APL (Dyalog Unicode) , 52 ไบต์SBCS

บันทึกแล้ว 7 ไบต์ด้วย @ngn และ @ Adám

0{⍬≡⍵:⍺⋄n←⍺+10=⊃⍵:n1↓⍵⋄n∇∊(⊂1n/-∘1@1¨)@1⊆∘⍵⍳⍨⌊\⍵}⌽

ลองออนไลน์!

คำอธิบาย:

0{...}⌽     A monadic function train. We define a recursive function with two
            arguments: zero (our counter), and the reverse of our input
⍬≡⍵:⍺       Our base case - if our input is an empty list, return our counter
n←⍺+1       Define 'n' as our counter plus 1
0=⊃⍵:n1↓⍵  If the first element of the input is zero, recurse with the tail
            of our input and n
\⍵         Minimum-expand: creates a new list from our input where each element
            is the incremental minimum     
⍳⍨          Applies above to both sides of the index-of function. Index-of returns
            the index of the first occurence of each element in the left-side list.
            At this point, a (reversed) input list of [3 4 5 2 3 4] would result
            in [1 1 1 4 4 4]
⊆∘⍵         Partition, composed with our input. Partition creates sublists of the
            right input whenever the integer list in the left input increases.
            This means we now have a list of sub-lists, with the first element
            being the worm's active segment.
(...)@1    ⍝ Take the active segment and apply the following function train...
-∘1@1¨     ⍝ Subtract 1 from the first element of the active segment
1n/        ⍝ Replicate the resultant list above n+1 times
⊂          ⍝ Enclose the above, so as to keep the original shape of our sub-array
∊          ⍝ Enlist everything above together - this recursively concatenates our
           ⍝ new active segment with the remainder of the list
n∇         ⍝ Recurse with the above and n

ฉันคิดว่า APL จะมีวิธีแก้ปัญหาที่ดีสำหรับเรื่องนี้ไม่ใช่ภาษาที่ใช้อาร์เรย์หรือไม่
ThePlasmaRailgun

1

สกาลา, 198

type A=List[Int]
def T(w:A)={def s(i:Int,l:A):Stream[A]=l match{case f::r=>l#::s(i+1,if(f<1)r
else{val(h,t)=l.span(_>=l(0));List.fill(i)(h(0)-1::h.tail).flatten++t})
case _=>Stream()};s(2,w).length}

การใช้งาน:

scala> T(List(2))
res0: Int = 51

1

K, 95

{i::0;#{~x~,0}{((x@!b),,[;r]/[i+:1;r:{@[x;-1+#x;-1+]}@_(b:0^1+*|&h>x)_x];-1_x)@0=h:*|x:(),x}\x}

.

k)worm:{i::0;#{~x~,0}{((x@!b),,[;r]/[i+:1;r:{@[x;-1+#x;-1+]}@_(b:0^1+*|&h>x)_x];-1_x)@0=h:*|x:(),x}\x}
k)worm 2
51
k)worm 1 1
19
q)worm 1 1 0 0 0 0
635

1

C (gcc) , 396 ไบต์

#define K malloc(8)
typedef*n;E(n e,n o){n s=K,t=s;for(*s=*o;o=o[1];*t=*o)t=t[1]=K;t[1]=e;e=s;}main(c,f,l,j,a)n*f;{n w=K,x=w;for(;l=--c;x=x[1]=K)*x=atoi(f[c]);for(;w&&++l;)if(*w){n v=K,z=v,u=w,t=K;for(a=*v=*w;(u=u[1])&&*u>=*w;*z=*u)z=z[1]=K;for(x=v[1],v=K,*v=a-1,1[u=v]=x;u;u=u[1])w=w[1];for(j=~l;j++;)u=t=E(t,v);for(;(u=u[1])&&(x=u[1])&&x[1];);u[1]=0;w=w?E(w,t):t;}else w=w[1];printf("%d",--l);}

ลองออนไลน์!

ฉันรู้ว่าฉันมาสายมากไปงานปาร์ตี้ แต่ฉันคิดว่าฉันจะลองทำสิ่งนี้ใน C ซึ่งต้องมีการติดตั้งลิสต์ มันไม่ได้เป็นกอล์ฟเลยนอกจากเปลี่ยนตัวระบุทั้งหมดเป็นตัวละครเดียว แต่มันทำหน้าที่!

สรุปแล้วฉันมีความสุขมากเมื่อพิจารณาว่านี่เป็นโปรแกรม C / C ++ ตัวที่ 3 ที่ฉันเคยเขียน


คุณต้องการรายการที่ลิงก์หรือไม่ ทำไมไม่จัดสรรเฉพาะอาร์เรย์ เนื่องจากนี่คือรหัสกอล์ฟคุณไม่จำเป็นต้องกังวลกับการปลดปล่อยพวกเขาเมื่อเสร็จสิ้น คุณอาจจะได้สามารถที่จะหาวิธีที่จะเก็บไว้ในสแต็คโทร (ไม่แน่ใจ)
dfeuer

นอกจากนี้คุณไม่จำเป็นต้องมีฟังก์ชั่นหลัก เพียงแค่เขียนฟังก์ชั่นที่รับเวิร์มเป็นอาร์กิวเมนต์และคืนค่าอายุการใช้งาน เวิร์มอาจเป็นอาร์เรย์และความยาวหรืออาจเป็นอาร์เรย์ที่ลงท้ายด้วยจำนวนลบ
dfeuer

1

Haskell , 84 ไบต์

(0!).reverse
n!(x:y)|x<1=(n+1)!y|(a,b)<-span(>=x)y=(n+1)!(([-1..n]*>x-1:a)++b)
n!_=n

ลองออนไลน์!

ขอบคุณ @xnor สำหรับสองไบต์

ฉันรู้สึกว่าควรจะมีวิธีที่ดีในการแยกปัจจัยที่เพิ่มขึ้นร่วมกัน แต่ฉันยังไม่พบข้อสรุปสั้น ๆ


1
สองสนามกอล์ฟขนาดเล็ก : ตรวจสอบรายการที่ว่างเปล่าที่สองและเลื่อนnลง 1
xnor

I also think there should be a way to not write (n+1)! twice, but my attempt only tied.
xnor


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