Đây là cách chúng tôi lăn


18

Piet là một ngôn ngữ lập trình thú vị vì một số lý do. Hôm nay chúng ta sẽ tập trung vào một lý do: lệnh roll . Lệnh roll ban đầu là từ PostScript và là một cách mạnh mẽ để thao tác ngăn xếp.

Lệnh roll xuất hiện hai phần tử trên cùng của ngăn xếp và sử dụng chúng làm tham số. Chúng tôi sẽ gọi giá trị đầu tiên xuất hiện turnsvà giá trị thứ hai depth. Việc chuyển sang độ sâu n sẽ lấy phần tử trên cùng của ngăn xếp, biến nó thành phần tử thứ n trong ngăn xếp và di chuyển từng phần tử bên trên nó lên trên một phần tử. Nếu turns là tiêu cực, điều này được thực hiện theo hướng ngược lại. Đó là, phần tử thứ n được di chuyển lên trên cùng và các phần tử khác được di chuyển xuống. Đây là lần lặp lại abs(turns).

Thử thách

Viết chương trình hoặc hàm nhận trong ngăn xếp và trả về ngăn xếp đó sau khi thực hiện cuộn.

Quy tắc

  • Đầu vào và đầu ra có thể ở trong một danh sách, mảng, chuỗi có dấu phân cách, được truyền vào một phần tử tại một thời điểm hoặc bất kỳ định dạng hợp lý nào khác. Đầu ra phải có cùng định dạng với đầu vào.
  • depth sẽ không bao giờ âm và sẽ không bao giờ lớn hơn chiều dài của ngăn xếp.
  • Ngăn xếp đầu vào sẽ luôn chứa ít nhất hai yếu tố.
  • Đây là vì vậy câu trả lời ngắn nhất trong mỗi ngôn ngữ sẽ thắng. Như vậy, tôi sẽ không chấp nhận một câu trả lời.
  • Sơ hở tiêu chuẩn bị cấm.

Các trường hợp thử nghiệm

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
Câu trả lời ngắn nhất trong mỗi ngôn ngữ sẽ thắng , đó không phải là cách [code-golf] hoạt động. Câu trả lời ngắn nhất thắng. Giai đoạn = Stage.
mbomb007


7
Tôi đã rất thất vọng vì điều này không hề liên quan đến việc lăn lộn
Christopher

2
@ mbomb007 Tôi không thấy điều đó trong phần mô tả thẻ hoặc trong một tìm kiếm nhanh trên meta vì vậy tôi không nghĩ đó là trường hợp.
Mike Bufardeci

2
@ mbomb007 Nếu bạn muốn tôi thay đổi nó, vui lòng cung cấp một số loại đối số khác ngoài việc nói "bạn sai và tôi đúng" nhiều lần. Có tiền lệ cho điều này, điều mà bạn đã loại bỏ, và không nơi nào nói rằng các thách thức đòi hỏi chính xác một người chiến thắng hoặc câu trả lời phải được chấp nhận.
Mike Bufardeci

Câu trả lời:


8

Haskell , 64 62 byte

Chỉnh sửa: -2 byte: @xnor đã thấy điều gì đó tôi nghĩ sai.

rmất và trả về một danh sách Ints.

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

Hãy thử trực tuyến!

splitAt n lchia một danh sách ltại chỉ mục n, modtính toán phần còn lại của phân chia, ++danh sách nối.


1
Tôi nghĩ bạn có thể cắt 2 byte bằng cách xác định (%)=splitAtinfix.
xnor

@xnor Ồ, bằng cách nào đó tôi đã tự thuyết phục bản thân rằng nó sẽ không hoạt động
Ørjan Johansen

8

JavaScript (ES6), 49 47 byte

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

