関数クリップボード:貼り付け


20

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


前書き

MATLの関数クリップボードは、通常の入力取得関数への最新の4つの呼び出しへの入力を保存(「コピー」)します。通常の関数は、MATLで最も一般的なタイプの関数です。入力取得とは、関数が少なくとも1つの入力を取得すること意味します。保存されたクリップボードの内容は、スタックにプッシュできます(「貼り付け」)。

このチャレンジは、クリップボードの内容を入力として受け取ります。そのクリップボード状態を生成したすべての関数は、入力として1つ以上の正の整数をとったと想定されます。したがって、クリップボードの状態は、数字のリストのリストで表すことができます。(クリップボードへの実際の入力方法の詳細については、関連するチャレンジを参照してください。ただし、現在のチャレンジには必要ありません)。

クリップボードの内容を解釈する

例1

最初の内側のリストにはを参照し、最新したがって、クリップボードの状態なので、上の関数呼び出し、および

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

は、最後の関数呼び出しが2つの入力を受け取ったこと1128示します。最後から2番目の呼び出しは、入力を取りました1216。など(このクリップボードの状態は、関連するチャレンジの最初の例のコードによって生成されます)。

例2

十分な関数呼び出しがなかった場合、クリップボードの末尾の内部リストは空になります。

[[7, 5], [], [], []]

(これは、単に7およびを追加するプログラムによって作成されます5)。

例3

関数呼び出しには任意の数の入力を含めることができますが、少なくとも少なくとも1(入力を受け取らない関数はクリップボードの状態を変更しません)。したがって、次のことも可能です。

[[3], [2, 40, 34], [7, 8, 15], []]

クリップボードの内容にアクセスする

関数クリップボードの内容は、MATLの関数M(ちなみに通常の関数ではなく、クリップボード関数)を使用してスタックにプッシュされます。この関数は、入力として正の整数を受け取り、次のようにクリップボードの内容の一部をスタックにプッシュします。例1のクリップボードの状態を参照してください:

[[11, 28], [12, 16], [4], [5, 6]]
  • 1Mすべての入力を最新の関数呼び出しに返します。そう考える例えば、それができます1128
  • 同様に2M3Mおよびは、4M最新の2番目、3番目、4番目の関数呼び出しにすべての入力を返します。そう2Mなります12163M与える4; そして、4Mなります56
  • 複数の入力を必要とする関数呼び出しへの個々の入力4選択する以上の数。したがって、最新のそのような呼び出しに最後の入力を返します。私たちの場合、これはを与えます。は、前の個々の入力を返します。であり、第二の最後の呼び出しの最後の入力を返し、となりますが。今、与える。入力方法に注意してください5M286M117M168M129M64が関数呼び出しの唯一の入力であったため、がスキップされる。最後に、10Mを与え5ます。

例3のクリップボード状態の場合:

[[3], [2, 40, 34], [7, 8, 15], []]
  • 1M与える32M与え240343M与え7815
  • 4M 持っている 未定義の動作のみ3回の関数の呼び出しがあったので、(この課題の目的のために)。
  • 5M与える346M与える407M与える28M与える159M与える810M与える7
  • 11M12M、...も持っている未定義の動作を

チャレンジ

入力

  • リストのリストとしてのクリップボードの状態、またはその他の妥当な形式。
  • 正の整数n

出力nを入力として関数Mを呼び出した結果。出力は、明確な区切り記号が付いた1つまたは複数の数字、またはリストや配列などの適切な形式になります。

明確化:

  • クリップボードの状態は、4つの数字のリストで構成されています。例2および3のように、末尾のリストの一部は空の場合があります。必要に応じて、末尾の空のリストなしでクリップボードを入力できます。したがって、例3はになり[[3], [2, 40, 34], [7, 8, 15]]ます。
  • クリップボード内のすべての数値は正の整数で、場合によっては複数の数字が含まれます。
  • 番号nは有効であることが保証されています。したがって、上記の例3では、またはにnすることはできません。411

追加のルール:

テストケース

Clipboard state
Number
Output(s)

[[11, 28], [12, 16], [4], []]
2
12, 16

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

[[7, 144], [12], [4, 8], [3, 4, 6]]
1
7, 144

[[7, 144], [12], [4, 8], [3, 4, 6]]
10
4

[[30], [40], [50, 60], [70, 80, 90]]
2
40

[[30], [40], [50, 60], [80, 90]]
7
90

[[15], [30], [2, 3, 5], [4, 5, 10]]
3
2, 3, 5

[[15], [30], [2, 3, 5], [4, 5, 10]]
7
2

0インデックス付きのnを使用できますか?
アーナウルド

3
@Arnauldノーと言うつもりです。これはMATLの実際の動作に基づいているためです
ルイスメンドー

