Chức năng clipboard: sao chép


17

Thử thách này có liên quan đến một số tính năng của ngôn ngữ MATL, như là một phần của sự kiện Ngôn ngữ của tháng 5 năm 2018 . Liên kết thách thức : Chức năng clipboard: dán .


Giới thiệu

MATL có một số bảng ghi , nơi bạn có thể lưu trữ các giá trị (bản sao) để được truy xuất sau (dán). Một số clipboard là tự động , có nghĩa là sao chép được tự động kích hoạt bởi các sự kiện nhất định. Thử thách này tập trung vào một trong các clipbards tự động, được gọi là clipboard bảng chức năng đầu vào , hoặc đơn giản là chức năng clipboard .

Bảng tạm này lưu trữ các đầu vào cho bốn cuộc gọi gần đây nhất tới các chức năng nhận đầu vào thông thường. Các hàm thông thường là loại hàm phổ biến nhất trong MATL. Nhập liệu có nghĩa là chức năng lấy ít nhất một đầu vào (các chức năng không lấy bất kỳ đầu vào nào không được xem xét bởi bảng tạm thời của chức năng).

Điều này được giải thích tốt nhất với các ví dụ sau, sử dụng hai hàm bình thường:

  • +, xuất hiện hai số từ ngăn xếp và đẩy tổng của chúng.
  • U, hiện ra một số và đẩy hình vuông của nó.

Ví dụ 1 :

3 2 + 6 + 12 4 U + +

tạo ra kết quả 39. Mã được diễn giải như sau:

  • Số chữ như 3hoặc 12được đẩy vào ngăn xếp
  • Các chức năng như +bật đầu vào của chúng và đẩy đầu ra của chúng lên ngăn xếp.

Các hàm gọi, theo thứ tự thời gian, là:

  1. 3 2 + cho 5
  2. 5 6 + cho 11
  3. 4 U cho 16
  4. 12 16 + 28
  5. 11 28 +cho 39.

Bảng tạm có thể được xem như một danh sách gồm bốn danh sách. Mỗi danh sách bên trong chứa các đầu vào cho một cuộc gọi chức năng, với hầu hết các cuộc gọi gần đây đầu tiên . Trong mỗi danh sách bên trong, đầu vào theo thứ tự ban đầu của chúng .

Vì vậy, sau khi chạy mã, nội dung của bảng tạm là (theo ký hiệu Python):

[[11, 28], [12, 16], [4], [5, 6]]

Ví dụ 2 :

10 20 U 30 +

để lại số 10430trên ngăn xếp. Ngăn xếp được hiển thị từ dưới lên trên vào cuối chương trình.

Các cuộc gọi chức năng là

  1. 20 U cho 400
  2. 400 30 + cho 430

Vì chỉ có hai lệnh gọi hàm, một số danh sách bên trong xác định bảng tạm sẽ trống . Cũng lưu ý làm thế nào 10không được sử dụng làm đầu vào cho bất kỳ chức năng.

Vì vậy, nội dung clipboard sau khi chạy mã là:

[[400, 30], [20], [], []]

Ví dụ 3 (không hợp lệ):

10 20 + +

được coi là không hợp lệ, vì đầu vào thứ hai +bị thiếu (trong MATL, điều này sẽ ngầm kích hoạt đầu vào của người dùng).

Các thách thức

Dữ liệu vào : một chuỗi S có số bằng chữ +và được Uphân cách bằng dấu cách.

Output : các nội dung của hàm vào clipboard sau khi đánh giá chuỗi S .

Làm rõ:

  • Bạn có thể sử dụng bất kỳ hai ký hiệu nhất quán nào để thể hiện các chức năng đó, ngoài các chữ số. Ngoài ra, bạn có thể sử dụng bất kỳ biểu tượng nhất quán nào làm dấu phân cách, thay vì khoảng trắng.
  • Chỉ có hai chức năng được chỉ định sẽ được xem xét.
  • Chuỗi đầu vào sẽ chứa ít nhất một số bằng chữ và ít nhất một hàm.
  • Tất cả các số sẽ là số nguyên dương, có thể có nhiều hơn một chữ số.
  • Có thể một số chữ không được sử dụng bởi bất kỳ chức năng nào, như trong ví dụ 2.
  • Đầu vào được đảm bảo là mã hợp lệ, không yêu cầu số bổ sung. Vì vậy, một chuỗi như trong ví dụ 3 sẽ không bao giờ xảy ra.
  • Trailing danh sách bên trong trống trong đầu ra có thể được thông báo. Vì vậy, kết quả trong ví dụ 2 có thể là[[400, 30], [20]]
  • Bất kỳ định dạng đầu ra hợp lý, rõ ràng đều được chấp nhận. Ví dụ: một chuỗi có dấu phẩy là dấu phân cách bên trong và dấu chấm phẩy là dấu phân cách bên ngoài : 400,30;20;;.

