功能剪贴板:粘贴


20

作为2018年5月每月语言活动的一部分,此挑战与MATL语言的某些功能有关 相关挑战: 功能剪贴板:复制


介绍

MATL的功能剪贴板将输入(存储到“副本”)存储到最近四个对常规输入函数的调用中。普通函数是MATL中最常见的函数类型。输入接受是指该功能至少接受一个输入。可以将存储的剪贴板内容推入堆栈(“粘贴”)。

此挑战将剪贴板内容作为输入。将假定所有产生剪贴板状态的函数都将一个或多个正整数作为输入。因此剪贴板状态可以用数字列表来表示。(有关如何实际填充剪贴板的更多信息,请参见相关挑战;但这对于当前挑战不是必需的)。

解释剪贴板内容

例子1

一个内部列表引用最近的函数调用,依此类推,因此剪贴板状态

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

表示最后的函数调用了两个输入,即1128; 倒数第二个电话花了投入1216; 等等(此剪贴板状态由相关挑战的第一个示例中的代码产生)。

例子2

如果没有足够的函数调用,剪贴板中的某些尾部内部列表将为空:

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

(这是由一个简单地添加7和的程序产生的5)。

例子3

函数调用可以具有任意数量的input,但至少可以是所有输入1(不接受任何输入的函数不会更改剪贴板状态)。因此,以下也是可能的。

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

访问剪贴板内容

使用MATL的功能M(顺便说一句,它不是普通功能,而是剪贴板功能)将功能剪贴板的内容压入堆栈。此函数将一个正整数作为输入,并将某些剪贴板内容压入堆栈,如下所示。参考示例1中的剪贴板状态:

[[11, 28], [12, 16], [4], [5, 6]]
  • 1M所有输入返回到最近的函数调用。因此,对于所讨论的例子,它给1128
  • 同样,2M3M4M所有输入返回到第二,第三和第四最近的函数调用。所以2M给人1216; 3M4; 并4M给出了56
  • 超越号4选择各个输入以占用多个的函数调用。因此,5M最后一个输入返回到最近的此类调用。就我们而言,这给出了286M返回前面的单个输入,即117M返回倒数第二个调用的最后一个输入,即16,并8M给出12。现在,9M给出6。请注意如何4跳过输入,因为它是函数调用中的唯一输入。最后,10M给出5

对于示例3中的剪贴板状态:

[[3], [2, 40, 34], [7, 8, 15], []]
  • 1M32M给人240343M给人7815
  • 4M具有不确定的行为(针对此挑战),因为只有三个函数调用。
  • 5M346M407M28M159M810M7
  • 11M、、12M...也具有未定义的行为

挑战

输入

  • 剪贴板状态,列表列表或任何其他合理格式;
  • 正整数n

输出Mn调用函数的结果为输入。输出将是带有明确分隔符的一个或多个数字,或采用任何合理的格式(例如列表或数组)。

说明:

  • 剪贴板状态由四个数字列表组成。某些尾随列表可能为空,如示例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的实际行为
Luis Mendo,

Answers:


3

果冻,8字节

ḊƇUẎ⁸;⁹ị

在线尝试!


2
您介意添加说明吗?
LordColus

@LordColus ḊƇ选择所有非单字母,U反向并展平。对于输入[[11, 28], [12, 16], [4], []]该得到[16, 12, 28, 11]的值5M通过8M。现在,将原始输入⁸;放在该列表的前面,并用其他输入将其索引到结果列表中⁹ị
林恩

@LordColus啊,对不起,我仅应要求添加解释(因为忍者),但我睡着了。Lynn对此进行了相当多的解释,但是我想补充一点,U它不会颠倒的结果ḊƇ,而是颠倒它的每个元素。只有当我能以某种方式减少ḊƇUẎ⁸;...
暴民埃里克



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

JavaScript(ES6),72个字节

以currying语法接受输入(clipboard)(n)

a=>m=>a[m-1]||(g=r=>(r=r|a[k][1]&&a[k].pop())?--m<5?r:g(1):g(!++k))(k=0)

在线尝试!



2

Java 8,110字节

一个lambda(已固化),以剪贴板状态为an int[][],数字为an,int然后返回intor 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

05AB1E,12个字节

Díʒg<Ā}˜«s<è

在线尝试!

说明

D              # duplicate input list
 í             # reverse each
  ʒg<Ā}        # filter, keep only elements that are longer than 1
       ˜       # flatten
        «      # append to original list
         s<    # decrement the second input
           è   # get the element in the list at that index

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

在线尝试!

Mlist向量c(); 因此,用,替换[[为和替换应将测试用例转换为R测试用例。list([c(])

对于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

Stax12 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

Stax,12个字节

Å{b≈\☼╣Δ@░ ‼

开箱

{vsc{%vfr$r+@}

这是一个块,所以我可以摆脱]|u,但是我不知道这是否有效,因为它正在包装一个块。


2

Ĵ33 22字节

-11字节(短1/3)归功于FrownyFrog的解决方案!

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

在线尝试!

我最初的解决方案:

J,33个字节

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

不高兴-我很确定它可以打得更远。

说明:

一个二进位函数,以剪贴板状态为其严格参数,左参数为 n

<:@[ 从左引数减去1

{ 选择 i从右边的列表中 th个元素(上面计算得出)

(...) 整个清单

# 复制

] 从剪贴板状态列表

(1<#) 长度大于1的子列表

|.&.> 旋转每个复制的子列表

<"0@; raze and box-将每个数字放入一个单独的盒子

, 将新列表追加到剪贴板状态列表

@] 使整个动词变为(...)单子

在线尝试!


0;最喜欢@FrownyFrog 。谢谢!
加伦·伊凡诺夫

高尔夫,这完全是您的解决方案:)
FrownyFrog

2

V + coreutils53 45 43 42 40字节

-9个字节感谢DJMcMayhem(使用VGÇ /dover :,$g/^[^ ]*$/dD@"ddover "aDÀdd!!over :.!)!

我第一次尝试使用V(欢迎使用提示!),以下代码使用带圆圈的字符(例如表示\xf)以提高可读性:

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

在线尝试!

十六进制转储

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.