回答:


3

ゼリー、8バイト

ḊƇUẎ⁸;⁹ị

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


2
説明を追加してもよろしいですか?
LordColus

@LordColusはḊƇ、シングルトン以外のすべてを選択し、U反転して平坦化します。入力の場合、[[11, 28], [12, 16], [4], []]これは[16, 12, 28, 11]5Mthrough の値を取得します8M。次に、元の入力をこのリストの先頭に⁸;追加し、他の入力によって結果のリストにインデックスを付けます⁹ị
リン

@LordColusああ、すみません、リクエストに応じて説明を追加するだけです(忍者のため)が、私は眠っていました。Lynnはほとんど説明してくれましたがU、の結果を反転させずにḊƇ、各要素を追加したいと思います。どうにかして減らすことができた場合にのみḊƇUẎ⁸;...
エリック・ザ・アウトゴルファー

4

ハスケル56 51 47バイト

ライコニのおかげで-5 -9バイト(長さ> 1を確保doし、リスト内包表記よりも-notationを使用するパターンマッチ)!

c!n=([]:c++do l@(_:_:_)<-c;reverse$pure<$>l)!!n

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

ポイントフリー、58 55バイト

Laikoni(移動([]:)および交換id)のおかげで-3バイト!

または、このポイントフリーバージョンを使用できます

(!!).(([]:)<>map pure.(>>=reverse).filter((1<).length))



3

JavaScript(Node.js)、57バイト

a=>n=>a.map(e=>e[1]&&a.push(...[...e].reverse()))&&a[n-1]

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

これは、匿名のカリー化された関数です。で実行する( function code )(clipboard)(n)

説明

a=>n=>{
    // The strategy is to append the individual clipboard inputs to the end of a,
    // after the function calls (lists). We then return a[n-1] to offset JavaScript's
    // zero indexing.
    a.map(e=>{
        e[1]&& // if this list has more than one element...
            a.push(...[...e].reverse()) // add each element to a, in reverse order.
            // reverse() modifies the original array, so we have to use [...e] to "clone" e
    })
    return a[n-1]
}



2

Java 8、110バイト

ラムダ(カレー)としてクリップボード状態をとるint[][]等の数int及び戻りint又はint[](単一数はいずれかのタイプを介して戻されてもよいです)。

s->n->{if(--n<4)return s[n];else{int i=0,l;for(n-=4;(l=s[i].length)<=n|l<2;i++)n-=l>1?l:0;return s[i][l+~n];}}

オンラインで試す

非ゴルフ

s ->
    n -> {
        if (--n < 4)
            return s[n];
        else {
            int i = 0, l;
            for (
                n -= 4;
                (l = s[i].length) <= n | l < 2;
                i++
            )
                n -= l > 1 ? l : 0;
            return s[i][l + ~n];
        }
    }


2

、12バイト

