関数クリップボード:コピー


17

この課題は、2018年5月の「Language of the Month」イベントの一環として、MATL言語の機能の一部に関連しています。 関連する課題関数クリップボード:貼り付け


前書き

MATLには、値を保存(コピー)して後で取得(貼り付け)できるクリップボードがいくつかあります。一部のクリップボードは自動です。つまり、特定のイベントによってコピーが自動的にトリガーされます。この課題は、関数入力クリップボードまたは単に関数クリップボードと呼ばれる自動クリップバーの1つに焦点を当てています。

このクリップボードは、通常の入力取得機能への4つの最新の呼び出しへの入力を保存します。通常の関数は、MATLで最も一般的なタイプの関数です。入力取得は、関数が少なくとも1つの入力を取得すること意味します(入力を取得しない関数は、関数クリップボードによって考慮されません)。

これは、2つの通常の関数を使用する次の例で最もよく説明されます。

  • +、スタックから2つの数値をポップし、それらの合計をプッシュします。
  • U、1つの数字をポップし、その正方形をプッシュします。

例1

3 2 + 6 + 12 4 U + +

結果を生成39ます。コードは次のように解釈されます。

  • 3または12スタックにプッシュされるなどの数値リテラル
  • +入力をポップし、出力をスタックにプッシュするなどの関数。

関数呼び出しは、時系列で次のとおりです。

  1. 3 2 + 与える 5
  2. 5 6 + 与える 11
  3. 4 U 与える 16
  4. 12 16 + 28
  5. 11 28 +与える39

クリップボードは、4つのリストのリストとして表示できます。各内部リストには、関数呼び出しへの入力が含まれ、最新の呼び出しが最初にあります。各内部リスト内で入力は元の順序になっています。

そのため、コードを実行した後のクリップボードの内容は次のとおりです(Python表記):

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

例2

10 20 U 30 +

数字10430スタックに残します。スタックは、プログラムの最後に下から上に表示されます。

関数呼び出しは

  1. 20 U 与える 400
  2. 400 30 + 与える 430

関数呼び出しは2つしかなかったため、クリップボードを定義する内部リストの一部はになります。また、どのように10関数への入力として使用されていないかに注意してください。

したがって、コード実行後のクリップボードの内容は次のとおりです。

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

例3(無効):

10 20 + +

2番目への入力+が欠落しているため、無効と見なされます(MATLでは、これは暗黙的にユーザー入力をトリガーします)。

チャレンジ

入力:数字リテラルを含む文字列S+U、スペースで区切られた。

出力:文字列Sを評価した後の関数クリップボードの内容。

明確化:

  • これらの機能を表すために、数字以外の2つの一貫した記号を使用できます。また、スペースの代わりに、一貫性のある記号をセパレータとして使用できます。
  • 示されている2つの機能のみが考慮されます。
  • 入力文字列には、少なくとも1つの数値リテラルと少なくとも1つの関数が含まれます。
  • すべての数値は正の整数で、場合によっては2桁以上です。
  • 例2のように、一部の数値リテラルはどの関数でも使用されない可能性があります。
  • 入力は、追加の番号を必要とせずに有効なコードであることが保証されています。したがって、例3のような文字列は発生しません。
  • 出力の末尾の空の内部リストは省略できます。したがって、例2の結果は次のようになります。[[400, 30], [20]]
  • 合理的で明確な出力形式であれば受け入れ可能です。たとえば、内部セパレータとしてカンマ、外部セパレータとしてセミコロンを含む文字列:400,30;20;;

追加のルール:

テストケース

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]]最初の例の有効な出力はありますか?
ovs

@ovsいいえ、各内部リスト内の入力は元の順序である必要があります。つまり、関数呼び出しのように
ルイスメンドー

うーん、MATLでこれを解決するだけでは、がっかりしますか?:P
エリックアウトゴルファー

1
このクリップボードMですか?
ジュゼッペ

1
@Giussepeまさに!functionを使用していないため、ここではその名前について言及していませんM。「貼り付け」チャレンジでそれをやります
ルイスメンドー

回答:


3

05AB1E、20バイト

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

オンラインでお試しください!

-4 エミグナに感謝(同様に、-8ルールについて私に更新してくれた彼に感謝)。

  • U: a
  • +: b

