นี่คือวิธีที่เรากลิ้ง


18

Piet เป็นภาษาการเขียนโปรแกรมที่น่าสนใจด้วยเหตุผลหลายประการ วันนี้เราจะเน้นไปที่เหตุผลหนึ่งข้อ: คำสั่งการหมุน คำสั่ง roll นั้นมาจาก PostScript และเป็นวิธีที่มีประสิทธิภาพในการจัดการกับ stack

คำสั่ง roll จะแสดงองค์ประกอบสองอันดับแรกของสแต็กและใช้เป็นพารามิเตอร์ เราจะเรียกค่าแรกโผล่และครั้งที่สองturns depthการหมุนไปยังความลึก n จะใช้องค์ประกอบสูงสุดของสแต็กทำให้เป็นองค์ประกอบที่ n ในสแต็กและย้ายองค์ประกอบแต่ละรายการที่อยู่ด้านบนขึ้นมา หากturns เป็นลบจะกระทำในทิศทางตรงกันข้าม นั่นคือองค์ประกอบที่ n จะถูกย้ายไปด้านบนและองค์ประกอบอื่น ๆ จะถูกย้ายลง นี่เป็นabs(turns)ครั้งซ้ำแล้วซ้ำอีก

ท้าทาย

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

กฎระเบียบ

  • อินพุตและเอาต์พุตอาจอยู่ในรายการอาร์เรย์สตริงที่มีตัวคั่นผ่านในองค์ประกอบหนึ่งครั้งหรือรูปแบบอื่นที่สมเหตุสมผล เอาต์พุตจะต้องอยู่ในรูปแบบเดียวกับอินพุต
  • depth จะไม่เป็นลบและจะไม่มากกว่าความยาวของสแต็ก
  • สแต็คอินพุตจะมีองค์ประกอบอย่างน้อยสององค์ประกอบเสมอ
  • นี่คือดังนั้นคำตอบที่สั้นที่สุดในแต่ละภาษาจะชนะ ดังนั้นฉันจะไม่รับคำตอบ
  • ช่องโหว่มาตรฐานเป็นสิ่งต้องห้าม

กรณีทดสอบ

in:  out:
2    
4    
1    3
2    4
3    1
4    2
5    5
6    6

in:  out:
-2   
3
1    2
2    3
3    1

in:  out:
-42
0
1    1
2    2
3    3
4    4
5    5

2
คำตอบที่สั้นที่สุดในแต่ละภาษาจะชนะนั่นไม่ใช่การทำงานของ [code-golf] คำตอบที่สั้นที่สุดชนะ ระยะเวลา
mbomb007


7
ฉันรู้สึกผิดหวังมากที่สิ่งนี้ไม่ได้เกี่ยวข้องกับการหมุนของ
ริค

2
@ mbomb007 ฉันไม่เห็นว่าในคำอธิบายแท็กหรือในการค้นหาเมตาอย่างรวดเร็วดังนั้นฉันจึงไม่คิดว่าเป็นเช่นนั้น
Mike Bufardeci

2
@ mbomb007 หากคุณต้องการให้ฉันเปลี่ยนแปลงโปรดระบุอาร์กิวเมนต์บางอย่างนอกเหนือจากการพูดว่า "คุณผิดและฉันพูดถูก" ซ้ำแล้วซ้ำอีก มีแบบอย่างสำหรับสิ่งนี้ซึ่งคุณถูกไล่ออกและไม่มีที่ไหนพูดได้ว่าความท้าทายต้องการผู้ชนะเพียงคนเดียวหรือต้องยอมรับคำตอบ
Mike Bufardeci

คำตอบ:


8

Haskell , 64 62 ไบต์

แก้ไข: -2 ไบต์: @xnor เห็นบางสิ่งที่ฉันคิดผิดไป

rใช้และส่งคืนรายการInts

