İşlev panosu: kopyala


17

Bu zorluk, Mayıs 2018 Ayın Dili etkinliğinin bir parçası olarak MATL dilinin bazı özellikleriyle ilgilidir . İlişkili zorluk : İşlev panosu: yapıştır .


Giriş

MATL, daha sonra alınacak değerleri (kopya) depolayabileceğiniz (yapıştır) birkaç panoya sahiptir . Bazı panolar otomatiktir , yani kopyalama bazı olaylar tarafından otomatik olarak tetiklenir. Bu zorluk, işlev giriş panosu veya basitçe işlev panosu adı verilen otomatik klip kartlarından birine odaklanır .

Bu pano, girişleri normal, giriş alma işlevlerine yapılan en son dört çağrının içinde saklar. Normal işlevler, MATL'de en yaygın işlev türüdür. Girdi alma , işlevin en az bir girdi alması anlamına gelir (herhangi bir girdi almayan işlevler işlev panosu tarafından dikkate alınmaz).

Bu en iyi iki normal işlevi kullanan aşağıdaki örneklerle açıklanmaktadır:

  • +yığınından iki sayı çıkar ve toplamlarını iter.
  • U, bir sayı çıkar ve karesini iter.

Örnek 1 :

3 2 + 6 + 12 4 U + +

sonucu üretir39 . Kod şu şekilde yorumlanır:

  • Gibi sayısı sabitleri 3veya 12yığınına itilir olsun
  • +Girdilerini açma ve çıktılarını yığına itme gibi işlevler .

Kronolojik sırayla işlev çağrıları şunlardır:

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

Pano, dört listenin listesi olarak görüntülenebilir. Her bir iç liste bir işlev çağrısının girişlerini içerir, en son çağrılar önce gelir . Her iç listede, girdiler orijinal sıralarına göre sıralanmıştır .

Bu yüzden kodu çalıştırdıktan sonra pano içeriği (Python notasyonunda):

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

Örnek 2 :

10 20 U 30 +

numaraları 10ve 430yığın üzerinde bırakır . Yığın, programın sonunda aşağıdan yukarıya görüntülenir.

Fonksiyon çağrıları

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

Yalnızca iki işlev çağrısı olduğundan, panoyu tanımlayan iç listelerin bazıları boş olacaktır . Ayrıca 10herhangi bir işleve giriş olarak nasıl kullanılmadığına dikkat edin.

Bu nedenle, kodu çalıştırdıktan sonra pano içeriği şunlardır:

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

Örnek 3 (geçersiz):

10 20 + +

ikinciye bir girdi +eksik olduğu için geçersiz kabul edilir (MATL'de bu dolaylı olarak kullanıcı girişini tetikler).

Meydan okuma

Girdi : sayı değişmezleri olan ve boşluklarla ayrılmış bir S dizesi .+U

Çıktı : S dizesini değerlendirdikten sonra işlev panosunun içeriği .

Açıklamalar:

  • Bu işlevleri temsil etmek için basamaklar dışında iki tutarlı simge kullanabilirsiniz. Ayrıca, boşluk yerine ayırıcı olarak herhangi bir tutarlı sembolü kullanabilirsiniz.
  • Sadece belirtilen iki fonksiyon dikkate alınacaktır.
  • Giriş dizesi en az bir sayı değişmezi ve en az bir işlev içerecektir.
  • Tüm sayılar, muhtemelen birden fazla basamaklı pozitif tamsayılar olacaktır.
  • Bazı sayı değişmezlerinin, örnek 2'deki gibi herhangi bir işlev tarafından kullanılmaması mümkündür.
  • Girişin, ek numaralar gerektirmeden geçerli bir kod olması garanti edilir. Yani örnek 3'teki gibi bir dize asla oluşmayacaktır.
  • Çıktıdaki boş iç listelerin izlenmesi ommite edilebilir. Yani örnek 2'deki sonuç[[400, 30], [20]]
  • Herhangi bir makul, net çıktı biçimi kabul edilebilir. Örneğin, dış ayırıcı olarak iç ayırıcı ve noktalı virgül ile bir dizge: 400,30;20;;.

Ek kurallar:

Test senaryoları

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]]İlk örnek için geçerli çıktı mı ?
ovs

@ovs Hayır, her bir iç listedeki girdiler orijinal sırada olmalıdır, yani işlev çağrısında olduğu gibi
Luis Mendo

Hm, bunu MATL'de çözmekten vazgeçtik mi, ha? : P
Outgolfer Erik

1
Bu pano Mmu?
Giuseppe

1
@Giussepe Kesinlikle! Burada bu isimden bahsetmedim çünkü fonksiyon kullanmıyoruz M. Bunu "macun" mücadelesinde yapacağım
Luis Mendo

Yanıtlar:



5

Bash , 43 bayt

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

Çevrimiçi deneyin!

Bu panoyu aşağıdaki biçimde yazdırır, ayırıcı olarak \ x0F kullanımını not edin.

item_1\x0Fitem_2
item_3
.
.
item_m\x0Fitem_n

Ana fikir, bunu yığın tabanlı bir dil olan dc'ye geçirmektir, böylece gerekli yığın öğeleri yazdırılır.