4
:( ...なぜそうseRïõS?
ルイスメンドー

@LuisMendoこのスコアは非常に厳しいです。:(
エリック・ザ・アウトゴルファー


5

Bash、43バイト

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

オンラインでお試しください!

これにより、クリップボードが次の形式で印刷されます。セパレータとして\ x0Fが使用されていることに注意してください。

item_1\x0Fitem_2
item_3
.
.
item_m\x0Fitem_n

重要なアイデアは、これをスタックベースの言語であるdcに渡して、必要なスタック項目が印刷されるようにすることです。

入力はsedにパイプされ、すべて+がに置き換えられrdnFPrp+ます。dcは、スタックの2番目の数値に続いて\ x0F、次に加算を実行する前の最上位の数値を出力します。sedはまた、すべてUp2^で置き換え、一番上のスタック要素を出力し、四角にします。

第1の置換コマンドは、sで示されるように、全てを置き換えるGローブフラグg+でですrdnFPrp+。dcでr、先頭の2つのスタック項目をスワップし、先頭の項目をd複製しn、改行なしで印刷し、F15をスタックにプッシュPして文字(区切り文字)rとしてp印刷し、再度スワップし、先頭のスタック項目を印刷してから+実行します上の2つのスタック項目に追加。

別のコマンドがあります。sedでは、コマンドはセミコロンまたは改行で区切られ、最初のオプションが選択されます。単に持っているだけで;、bashはそれをsedコマンドの終わりとして解釈するので、でエスケープされます\

最後の置換コマンドでUは、はでグローバルに置き換えられp2^ます。DCでは、p出力2^し、2乗します。

sedの結果はdcコードとして評価され、クリップボード全体が印刷されます。

dcへのパイプは、dcをそれをdcコードとして解釈します。現在、最新の呼び出しが下部にあり、古い呼び出しが上部にあります。

行は逆順なので、tac(reverse cat)を使用して修正します。

そして最後に、sedはtacから最初の4行を選択します。

これはより短いやり方ですhead -4。sedは、入力のすべての行に対してコマンドを一度に1つずつ実行します。コマンドがない場合、入力には何も行われず、そのまま返されます。4行目で4qコマンドを実行するようにsedに指示しますq。sedが入力の4行目を処理しているとき、最初の3つの入力はすでに印刷されています。このコマンドqはプログラムを終了するため、4行目を出力して終了しhead -4ます。したがって、と同等の処理が実行されます。



4

Haskell113 109バイト

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#

最初の行は、たとえば"3 2 + 6 + 12 4 U + +"、文字列を受け取り、intのリストのリストを返す匿名関数を定義します[[11,28],[12,16],[4],[5,6]]オンラインでお試しください!



2

JavaScript(ES6)、107バイト

整数からなるリストとして入力を受け取り、'+'そして'U'。整数、2つの整数の配列、および'_'空のスロットで構成される別のリストを返します。

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)

オンラインでお試しください!

コメント済み

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

ゴー、305の 303 295バイト

@ovsのおかげで8バイトが削除さました

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

オンラインでお試しください!


2

オクターブ、206バイト

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)

オンラインでお試しください!

Octaveにのみpop構文がある場合。mメモリクリップボード、tスタックです。


要素を構築mt、逆に、最後ではなく前に要素を追加できますか?
ジュゼッペ

上記の戦略を使用した178バイト
ジュゼッペ

@Guiseppe Clever。私はいつも、
アペンディングは一般にプリペンディング


1

335330バイト

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]

オンラインでお試しください!

より読みやすい:

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

R205 182バイト

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

オンラインでお試しください!

Mメモリクリップボード、Pプログラム、およびSスタックです。

技術的にSは、単一のゼロを含むベクトルとして初期化されますが、無効な入力を取得することはないため、から1バイト節約できますS={}


1

C(gcc)、264バイト

関数スタックをデータスタックとして使用できるように再帰を使用しました。入力リストを調べて操作を実行します。結果は逆の順序で表示され、スタックプッシュは表示されません。

スタックはリンクリストとして実装されます。仕組みは次のとおりです。

  • 現在のノードは[値へのポインター、前のノードへのポインター]で設定されます
  • 値をプッシュするには、その値が保存され、現在のノードで関数が再度呼び出されます。
  • スタックの一番上の値をポップまたは変更するには、前のノードの値が変更され、前のノードで関数が再度呼び出されます。

もともとノードの構造を使用していましたが、スペースを節約するためにベアポインターに切り替えました。このリンクリストの興味深い機能は、再帰が完了すると自動的にクリーンアップされることです。

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

オンラインでお試しください!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.