!S+(m;ṁ↔f(¬ε

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

説明

Haskellの答えのかなりの直接ポート:

!S+(m;ṁ↔f(¬ε  -- example inputs: [[1],[2,3],[4],[5,6,7],[]] 7
 S+           -- concatenate itself with itself modified by
        f(    -- | filter
           ε  -- | | length 1
          ¬   -- | | not
              -- | : [[2,3],[5,6,7],[]]
      ṁ       -- | map and flatten
       ↔      -- | | reverse
              -- | : [3,2,7,6,5]
              -- | map
              -- | | pure
              -- | : [[3],[2],[7],[6],[5]]
              -- : [[1],[2,3],[4],[5,6,7],[],[3],[2],[7],[6],[5]]
!             -- index into it: [2]

2

R、58バイト

function(M,n)c(M,unlist(lapply(M[lengths(M)>1],rev)))[[n]]

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

a Mとしてlistベクトルを取りますc()。交換するそう[[list([c(])テストケースがRテストケースに変換されます。

入力の場合n<=4「未定義の動作」と、リターンNULLおよびその他の無効な入力に対して、「範囲外の添字」エラーがスローされます。

function(M,n)
                                        [[n]]	# take the nth element of
c(M,                                   )	# M concatenated with:
    unlist(                           )		# the individual elements of
           lapply(               ,rev)		# in-place reversals of
                  M[lengths(M)>1]		# elements of M with length > 1

おそらくの[n]代わりに使用して逃げることができ[[n]]ます。
JAD

2

スタックス12 14 13 バイト

àJ├∙ε╝F▀ÿi☻Ia

実行してデバッグする

説明:

vsc{%vfr$r+@]|u Full program, unpacked, implicit input
vs              Decrement the number and get the list
  c{  f         Copy and filter:
    %v            Length not equal to 1?
       r$r      Reverse, flatten, and reverse again
          +     Concat orig array and and modified array
           @]|u Index, wrap into array, uneval

スタックス、12バイト

Å{b≈\☼╣Δ@░ ‼

開梱:

{vsc{%vfr$r+@}

これはブロックなので、を取り除くことができます]|uが、ブロックをパックしているのでこれが有効かどうかわかりません。


2

J33 22バイト

FrownyFrogのソリューションのおかげで、-11バイト(1/3短縮)!

{0;],|.&.>;/@;@#~1<#&>

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

私の最初の解決策:

J、33バイト

<:@[{(,[:<"0@;[:|.&.>(1<#)&>#])@]

不幸-私はそれがもっともっとゴルフできると確信しています。

説明:

クリップボードの状態をその厳密な引数としてとる二項関数、左引数は n

<:@[ 左引数から1を引きます

{i右側のリストから(上で計算された)番目の要素を選択します

(...) リスト全体

# コピー

] クリップボード状態のリストから

(1<#) 長さが1より大きいサブリスト

|.&.> コピーされた各サブリストを回転させる

<"0@; raze and box-各番号を別々のボックスに入れます

, クリップボードの状態のリストに新しいリストを追加します

@] (...)の動詞全体を単項にします

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


@FrownyFrog私0;が一番好きです。ありがとう!
ガレンイワノフ

それは完全にあなたの解決策であり、ただゴルフをしただけです:)
FrownyFrog

2

V + coreutils53 45 43 42 40バイト

DJMcMayhemのおかげで-9バイト(使用VGÇ /d over :,$g/^[^ ]*$/dD@"ddover "aDÀddand !!overを使用:.!)!

私の最初の試み V(ヒントを歓迎します!)、以下のコードは読みやすくするために丸で囲まれた文字(例:)を使用しています\xf

jäGⓞVGÇ /d
ⓞò!!tr \  \\n|tac
jòHD@"ddjdG

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

Hexdump

00000000: 6ae4 470f 5647 c720 2f64 0a0f f221 2174  j.G.VG. /d...!!t
00000010: 7220 5c20 205c 5c6e 7c74 6163 0a6a f248  r \  \\n|tac.j.H
00000020: 4440 2264 646a 6447                      D@"ddjdG

説明

最初の行にはnが含まれ、下の行にはクリップボードのエントリが含まれます。複数の入力があった場合、各エントリはスペースで区切られます。

j                        " move to the beginning of the clipboard entries
 äG                      " duplicate the clipboard
   ⓞ                    " <C-o> move cursor to the beginning of the 2nd copy
     VG                  " select everything from cursor to the end of buffer and ..
       Ç /d              " .. delete every line that doesn't contain a space

ⓞ                       " <C-o> move cursor to the beginning of the 2nd copy (now without single arguments)
  ò                   ò  " do the following until the end of buffer
   !!                    "   on the current line execute the shell command
     tr \  \\n           "   replace spaces with newlines
              |tac⮠     "   and reverse the lines
                    j    "   move to next line

H                        " go to the beginning of buffer (where n is)
 D                       " delete n (stores it in register ")
  @"                     " that many times ..
    dd                   " .. remove the line
      j                  " move cursor to next line
       dG                " delete everything from here to the end of buffer


1

C(gcc)、176バイト

#define p printf("%d ",
int*_,i;f(x,n)int**x;{if(n<5){for(_=x[2*n-2];_-x[2*n-1];++_)p*_);}else{n-=4;for(i=0;i<8;i+=2)if(n&&x[i]+1-x[i+1])for(_=x[i+1];_-x[i]&&n;--_,--n);p*_);}}

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

配列を4つの開始/終了ポインターペアのリストとして受け取り、次にnを受け取ります。

説明:

#define p printf("%d ",  // This gives us the short-hand for printing
int*_,                   // This defines _ as a pointer to int
i;                       // This defines i as an integer
f(x,n)int**x;{           // This defines f as a function taking int **x and int n
                         // NOTE: x is {start, end, start, end, start, end, start, end}
if (n<5) {               // This is for the 1-4 case
  for(_=x[2*n-2];        // Loop _ from the 'end pointer' 
  _-x[2*n-1];++_)        // Until the 'start pointer'
  p*_);                  // Using the short-hand, print *_
}else{                   // This is for the 5+ case
  n-=4;                  // Cut n to improve indexing
  for(i=0;i<8;i+=2)      // Loop over each 'start pointer index'
    for(_=x[i+1];        // Loop _ from the 'end pointer'
        _-x[i]&&n;       // Until the 'start pointer' or n becomes 0
        --_,--n);        // Decreasing n each time
  p*_);}}                // _ now points to the 'correct' index, so print it
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.