Функция буфера обмена: вставка

20

Эта проблема связана с некоторыми возможностями языка MATL в рамках мероприятия « Язык месяца», который состоится в мае 2018 года . Сопутствующий вызов: Функция буфера обмена: копия .


Вступление

Буфер обмена функций MATL хранит («копирует») входные данные для четырех самых последних вызовов обычных функций ввода. Нормальные функции - самый распространенный тип функций в MATL. Взятие ввода означает, что функция берет по крайней мере один ввод. Сохраненное содержимое буфера обмена может быть помещено в стек («вставлено»).

Эта задача будет принимать содержимое буфера обмена в качестве входных данных. Предполагается, что все функции, которые создали это состояние буфера обмена, приняли одно или несколько положительных целых чисел в качестве входных данных. Таким образом, состояние буфера обмена может быть представлено списком номеров. (Для получения дополнительной информации о том, как фактически заполнен буфер обмена, см. Связанную проблему, но для текущей это не обязательно).

Интерпретация содержимого буфера обмена

Пример 1

Первый внутренний список относится к самому последнему вызову функции, и так далее, таким образом, состояние буфера обмена

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

указывает на то, что вызов последней функции взял два входа, а именно 11, 28; второй последний вызов принял входы 12, 16; и т. д. (Это состояние буфера обмена создается кодом в первом примере связанной задачи).

Пример 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возвращает все входные данные для самого последнего вызова функции. Таким образом, для рассматриваемого примера, он дает 11, 28.
  • Точно так же 2M, 3Mи 4Mвернуть все входы на второй, третий и четвертый самые последние вызовы функций. Таким образом , 2Mдает 12, 16; 3Mдает 4; и 4Mдает 5, 6.
  • Числа за пределами 4выбирают отдельные входы для вызовов функций, которые занимали более одного входа. Поэтому 5Mвозвращает последний ввод для самого последнего такого вызова. В нашем случае это дает 28. 6Mвозвращает предыдущий отдельный вход, который 11. 7Mвозвращает последний ввод второго по последнему вызову, то есть 16и 8Mдает 12. Теперь 9Mдает 6. Обратите внимание, как ввод 4пропускается, потому что это был единственный ввод при вызове функции. Наконец, 10Mдает 5.

Для состояния буфера обмена в примере 3:

[[3], [2, 40, 34], [7, 8, 15], []]
  • 1Mдает 3. 2Mдает 2, 40, 34. 3Mдает 7, 8, 15.
  • 4Mимеет неопределенное поведение (для целей этой задачи), потому что было только три вызова функций.
  • 5Mдает 34. 6Mдает 40. 7Mдает 2. 8Mдает 15. 9Mдает 8, 10Mдает 7.
  • 11M, 12M... также есть неопределенное поведение .

Соревнование

Вход :

  • состояние буфера обмена в виде списка списков или любого другого приемлемого формата;
  • положительное целое число n .

Выход : результат вызова функции Mс n в качестве ввода. Выходными данными будут одно или несколько чисел с однозначным разделителем или в любом приемлемом формате, таком как список или массив.

Разъяснения:

  • Состояние буфера обмена состоит из четырех списков чисел. Некоторые из конечных списков могут быть пустыми, как в примерах 2 и 3. При желании вы можете ввести буфер обмена без этих конечных пустых списков. Так что пример 3 станет [[3], [2, 40, 34], [7, 8, 15]].
  • Все числа в буфере обмена будут положительными целыми числами, возможно, с более чем одной цифрой.
  • Число n гарантированно будет действительным. Так, например, 3 выше, nне может быть 4или 11.

Дополнительные правила:

Контрольные примеры

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Ẏ⁸;⁹ị

Попробуйте онлайн!

Эрик Outgolfer
источник
2
Вы не против добавить объяснение?
LordColus
@LordColus ḊƇвыделите все несинглетоны , Uпереверните и сгладьте. Для ввода [[11, 28], [12, 16], [4], []]это получает [16, 12, 28, 11]значения 5Mчерез 8M. Теперь добавьте исходный ввод в этот список ⁸;и внесите в результирующий список другой вход ⁹ị.
Линн
@LordColus Ах, извините, я только добавляю объяснения по запросу (потому что ниндзя), но я спал. Линн в значительной степени объяснила это, однако я хотел бы добавить, что Uэто не меняет результат ḊƇ, а скорее на каждый из его элементов. Только если бы я мог как-то уменьшить ḊƇUẎ⁸;...
Эрик Outgolfer
4

Haskell , 56 51 47 байт

-5 -9 байт благодаря Laikoni (сопоставление с образцом, чтобы обеспечить длину> 1 и использование do-notation над списком понимания)!

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

Попробуйте онлайн!

Pointfree, 58 55 байт

-3 байта благодаря Лайкони (перемещение ([]:)и замена id)!

В качестве альтернативы мы могли бы использовать эту версию без очков

(!!).(([]:)<>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]
}
NinjaBearMonkey
источник
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];}}

Попробуйте онлайн

Ungolfed

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];
        }
    }
Jakob
источник
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
Emigna
источник
2

Шелуха , 12 байт

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

Попробуйте онлайн!

объяснение

Практически прямой порт ответа Хаскелла:

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

Попробуйте онлайн!

Принимает 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
Giuseppe
источник
Возможно, сойдет с рук с использованием [n]вместо [[n]].
JAD
2

Stax , 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

Stax, 12 байт

Å{b≈\☼╣Δ@░ ‼

Распакованный:

{vsc{%vfr$r+@}

Это блок, поэтому я могу избавиться от него ]|u, но я не знаю, допустимо ли это, поскольку он упаковывает блок.

Wastl
источник
2

J , 33 22 байта

-11 байт (на 1/3 короче) благодаря решению FrownyFrog!

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

Попробуйте онлайн!

Мое первоначальное решение:

J , 33 байта

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

Не рад - я уверен, что это может быть сделано в гольф гораздо дальше.

Объяснение:

Диадическая функция, принимающая состояние буфера обмена в качестве своего правого аргумента, левый аргумент n

<:@[ вычтите 1 из левого аргумента

{выбирает iэлемент th (рассчитанный выше) из списка справа

(...) весь список

# копия

] из списка состояния буфера обмена

(1<#) подсписки длиной более 1

|.&.> вращать каждый скопированный список

<"0@; никак и коробка - помещает каждый номер в отдельную коробку

, добавить новый список в список состояний буфера обмена

@] делает весь глагол в (...) монадическом

Попробуйте онлайн!

Гален Иванов
источник
@FrownyFrog Мне нравится 0;больше всего. Благодарность!
Гален Иванов
Это полностью ваше решение, просто игра в гольф :)
FrownyFrog
2

V + coreutils , 53 45 43 42 40 байт

-9 байт благодаря DJMcMayhem (используя VGÇ /dснова :,$g/^[^ ]*$/d, D@"ddснова "aDÀddи !!снова :.!)!

Моя самая первая попытка 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
LambdaBeta
источник