Giriş, her +birinin yerini aldığı yere sed olarak rdnFPrp+ayarlanır ve dc'de, yığındaki ikinci sayıyı ardından \ x0F ve ardından ekleme yapmadan önce üst sayı yazdırır. sed da her yerini Uilep2^ üst yığını elemanı yazdırmak ve karesini.

İlk ikame komutu s, g lobal bayrağıyla belirtildiği gibi g, +s ile değiştirilir rdnFPrp+. DC'de, ren üstteki iki yığın döğeyi değiştirir, en üstteki öğeyi çoğaltır, nyeni satır olmadan yazdırır, F15'i yığının üzerine iter ve Pbir karakter olarak (sınırlayıcı olan) yazdırır, ryeniden değiştirir, püst yığın öğesini yazdırır ve sonra+ gerçekleştirir üstteki iki yığın öğeye eklenir.

Başka bir komutumuz var ve sed'de komutlar, ilk seçeneğin seçildiği noktalı virgül veya satırlarla ayrılır. Sadece ;bash bunu sed komutunun sonu olarak yorumlayacaktır, bu yüzden a ile kaçar \.

Son ikame komutunda, Uküresel olarak değiştirilir p2^. DC'de pyazdırır ve 2^ikinci güce yükseltir.

Sed sonucu tüm panoya yazdırarak dc kodu olarak değerlendirilir.

DC'den gelen boru, dc'yi dc kodu olarak yorumlar. Şimdi, en son çağrılar en altta ve daha eski olanlar en üstte.

Çizgiler ters sırada olduğundan, bunu düzeltmek için tac(ters cat) kullanılır.

Ve son olarak, sed tac'den ilk 4 satırı seçer.

Bu daha kısa bir yol head -4. sed komutları girişin her satırına birer birer uygular. Komut yoksa, girişe hiçbir şey yapılmaz ve olduğu gibi döndürülür. 4qsed'e q4. satırdaki komutu gerçekleştirmesini söyler. sed girdinin 4. satırını işlerken, ilk üç giriş zaten yazdırılmıştır. Komut qprogramdan çıkar, böylece dördüncü satırı yazdırır ve böylece eşdeğerini yerine getirir head -4.



4

Haskell , 113 109 bayt

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#

İlk satır bir dize, örneğin alır anonim işlevi tanımlar "3 2 + 6 + 12 4 U + +"ve ints listelerin bir listesini döndürür: [[11,28],[12,16],[4],[5,6]]. Çevrimiçi deneyin!


2

Temiz , 140 bayt

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)

Çevrimiçi deneyin!

Klasik Clean tarzında, yaklaşık% 50 daha uzun hariç Haskell çözümü.


2

JavaScript (ES6), 107 bayt

Girdileri tamsayılardan oluşan bir liste olarak alır '+'ve 'U'. Tamsayılardan, 2 tamsayıdan oluşan dizilerden ve '_'boş yuvalardan oluşan başka bir liste döndürür .

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)

Çevrimiçi deneyin!

Yorumlananlar

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

Git 305 303 295 bayt

@Ovs sayesinde 8 bayt düştü

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])}

Çevrimiçi deneyin!


2

Oktav , 206 bayt

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)

Çevrimiçi deneyin!

Keşke Octave popsözdizimine sahip olsaydı . mbellek panosu, tyığın.


Sonuna değil cepheye eleman ekleyerek yapılandırabilir mve ttersine çevirebilir misiniz ?
Giuseppe

Yukarıda belirtilen stratejiyi kullanarak 178 bayt
Giuseppe

@Guiseppe Clever. Ben her zaman ekleme genellikle prepending daha kısa olduğunu hissediyorum ama bu durumda çok sayıda "son" beni yeniden düşünmeliydim
Sanchises

1

Python 3 , 218 204 bayt

Ovs sayesinde -14 bayt

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])

Çevrimiçi deneyin!


1

Kırmızı , 335 330 bayt

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]

Çevrimiçi deneyin!

Daha okunabilir:

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 bayt

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]}

Çevrimiçi deneyin!

Mbellek panosu, Pprogram veS yığıntır.

Teknik Solarak tek bir sıfır içeren bir vektör olarak başlatılır, ancak asla geçersiz bir girdi almadığımız için bana bir bayt kazandırır S={}.


1

C (gcc) , 264 bayt

Veri yığını olarak işlev yığınını kullanabilmem için özyineleme kullandım: giriş listesi gözden geçirilir ve işlemler gerçekleştirilir: sonuçlar ters sırada görüntülenir, yığın itmeleri görüntülenmez.

Yığın bağlantılı bir liste olarak uygulanır. Şöyle çalışır:

  • Geçerli düğüm [değere işaretçi, önceki düğüme işaretçi] ile ayarlanır.
  • Bir değeri itmek için saklanır ve işlev geçerli düğümle yeniden çağrılır.
  • Bir değer açmak veya yığının üstündeki değeri değiştirmek için önceki düğümün değeri değiştirilir ve işlev önceki düğümle yeniden çağrılır.

Başlangıçta düğümler için bir yapı kullandım, ancak yerden tasarruf etmek için çıplak göstergelere geçtim. Bu bağlantılı listenin ilginç bir özelliği, özyineleme tamamlandığında kendini temizlemesidir.

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

Çevrimiçi deneyin!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.