Quy tắc bổ sung:

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

Input
Output

3 2 + 6 + 12 4 U + +
[[11, 28], [12, 16], [4], [5, 6]]

15 3 4 + 2 U 8 + U +
[[7, 144], [12], [4, 8], [2]]

3 6 9 12 + + 10 8 U 6
[[8], [6, 21], [9, 12], []]

8 41 12 25 4 5 33 7 9 10 + + + + + + + +
[[41, 105], [12, 93], [25, 68], [4, 64]]

10 1 1 + U U U U U
[[65536], [256], [16], [4]]

[[28, 11], [16, 12], [4], [6, 5]]đầu ra hợp lệ cho ví dụ đầu tiên?
trứng

@ovs Không, các đầu vào trong mỗi danh sách bên trong phải theo thứ tự ban đầu, nghĩa là, như trong lệnh gọi hàm
Luis Mendo

Hừm, chúng ta có nản lòng không, eh, chỉ giải quyết điều này trong MATL? : P
Erik the Outgolfer

1
Đây có phải là clipboard M?
Giuseppe

1
@Giussepe Chính xác! Tôi đã không đề cập đến tên đó ở đây vì chúng tôi không sử dụng chức năng M. Tôi sẽ thực hiện nó trong thử thách dán miếng dán
Luis Mendo

Câu trả lời:



5

Bash , 43 byte

sed s/+/rdnFPrp+/g\;s/U/p2^/g|dc|tac|sed 4q

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

Thao tác này sẽ in bảng tạm theo định dạng sau, lưu ý việc sử dụng \ x0F làm dấu phân cách.

item_1\x0Fitem_2
item_3
.
.
item_m\x0Fitem_n

Ý tưởng chính là chuyển thứ này thành dc, một ngôn ngữ dựa trên ngăn xếp, sao cho các mục ngăn xếp được yêu cầu sẽ được in.

Đầu vào được chuyển sang sed nơi mọi thứ +được thay thế bằng rdnFPrp+, trong dc in số thứ hai trên ngăn xếp theo sau là \ x0F và sau đó là số trên cùng trước khi thực hiện phép cộng. sed cũng thay thế mọi Uvới p2^, in phần tử ngăn xếp trên cùng và vuông nó.

Lệnh sthay thế đầu tiên thay thế tất cả, như được biểu thị bằng cờ g lobal g, +s với rdnFPrp+. Trong dc, rhoán đổi hai mục trên cùng của ngăn xếp, dsao chép mục trên cùng, nin nó mà không có dòng mới, Fđẩy 15 lên ngăn xếp và Pin thành ký tự (là dấu phân cách), rhoán đổi lại, pin mục ngăn xếp trên cùng và sau đó +thực hiện Ngoài ra trên hai mục hàng đầu ngăn xếp.

Chúng ta có một lệnh khác và trong sed, các lệnh được phân tách bằng dấu chấm phẩy hoặc dòng mới, trong đó tùy chọn đầu tiên được chọn. Đơn giản chỉ cần có ;sẽ làm cho bash giải thích rằng là kết thúc của lệnh sed, vì vậy nó được thoát với a \.

Trong lệnh thay thế cuối cùng, Uđược thay thế trên toàn cầu bằng p2^. Trong dc, pin và 2^nâng nó lên sức mạnh thứ hai.

Kết quả của sed được coi là mã dc, in toàn bộ bảng tạm.

Các ống để dc làm cho dc hiểu đó là mã dc. Bây giờ, các cuộc gọi gần đây nhất ở phía dưới và các cuộc gọi cũ ở phía trên.

Vì các dòng theo thứ tự ngược lại, tac(đảo ngược cat) được sử dụng để sửa lỗi đó.