r(t:d:l)|d<1=l|(x,y)<-d%l,(z,w)<-mod t d%x=w++z++y
(%)=splitAt

ลองออนไลน์!

splitAt n lแยกรายการlที่ดัชนีn, modคำนวณที่เหลือของส่วน++concatenates รายการ


1
ฉันคิดว่าคุณสามารถตัด 2 ไบต์โดยกำหนด(%)=splitAtมัด
xnor

@xnor โอ้ฉันเชื่อว่าตัวเองไม่สามารถทำงานได้
Ørjan Johansen

8

JavaScript (ES6), 49 47 ไบต์

(t,d,...a)=>a.splice(t=(t%d+d)%d,d-t).concat(a)

แก้ไข: บันทึก 2 ไบต์ด้วย @Shaggy โดยการใช้องค์ประกอบสแต็กเป็นพารามิเตอร์แยก คำอธิบาย:

  • เมื่อถึงคราวที่มีความลึกหลายระดับไม่มีอะไรเกิดขึ้น ขั้นตอนแรกคือการคำนวณความลึกแบบโมดูโล เนื่องจาก JavaScript รู้วิธีการคำนวณส่วนที่เหลือฉันจึงต้องทำสองขั้นตอน
  • เทิร์นของการ1ย้ายองค์ประกอบด้านบนไปยังdepthองค์ประกอบ การเลี้ยวของการ2เคลื่อนย้ายองค์ประกอบสองอันดับแรก ฯลฯ อย่างไรก็ตามคุณสามารถบรรลุสิ่งนี้ได้โดยการย้ายองค์ประกอบระหว่างการเลี้ยวและความลึกไปด้านหน้า spliceลบองค์ประกอบเหล่านั้นและconcatผนวกเข้ากับองค์ประกอบที่เหลืออยู่ (ฉันสามารถใช้ความเข้าใจอาร์เรย์แทนได้เนื่องจากมีความยาวเท่ากัน)
  • ต่างจากsliceพารามิเตอร์ตัวที่สองถึงspliceคือจำนวนองค์ประกอบที่จะลบ

ไม่(t%d+d)%dเหมือนกันt%dใช่ไหม
ลุค

@ ลุคไม่ใช่%เป็นสิ่งที่เหลืออยู่ดังนั้นจึงให้คำตอบเชิงลบเมื่อtเป็นลบ
Neil

คุณสามารถบันทึก 2 ไบต์โดยใช้(t,d,...a)=>เป็นกฎที่อนุญาตให้ป้อนข้อมูลในองค์ประกอบหนึ่งครั้ง
Shaggy

@ ขอบคุณ Shaggy ฉันไม่ได้สังเกตเห็นว่า
Neil

7

CJam, 31 ไบต์

)\):N@\,0a|={NW*1$1$>)\+@@<\+}*

อินพุตและเอาต์พุตเป็นอาร์เรย์บนสแต็กโดยมีองค์ประกอบสุดท้ายแสดงถึงด้านบนของสแต็ก

การติดตามสแต็ก:

                   e# Stack:                [6 5 4 3 2 1 4 2]
)                  e# Take out first value: [6 5 4 3 2 1 4] 2
\                  e# Swap:                 2 [6 5 4 3 2 1 4]
)                  e# Take out first value: 2 [6 5 4 3 2 1] 4
:N                 e# Store in N:           2 [6 5 4 3 2 1] 4; N=4
@                  e# Rotate:               [6 5 4 3 2 1] 4 2
\                  e# Swap:                 [6 5 4 3 2 1] 2 4
,                  e# Range:                [6 5 4 3 2 1] 2 [0 1 2 3]
0                  e# Push 0:               [6 5 4 3 2 1] 2 [0 1 2 3] 0
a                  e# Wrap in array:        [6 5 4 3 2 1] 2 [0 1 2 3] [0]
|                  e# Logical or:           [6 5 4 3 2 1] 2 [0 1 2 3]
                   e# (This will replace an empty array with [0] to handle a special case of n=0)
