Fungsi papan klip: salin

17

Tantangan ini terkait dengan beberapa fitur bahasa MATL, sebagai bagian dari acara Bahasa Bulan Mei 2018 . Tantangan terkait : Papan klip fungsi: tempel .


pengantar

MATL memiliki beberapa papan klip , tempat Anda dapat menyimpan nilai (salin) untuk diambil nanti (tempel). Beberapa clipboard otomatis , yang berarti bahwa penyalinan secara otomatis dipicu oleh peristiwa tertentu. Tantangan ini berfokus pada salah satu clipbard otomatis, yang disebut clipboard fungsi-input , atau hanya clipboard fungsi .

Clipboard ini menyimpan input ke empat panggilan terbaru ke fungsi pengambilan input yang normal. Fungsi normal adalah jenis fungsi yang paling umum di MATL. Pengambilan input berarti bahwa fungsi tersebut mengambil setidaknya satu input (fungsi yang tidak mengambil input apa pun tidak dipertimbangkan oleh clipboard fungsi).

Ini paling baik dijelaskan dengan contoh-contoh berikut, yang menggunakan dua fungsi normal:

  • +, yang mengeluarkan dua angka dari tumpukan dan mendorong jumlahnya.
  • U, yang muncul satu angka dan mendorong kuadratnya.

Contoh 1 :

3 2 + 6 + 12 4 U + +

menghasilkan hasilnya 39. Kode ditafsirkan sebagai berikut:

  • Jumlah literal seperti 3atau 12didorong ke tumpukan
  • Fungsi seperti +pop input mereka dan mendorong output mereka ke stack.

Panggilan fungsi, dalam urutan kronologis, adalah:

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

Papan klip dapat dilihat sebagai daftar empat daftar. Setiap daftar bagian dalam berisi input untuk panggilan fungsi, dengan sebagian besar panggilan terakhir terlebih dahulu . Dalam setiap daftar dalam, input berada dalam urutan aslinya .

Jadi setelah menjalankan kode, isi clipboardnya adalah (dalam notasi Python):

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

Contoh 2 :

10 20 U 30 +

meninggalkan angka 10dan 430di tumpukan. Tumpukan ditampilkan dari bawah ke atas di akhir program.

Panggilan fungsi adalah

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

Karena hanya ada dua panggilan fungsi, beberapa daftar bagian dalam menentukan clipboard akan kosong . Perhatikan juga bagaimana 10tidak digunakan sebagai input ke fungsi apa pun.

Dengan demikian, konten clipboard setelah menjalankan kode adalah:

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

Contoh 3 (tidak valid):

10 20 + +

dianggap tidak valid, karena input ke yang kedua +tidak ada (dalam MATL ini secara implisit akan memicu input pengguna).

Tantangan

Input : string S dengan angka literal, +dan U, dipisahkan oleh spasi.

Output : isi fungsi clipboard setelah mengevaluasi string S .

Klarifikasi:

  • Anda dapat menggunakan dua simbol yang konsisten untuk mewakili fungsi-fungsi itu, selain digit. Selain itu, Anda dapat menggunakan simbol apa pun yang konsisten sebagai pemisah, alih-alih ruang.
  • Hanya dua fungsi yang ditunjukkan yang akan dipertimbangkan.
  • String input akan mengandung setidaknya satu angka literal dan setidaknya satu fungsi.
  • Semua angka akan bilangan bulat positif, mungkin dengan lebih dari satu digit.
  • Ada kemungkinan beberapa literal angka tidak digunakan oleh fungsi apa pun, seperti pada contoh 2.
  • Input dijamin kode yang valid, tanpa memerlukan nomor tambahan. Jadi string seperti pada contoh 3 tidak akan pernah terjadi.
  • Mengejar daftar batin kosong di output dapat dihilangkan. Jadi hasilnya dalam contoh 2 bisa[[400, 30], [20]]
  • Format output yang masuk akal dan tidak ambigu dapat diterima. Sebagai contoh, string dengan koma sebagai pemisah dalam dan titik koma sebagai pemisah luar: 400,30;20;;.