Và cuối cùng, sed chọn 4 dòng đầu tiên từ tac.

Đây là một cách làm ngắn hơn head -4. sed thực hiện các lệnh cho mỗi dòng của đầu vào một lần. Nếu không có lệnh, không có gì được thực hiện cho đầu vào, và nó được trả lại như hiện tại. 4qyêu cầu sed thực hiện lệnh qtrên dòng 4. Khi sed đang xử lý dòng 4 của đầu vào, ba đầu vào đầu tiên đã được in. Lệnh qthoát khỏi chương trình, do đó, nó in dòng thứ tư và thoát, do đó thực hiện tương đương head -4.



4

Haskell , 113 109 byte

take 4.([]#).words
x:y:s#"+":r=(x+y:s#r)++[[y,x]]
x:s#"U":r=(x*x:s#r)++[[x]]
s#n:r=read n:s#r
_#_=[]
infix 4#

Dòng đầu tiên xác định một hàm ẩn danh có một chuỗi, ví dụ "3 2 + 6 + 12 4 U + +", và trả về một danh sách các danh sách int : [[11,28],[12,16],[4],[5,6]]. Hãy thử trực tuyến!


2

Sạch , 140 byte

import StdEnv,Text
k[a,b:n]["+":s]=k[a+b:n]s++[[b,a]]
k[a:n]["U":s]=k[a^2:n]s++[[a]]
k n[v:s]=k[toInt v:n]s
k _[]=[]
$s=k[](split" "s)%(0,3)

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

Theo phong cách Clean cổ điển, đó là giải pháp Haskell ngoại trừ khoảng 50% lâu hơn.


2

JavaScript (ES6), 107 byte

Lấy đầu vào là một danh sách bao gồm các số nguyên '+''U'. Trả về một danh sách khác bao gồm các số nguyên, mảng gồm 2 số nguyên và '_'cho các vị trí trống.

a=>a.map(x=>s.push(+x?x:(c=[x>[a=s.pop(),r=a*a]?a:[r=s.pop(),(r+=a,a)],...c],r)),s=[c='___'])&&c.slice(0,4)

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

Đã bình luận

a =>                          // a[] = input array
  a.map(x =>                  // for each entry x in a[]:
    s.push(                   //   update the stack:
      +x ?                    //     if x is a positive integer:
        x                     //       push x onto the stack
      :                       //     else:
        ( c = [               //       update the clipboard:
            x > [             //         compare x with '['
              a = s.pop(),    //         a = first operand
              r = a * a       //         use a² as the default result
            ] ?               //         if x is 'U' (greater than '['):
              a               //           save the 1st operand in the clipboard
            :                 //         else:
              [ r = s.pop(),  //           r = 2nd operand
                (r += a, a)   //           add the 1st operand
              ],              //           save both operands in the clipboard
            ...c              //         append the previous clipboard entries
          ],                  //       end of clipboard update
          r                   //       push r onto the stack
        )                     //
    ),                        //     end of stack update
    s = [c = '___']           //   initialize the stack; start with c = '___'
  ) &&                        // end of map()
  c.slice(0, 4)               // return the last 4 entries of the clipboard

2

Đi, 305 303 295 byte

Giảm 8 byte nhờ @ovs

func e(s string){b,v,w,x,r:=[][]int{{},{},{},{}},[]int{},0,0,0;for _,d:=range Split(s," "){if d=="+"{w,x,v=v[0],v[1],v[2:];r=w+x;b=append([][]int{[]int{x,w}},b...)}else if d=="U"{w,v=v[0],v[1:];r=w*w;b=append([][]int{[]int{w}},b...)}else{n,_:=Atoi(d);r=n};v=append([]int{r},v...)};Print(b[0:4])}

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


2

Octave , 206 byte

s=strsplit(input(''));m=t=[];for z=s
if(q=str2num(p=z{1}))t=[t q];else
if(p-43)m{end+1}=(k=t(end));t(end)=k^2;else
m{end+1}=(k=t(end-1:end));t(end-1:end)=[];t(end+1)=sum(k);end
end
end
m(1:end-4)=[];flip(m)

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

Nếu chỉ có Octave có một popcú pháp. mlà bộ nhớ tạm, tngăn xếp.


bạn có thể xây dựng mtngược lại, thêm các yếu tố vào phía trước chứ không phải là kết thúc?
Giuseppe

178 byte sử dụng chiến lược được nêu ở trên
Giuseppe

@ Guiseppe Thông minh. Tôi luôn có cảm giác rằng việc nối thêm thường ngắn hơn so với trả trước nhưng trong trường hợp này, số lượng lớn "kết thúc" đáng lẽ phải khiến tôi phải xem xét lại
Sanchises

1

Python 3 , 218 204 byte

-14 byte nhờ vào ovs

from collections import*
def f(s):
	a=deque(maxlen=4);z=a.appendleft;b=[];x=b.pop
	for i in s.split():
		if'+'==i:c=x(),x();z(c);r=sum(c)
		elif'U'==i:c=x();z(c);r=c*c
		else:r=int(i)
		b+=r,
	print([*a])

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


1

Màu đỏ , 335 330 byte

func[s][b: copy[]foreach c split s" "[append b either c >"+"and(c <"U")[do c][c]]r: copy[]until[t: 0 until[not parse
b[to copy c[2 integer!"+"](insert/only r reduce[c/1 c/2]replace b c c/1 + c/2 t: 1)to end]]until[not parse b[to copy
c[integer!"U"](insert/only r to-block c/1 replace b c c/1 ** 2 t: 1)to end]]t = 0]take/part r 4]

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

Dễ đọc hơn:

f: func[s] [
    s: split s " "
    b: copy []
    foreach c s [
        append b either (c > "+") and (c < "U")[do c] [c]
    ]
    r: copy []
    until [
        t: 0
        until [
            not parse b [to copy c[2 integer! "+"]
            (insert/only r reduce[c/1 c/2]
            replace b c c/1 + c/2
            t: 1)
            to end]
        ]
        until [
            not parse b [to copy c[integer! "U"]
            (insert/only r to-block c/1
            replace b c c/1 ** 2
            t: 1)
            to end]
        ]
        t = 0
    ]
    take/part r 4  
]

1

R , 205 182 byte

function(P){S=F
M=list()
for(K in el(strsplit(P," "))){if(is.na(x<-strtoi(K))){if(K>1){M=c(m<-S[1],M)
S[1]=m^2}else{M=c(list(m<-S[2:1]),M)
S=c(sum(m),S[-2:0])}}else S=c(x,S)}
M[1:4]}

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

Mlà bộ nhớ tạm, Plà chương trình và Slà ngăn xếp.

Về mặt kỹ thuật Sđược khởi tạo như một vectơ chứa một số 0 duy nhất nhưng vì chúng ta không bao giờ nhận được đầu vào không hợp lệ, nó tiết kiệm cho tôi một byte từ đó S={}.


1

C (gcc) , 264 byte

Tôi đã sử dụng đệ quy để tôi có thể sử dụng ngăn xếp hàm làm ngăn xếp dữ liệu: danh sách đầu vào được thực hiện và các thao tác được thực hiện: kết quả được hiển thị theo thứ tự ngược lại, với các lần đẩy ngăn xếp không được hiển thị.

Ngăn xếp được thực hiện như một danh sách liên kết. Đây là cách nó hoạt động:

  • Nút hiện tại được thiết lập với [con trỏ tới giá trị, con trỏ đến nút trước đó]
  • Để đẩy một giá trị, nó được lưu trữ và hàm được gọi lại với nút hiện tại.
  • Để bật một giá trị hoặc sửa đổi giá trị trên đỉnh của ngăn xếp, giá trị của nút trước đó được sửa đổi và hàm được gọi lại với nút trước đó.

Ban đầu tôi sử dụng cấu trúc cho các nút, nhưng tôi đã chuyển sang con trỏ trần để tiết kiệm không gian. Một tính năng thú vị của danh sách được liên kết này là nó tự dọn sạch khi đệ quy hoàn tất.

#define _ printf
f(char**s,int**p){int**w,v,*y[]={&v,p},m,n,t,z;w=y;z=1;return(*s?(**s-85?**s-43?(--z,t=14,v=atoi(*s)):(t=6,w=p[1],m=**w,**w+=n=**p):(t=0,w=p,**w*=m=**p),v=f(s+1,w),_(v<4?",[%d]\0,[%d,%d]\0"+t+!v:"",m,n),v+z):0);}g(char**s){_("[");f(s,0);_("]\n");}

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

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.