Chỉnh sửa: Đã lưu 2 byte nhờ @Shaggy bằng cách lấy các phần tử ngăn xếp làm tham số riêng. Giải trình:

  • Khi lần lượt là bội số của độ sâu, không có gì xảy ra. Do đó, bước đầu tiên là tính toán độ sâu modulo lần lượt. Vì JavaScript chỉ biết cách tính phần còn lại, tôi phải làm điều này theo hai bước.
  • Một lượt 1di chuyển phần tử hàng đầu đến depthphần tử. Một lượt 2di chuyển hai yếu tố hàng đầu, vv Tuy nhiên, bạn cũng có thể đạt được điều này bằng cách di chuyển các yếu tố giữa lượt và độ sâu về phía trước. spliceloại bỏ các yếu tố đó và concatđưa chúng vào các yếu tố còn lại. (Tôi có thể đã sử dụng một sự hiểu biết mảng thay vì nó có cùng độ dài.)
  • Không giống như slice, tham số thứ hai splicelà số lượng phần tử cần loại bỏ.

Không (t%d+d)%dgiống như t%d?
Luke

@Luke Không, %là phần còn lại, vì vậy nó đưa ra câu trả lời phủ định khi tâm.
Neil

Bạn có thể lưu 2 byte bằng cách sử dụng (t,d,...a)=>làm quy tắc cho phép đầu vào được truyền vào một phần tử tại một thời điểm.
Shaggy

@Shaggy Cảm ơn, tôi đã không nhận thấy điều đó.
Neil

7

CJam, 31 byte

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

Đầu vào và đầu ra là các mảng trên ngăn xếp, với phần tử cuối cùng đại diện cho đỉnh của ngăn xếp.

Dấu vết ngăn xếp:

                   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

Toán học, 58 50 byte

Chỉnh sửa: Cảm ơn Martin Ender vì đã lưu 8 byte.

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

Giải trình:

Hàm thuần túy dự kiến ​​một danh sách trong đó phần đầu của danh sách biểu thị phần trên cùng của ngăn xếp. Chúng tôi chuyển các phần tử của danh sách vào hàm thuần túy Take[x={##3},#2]~RotateLeft~#~Join~Drop[x,#2]&. xđược đặt thành chuỗi các phần tử bắt đầu bằng đối số thứ ba. Sau đó, chúng ta xoay các phần tử #2(đối số thứ hai) đầu tiên xsang trái #(đối số thứ nhất) lần sau, sau đó Joincác phần tử còn lại của x.

Nó sẽ tiết kiệm 3byte nếu chúng ta chỉ truyền trực tiếp các phần tử ngăn xếp dưới dạng đối số cho hàm thay vì nằm trong danh sách, nhưng sau đó các định dạng đầu vào và đầu ra sẽ không khớp.

Giải pháp ban đầu:

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

Có một cái gì đó thực sự thỏa mãn về chuỗi chức năng này. Thay thế một danh sách bằng phần tử tthứ nhất d, phần tử thứ hai và các phần tử còn lại xbằng kết quả của việc xoay các dphần tử đầu tiên {x}sang tthời gian bên trái và nối các phần tử còn lại của {x}.


1
Đẹp! Bạn có thể lưu 3 byte bằng cách sử dụng chức năng tiền tố một byte ±bao gồm quy tắc thay thế và 1 byte khác bằng cách khai thác TakeDropnhư sau: ±{t_,d_,x___}:=#~RotateLeft~t~Join~#2&@@{x}~TakeDrop~d
Greg Martin

Tôi vừa mới nhận xét điều tương tự như Greg, nhưng bạn thực sự có thể đi ngắn hơn nữa. Hoặc là tạo một hàm matrixdic không tên (mặc dù đó là một chút tinh ranh vì nó lấy đầu vào ...&[1, 1, 3, 4]và trả về {3, 4}hoặc làm điều đó bằng tay Applyngay từ đầu: Take[x={##3},#2]~RotateLeft~#~Join~Drop[x,#2]&@@#&(để rõ ràng, đề xuất đầu tiên của tôi bỏ qua @@#&.)
Martin Ender

5

Ruby, 40 byte

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

Hãy thử trực tuyến!

Lấy đầu vào là một danh sách, trả về một danh sách. Thực tế là tích hợp sẵnrotate tồn tại tích hợp có thể xử lý cả xoay tích cực và tiêu cực làm cho điều này trở nên tầm thường.


5

Con trăn, 141 98 87 74 byte

11 byte được lưu nhờ @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]

Nhận đầu vào dưới dạng danh sách, trong đó phần tử cuối cùng là đỉnh của ngăn xếp.

Sử dụng mẹo 0ⁿ để lọc toán tử modulo điều chỉnh ký hiệu độ sâu và độ sâu của python để xác định phần của danh sách cần cắt.


Tại sao không chỉ lấy f(s,t,d)?
cole

@Cole Cảm ơn bạn đã giải nén! Tuy nhiên, tôi không thể hiểu ý của bạn là gì f(s,t,d)(đầu vào là toàn bộ ngăn xếp).
Uriel

ý tưởng tuyệt vời cho việc giải nén, mặc dù tôi không nghĩ bạn nên tin tưởng vào điều đó (tôi đã đề nghị chỉ lấy các biến riêng biệt). Thông số kỹ thuật đầu vào dường như cho phép bạn lấy độ sâu và biến thành các biến riêng biệt từ ngăn xếp: "Đầu vào và đầu ra có thể nằm trong một danh sách, mảng, chuỗi có dấu phân cách, được truyền trong một phần tử tại một thời điểm hoặc bất kỳ định dạng hợp lý nào khác. Đầu ra phải có cùng định dạng với đầu vào. "
cole

Bạn có thể lưu 1 byte với r=-t%d-d. Ngoài ra, thay thế s*0**dbằng s*(d<1)duy trì số byte nhưng có thể cải thiện khả năng đọc (không phải đó là mục tiêu). Tôi không biết rằng 0**0==1trong Python, điều đó thật thú vị.
Ben Frankel

@BenFrankel tôi không thể tiết kiệm -t%d-dnhư một giá trị (như tôi đã làm trước đó), bởi vì khi dđược 0điều này sẽ kích hoạt một bộ phận-by-zero ngoại lệ.
Uriel

3

JavaScript ES6, 109 92 byte

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}

Hãy thử trực tuyến!

Nhận đầu vào dưới dạng một mảng các số nguyên.
Cũng có số đếm đến mũi tên: P

Giải trình:

Mã sử ​​dụng hàm shift để trích xuất hai phần tử đầu tiên của danh sách.

Sau đó, nó nhận được giá trị tuyệt đối của phần tử đầu tiên, đó là số lượt.

Vì Javascript không được lập chỉ mục, nên chỉ số độ sâu cần giảm đi 1.

Nếu chỉ số độ sâu là 0 hoặc 1, không có gì thay đổi, nhưng do giảm, chỉ số 0 sẽ gây ra thay đổi. Do đó thoát khỏi vòng lặp nếu chỉ số độ sâu không <= 0.

Hàm splice (a, b) trả về mảng con có độ dài b với chỉ số bắt đầu a từ mảng và rời khỏi mảng ban đầu mà không có các phần tử đó.

Khi được nối với phần còn lại của mảng ban đầu, đây là một vòng quay duy nhất của mảng ở chỉ số độ sâu.

Bằng cách thực hiện thao tác này n lần, trong đó n là số lượt, mảng kết quả là kết quả của toán tử cuộn.



2

TI-Basic, 141 150 byte (không lọc)

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

Chỉnh sửa: trường hợp cố định trong đó độ sâu bằng 0 (+9 byte)

TI-Basic không hỗ trợ danh sách có độ dài 0, vì vậy phương pháp này sẽ không hiệu quả với đầu vào hai chiều dài.

Giải trình:

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

Tôi nghĩ bạn cũng cần mã để xử lý trường hợp danh sách 2 phần tử; Hiện tại nó sẽ báo lỗi tại seq(.
lirtosiast

1

Hàng loạt, 163 byte

@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%

Lấy đầu vào làm tham số dòng lệnh và đưa ra danh sách được phân tách bằng dấu cách. Các tham số giữa tdđược trích xuất thành rbiến để chúng có thể được thêm vàos biến, nhận tất cả các tham số khác.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.