Aturan tambahan:

Uji kasus

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]]
Luis Mendo
sumber
Apakah [[28, 11], [16, 12], [4], [6, 5]]keluaran yang valid untuk contoh pertama?
Ovs
@ovs Tidak, input dalam setiap daftar bagian dalam harus berada dalam urutan asli, yaitu, seperti dalam pemanggilan fungsi
Luis Mendo
Hm, apakah kita berkecil hati, eh, hanya menyelesaikan ini di MATL? : P
Erik the Outgolfer
1
Apakah ini clipboard M?
Giuseppe
1
@Giussepe Persis! Saya belum menyebutkan nama itu di sini karena kami tidak menggunakan fungsi M. Saya akan melakukannya dalam tantangan "tempel"
Luis Mendo

Jawaban:

3

05AB1E , 20 byte

A"D¸ˆn‚DˆO"4ô‡.V¯R4£

Cobalah online!

-4 Terima kasih kepada Emigna (dan juga -8 terima kasih karena dia memperbarui saya tentang aturan).

  • U: a
  • +: b
Erik the Outgolfer
sumber
4
:( ... Kenapa begitu seRïõS?
Luis Mendo
@LuisMendo Skor ini sangat mahal. :(
Erik the Outgolfer
Mari kita lanjutkan diskusi ini dalam obrolan .
Erik the Outgolfer
5

Bash , 43 byte

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

Cobalah online!

Ini mencetak clipboard dalam format berikut, perhatikan penggunaan \ x0F sebagai pemisah.

item_1\x0Fitem_2
item_3
.
.
item_m\x0Fitem_n

Gagasan utamanya adalah meneruskannya ke dc, bahasa berbasis stack, sehingga item-item stack yang diperlukan akan dicetak.

Masukan disalurkan ke sed di mana setiap +diganti dengan rdnFPrp+, yang di dc mencetak angka kedua pada tumpukan diikuti oleh \ x0F dan kemudian angka teratas sebelum melakukan penambahan. sed juga menggantikan setiap Udenganp2^ , mencetak elemen tumpukan atas dan persegi itu.

Perintah substitusi pertama smenggantikan semua, seperti yang dilambangkan dengan g bendera lobal g, +s dengan rdnFPrp+. Dalam dc, rmenukar dua item tumpukan teratas, dmenggandakan item teratas, nmencetaknya tanpa baris baru, Fmendorong 15 ke tumpukan dan Pmencetaknya sebagai karakter (yang merupakan pembatas), rbertukar lagi, pmencetak item tumpukan atas dan kemudian +melakukan Selain pada dua item tumpukan teratas.

Kami memiliki perintah lain, dan pada dasarnya, perintah dipisahkan oleh titik koma atau baris baru, di mana opsi pertama dipilih. Cukup memiliki; akan membuat bash menginterpretasikan itu sebagai akhir dari perintah sed, sehingga ia lolos dengan a \.

Dalam perintah substitusi terakhir, Udiganti secara global dengan p2^. Di dc, pcetak, dan 2^naikkan ke kekuatan kedua.

Hasil sed dievaluasi sebagai kode dc, mencetak seluruh clipboard.

Pipa ke dc membuat dc menafsirkannya sebagai kode dc. Sekarang, panggilan terbaru ada di bawah dan yang lebih tua di atas.

Karena garis berada dalam urutan terbalik, tac(mundur cat) digunakan untuk memperbaikinya.

Dan akhirnya, sed mengambil 4 baris pertama dari tac.

Ini adalah cara yang lebih singkat untuk dilakukan head -4. sed melakukan perintah ke setiap baris input satu per satu. Jika tidak ada perintah, tidak ada yang dilakukan pada input, dan itu dikembalikan seperti apa adanya. 4qmemberitahu sed untuk melakukan perintah qpada baris 4. Ketika sed memproses baris 4 dari input, tiga input pertama telah dicetak. Perintah qberhenti dari program, sehingga ia mencetak baris keempat dan berhenti, dengan demikian melakukan yang setara dengan head -4.

Kritixi Lithos
sumber
4

Python 2 , 126 byte

s=[0];b=[]
for c in input().split():k='U+'.find(c)+1;b=[s[k-1::-1]][:k]+b;s=[int([c,s[0]**2,sum(s[:2])][k])]+s[k:]
print b[:4]

Cobalah online!

ovs
sumber
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#

Baris pertama mendefinisikan fungsi anonim yang mengambil string, misalnya "3 2 + 6 + 12 4 U + +", dan mengembalikan daftar daftar int: [[11,28],[12,16],[4],[5,6]]. Cobalah online!

Laikoni
sumber
2

Bersih , 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)

Cobalah online!

Dalam gaya Clean klasik, ini adalah solusi Haskell kecuali sekitar 50% lebih lama.

Suram
sumber
2

JavaScript (ES6), 107 byte

Mengambil input sebagai daftar yang terdiri dari bilangan bulat, '+'dan 'U'. Mengembalikan daftar lain yang terdiri dari integer, array 2 integer dan '_'untuk slot kosong.

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)