=                  e# Get array value:      [6 5 4 3 2 1] 2
{NW*1$1$>)\+@@<\+} e# Push block:           [6 5 4 3 2 1] 2 {NW*1$1$>)\+@@<\+}
*                  e# Preform n times:      [6 5 4 3 2 1]
  N                e# Push N:               [6 5 4 3 2 1] 4
  W*               e# Negate:               [6 5 4 3 2 1] -4
  1$               e# Copy element 1 back:  [6 5 4 3 2 1] -4 [6 5 4 3 2 1]
  1$               e# Copy element 1 back:  [6 5 4 3 2 1] -4 [6 5 4 3 2 1] -4
  >                e# Slice a[-4:]          [6 5 4 3 2 1] -4 [4 3 2 1]
  )                e# Take first value:     [6 5 4 3 2 1] -4 [4 3 2] 1
  \                e# Swap:                 [6 5 4 3 2 1] -4 1 [4 3 2]
  +                e# Append:               [6 5 4 3 2 1] -4 [1 4 3 2]
  @@               e# Rotate twice:         [1 4 3 2] [6 5 4 3 2 1] -4
  <                e# Slice a[:-4]:         [1 4 3 2] [6 5]
  \                e# Swap:                 [6 5] [1 4 3 2]
  +                e# Append:               [6 5 1 4 3 2]
e# Preform the block again:                 [6 5 2 1 4 3]

6

Mathematica, 58 50 ไบต์

แก้ไข: ขอบคุณ Martin Ender สำหรับการบันทึก 8 ไบต์

Take[x={##3},#2]~RotateLeft~#~Join~Drop[x,#2]&@@#&

คำอธิบาย:

ฟังก์ชั่นบริสุทธิ์ซึ่งคาดว่ารายการที่จุดเริ่มต้นของรายการแสดงถึงด้านบนของสแต็ค Take[x={##3},#2]~RotateLeft~#~Join~Drop[x,#2]&เราผ่านองค์ประกอบของรายการลงในฟังก์ชั่นที่บริสุทธิ์ xมีการตั้งค่าลำดับขององค์ประกอบที่เริ่มต้นด้วยอาร์กิวเมนต์ที่สาม. แล้วเราหมุนครั้งแรก#2(อาร์กิวเมนต์ที่สอง) องค์ประกอบของxไปทางซ้าย#(อาร์กิวเมนต์แรก) ครั้งจากนั้นที่เหลือของJoinx

มันจะประหยัด3ไบต์ถ้าเราเพิ่งผ่านองค์ประกอบสแต็กในฐานะที่เป็นข้อโต้แย้งไปยังฟังก์ชั่นโดยตรงมากกว่าที่จะอยู่ในรายการเริ่มแรก แต่จากนั้นรูปแบบอินพุตและเอาต์พุตจะไม่ตรงกัน

ทางออกเดิม:

#/.{t_,d_,x___}:>{x}~Take~d~RotateLeft~t~Join~Drop[{x},d]&

มีบางสิ่งที่น่าพอใจจริงๆเกี่ยวกับฟังก์ชันโซ่มัดนี้ แทนที่รายการที่มีองค์ประกอบแรกt, องค์ประกอบที่สองdและองค์ประกอบที่เหลือxที่มีผลการหมุนครั้งแรกdองค์ประกอบของ{x}ไปทางซ้ายครั้งและเข้าร่วมในองค์ประกอบที่เหลืออยู่ของt{x}


1
ดี! คุณสามารถบันทึก 3 ไบต์โดยใช้คำนำหน้าฟังก์ชั่นหนึ่งไบต์±แทรกกฎการแทนที่และอีก 1 ไบต์โดยใช้ประโยชน์TakeDropดังนี้: ±{t_,d_,x___}:=#~RotateLeft~t~Join~#2&@@{x}~TakeDrop~d
Greg Martin

ฉันแค่แสดงความคิดเห็นเช่นเดียวกับเกร็ก แต่จริงๆแล้วคุณสามารถสั้นกว่านี้ได้ ทำฟังก์ชัน Variadic ที่ไม่มีชื่อ (แม้ว่าจะเป็นบิตหลบเพราะใช้อินพุต...&[1, 1, 3, 4]และส่งคืน{3, 4}หรือทำด้วยตนเองด้วยการApplyเริ่มต้น: Take[x={##3},#2]~RotateLeft~#~Join~Drop[x,#2]&@@#&(เพื่อให้ชัดเจนคำแนะนำแรกของฉันจะข้าม@@#&)
Martin Ender

5

Ruby, 40 ไบต์

x=->s{n,d,*s=s;s[0,d]=s[0,d].rotate n;s}

ลองออนไลน์!

รับอินพุตเป็นรายการส่งคืนรายการ ความจริงที่ว่ามีrotateอยู่แล้วภายในซึ่งสามารถจัดการกับการหมุนทั้งบวกและลบทำให้เรื่องนี้เล็กน้อย


5

Python, 141 98 87 74 ไบต์

บันทึก 11 ไบต์ด้วย @Cole

def f(s):*s,d,t=s;n=len(s)-d;return s*0**d or s[:n]+s[-t%d-d:]+s[n:-t%d-d]

รับอินพุตเป็นรายการโดยที่องค์ประกอบสุดท้ายคือด้านบนสุดของสแต็ก

ใช้เคล็ดลับ0ⁿเพื่อกรองตัวดำเนินการโมดูโลที่ปรับความลึกเป็นศูนย์และเครื่องหมายงูใหญ่เพื่อกำหนดส่วนของรายการที่ต้องสับ


ทำไมไม่ลองดูf(s,t,d)ล่ะ?
โคล

@ Cold ขอบคุณสำหรับการเปิดออก! อย่างไรก็ตามฉันไม่เห็นความหมายของคุณf(s,t,d)(อินพุตคือทั้งสแต็ค)
Uriel

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

คุณสามารถบันทึก 1 r=-t%d-dไบต์ด้วย นอกจากนี้การแทนที่s*0**dด้วยการs*(d<1)รักษาจำนวนไบต์ แต่อาจปรับปรุงความสามารถในการอ่านได้ (ไม่ใช่ว่าเป็นเป้าหมาย) ฉันไม่รู้ว่า0**0==1ใน Python นั้นเป็นสิ่งที่น่าสนใจ
Ben Frankel

@BenFrankel ฉันไม่สามารถบันทึก-t%d-dเป็นค่าได้ (อย่างที่ฉันเคยทำมาก่อน) เพราะเมื่อdใด0นี่จะทำให้เกิดข้อยกเว้นการหารโดยศูนย์
Uriel

3

JavaScript ES6, 109 92 ไบต์

x=>{for(i=x.shift(),i=i>0?i:-i,j=x.shift();i-->0&&j>0;)x=x.splice(j,1).concat(x);return x}

ลองออนไลน์!

รับอินพุตในรูปแบบของอาร์เรย์ของจำนวนเต็ม
นอกจากนี้ยังมีการนับลูกศร: P

คำอธิบาย:

รหัสใช้ฟังก์ชัน shift เพื่อแยกสององค์ประกอบแรกของรายการ

จากนั้นจะได้รับค่าสัมบูรณ์ขององค์ประกอบแรกซึ่งก็คือจำนวนรอบ

เนื่องจาก Javascript มีการทำดัชนีเป็นศูนย์ดัชนีความลึกต้องลดลง 1

หากดัชนีความลึกเป็น 0 หรือ 1 จะไม่มีอะไรเปลี่ยนแปลง แต่เนื่องจากการลดลงดัชนี 0 จะทำให้เกิดการเปลี่ยนแปลง ดังนั้นออกจากลูปถ้าดัชนีความลึกไม่ <= 0

ฟังก์ชั่น splice (a, b) ส่งคืนอาเรย์ย่อยของความยาว b ด้วยดัชนีเริ่มต้น a จากอาเรย์และออกจากอาเรย์เดิมโดยไม่มีองค์ประกอบเหล่านั้น

เมื่อเชื่อมต่อกับส่วนที่เหลือของอาเรย์ดั้งเดิมนี่เป็นการหมุนครั้งเดียวของอาเรย์ที่ดัชนีความลึก

ด้วยการดำเนินการนี้ n ครั้งโดยที่ n คือจำนวนรอบอาเรย์ที่เกิดขึ้นเป็นผลมาจากผู้ดำเนินการม้วน



2

TI-Basic, 141 150 ไบต์ (ไม่ใช่การเข้ารหัส)

Prompt L1
L1(1→T
L1(2→D
seq(L1(C),C,3,dim(L1→L1
If TD>0
Then
For(A,1,T
L1(1→B
For(C,2,D
L1(C→L1(C–1
End
B→L1(D
End
End
If TD<0
Then
For(A,1,-T
L1(D→B
For(C,D,2,-1
L1(C–1→L1(C
End
B→L1(1
End
End
L1

แก้ไข: ตัวพิมพ์ใหญ่ที่ความลึกเป็นศูนย์ (+9 ไบต์)

TI-Basic ไม่สนับสนุนรายการที่มีความยาว 0 รายการดังนั้นวิธีนี้จะใช้ไม่ได้กับการป้อนข้อมูลแบบสองความยาว

คำอธิบาย:

Prompt L1                # 4 bytes, input list
L1(1→T                   # 7 bytes, turns
L1(2→D                   # 7 bytes, depth
seq(L1(C),C,3,dim(L1→L1   # 18 bytes, remove turns and depth from list
If TD>0                  # 6 bytes, if turns is positive and depth is nonzero (can't be negative)
Then                     # 2 bytes
For(A,1,T                # 7 bytes, do this 'turns' times
L1(1→B                    # 7 bytes, backup the first item
For(C,2,D                # 7 bytes, shuffle the rest along
L1(C→L1(C–1               # 12 bytes
End                      # 2 bytes
B→L1(D                   # 7 bytes, restore the backup to where it should be
End                      # 2 bytes
End                      # 2 bytes
If TD<0                  # 6 bytes, if T is negative and D is nonzero
Then                     # 2 bytes
For(A,1,-T               # 8 bytes, do this -'turns' times
L1(D→B                   # 7 bytes, backup the Dth item
For(C,D,2,-1             # 10 bytes, shuffle the items the other way
L1(C–1→L1(C              # 12 bytes
End                      # 2 bytes
B→L1(1                   # 7 bytes, restore backup to where it belongs
End                      # 2 bytes
End                      # 2 bytes
L1                       # 2 bytes, implicitly return

ฉันคิดว่าคุณต้องใช้รหัสเพื่อจัดการกับกรณีรายการ 2 องค์ประกอบเช่นกัน seq(ขณะนี้มันจะเกิดข้อผิดพลาดที่
lirtosiast

1

แบตช์ 163 ไบต์

@set s=
@set r=
@set/ad=%2,t=(%1%%d+d)%%d
:l
@shift
@set/af=t-=1,f^^=d-=1
@if %f% lss 0 (set r=%r% %2)else set s=%s% %2
@if not "%3"=="" goto l
@echo%r%%s%

รับอินพุตเป็นพารามิเตอร์บรรทัดคำสั่งและแสดงรายการคั่นด้วยช่องว่าง พารามิเตอร์ระหว่างtและdถูกแยกลงในrตัวแปรเพื่อให้สามารถผนวกเข้ากับsตัวแปรซึ่งได้รับพารามิเตอร์อื่นทั้งหมด

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