Cobalah online!

Berkomentar

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
Arnauld
sumber
2

Pergilah, 305 303 295 byte

Turun 8 byte berkat @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])}

Cobalah online!

ollien
sumber
2

Oktaf , 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)

Cobalah online!

Andai saja Oktaf memiliki popsintaksis. madalah papan klip memori, ttumpukan.

Sanchises
sumber
dapatkah Anda membuat mdan tmembalikkannya, menambahkan elemen ke depan daripada pada akhirnya?
Giuseppe
178 byte menggunakan strategi yang diuraikan di atas
Giuseppe
@Guiseppe Pandai. Saya selalu merasa bahwa menambahkan pada umumnya lebih pendek dari pada memprioritaskan, tetapi dalam hal ini jumlah besar "akhir" seharusnya membuat saya mempertimbangkan kembali
Sanchises
1

Python 3 , 218 204 byte

-14 byte berkat 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])

Cobalah online!

Draconis
sumber
1

Merah , 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]

Cobalah online!

Lebih mudah dibaca:

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  
]
Galen Ivanov
sumber
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]}

Cobalah online!

Madalah papan klip memori, Padalah program, dan Smerupakan tumpukan.

Secara teknis Sdiinisialisasi sebagai vektor yang mengandung nol tunggal tetapi karena kita tidak pernah mendapatkan input yang tidak valid, itu menyelamatkan saya byte dari S={}.

Giuseppe
sumber
1

C (gcc) , 264 byte

Saya menggunakan rekursi sehingga saya bisa menggunakan fungsi stack sebagai tumpukan data: daftar input berjalan dan operasi dilakukan: hasilnya ditampilkan dalam urutan terbalik, dengan dorongan tumpukan tidak ditampilkan.

Tumpukan diimplementasikan sebagai daftar tertaut. Begini cara kerjanya:

  • Node saat ini diatur dengan [penunjuk ke nilai, penunjuk ke simpul sebelumnya]
  • Untuk mendorong nilai, ini disimpan dan fungsinya dipanggil lagi dengan simpul saat ini.
  • Untuk memunculkan nilai atau mengubah nilai di atas tumpukan, nilai simpul sebelumnya dimodifikasi dan fungsinya dipanggil lagi dengan simpul sebelumnya.

Saya awalnya menggunakan struktur untuk node, tetapi saya beralih ke bare pointer untuk menghemat ruang. Fitur yang menarik dari daftar tertaut ini adalah bahwa ia membersihkan dirinya sendiri ketika rekursi selesai.

#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");}

Cobalah online!

ErikF
sumber