Буфер обміну функцій: вставити


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

Чи можемо ми взяти n -індексований n ?
Арнольд

3
@Arnauld Я хочу сказати "ні", оскільки це базується на фактичній поведінці MATL
Луїс Мендо

Відповіді:


3

Желе , 8 байт

ḊƇUẎ⁸;⁹ị

Спробуйте в Інтернеті!


2
Ви не проти додати пояснення?
LordColus

@LordColus ḊƇвиберіть усі не- однократні , Uпереверніть та згладьте. Для введення [[11, 28], [12, 16], [4], []]цього отримуються [16, 12, 28, 11]значення 5Mчерез 8M. Тепер додайте початковий вхід до цього списку ⁸;та індексуйте в отриманий список іншим входом ⁹ị.
Лінн

@LordColus Ах, вибачте, я додаю лише пояснення на запит (бо ніндзя), але я спав. Лінн це дуже пояснила, проте хотілося б додати, що результат Uне зворотно ḊƇ, а скоріше кожен з його елементів. Тільки якби я міг якось зменшити ḊƇUẎ⁸;...
Ерік Атголфер

4

Haskell , 56 51 47 байт

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

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

Спробуйте в Інтернеті!

Pointfree, 58 55 байт

-3 байти завдяки Laikoni (переміщення ([]:)та заміна 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]
}



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

Спробуйте в Інтернеті!

Приймає 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

J , 33 22 байти

-11 байт (на 1/3 коротше) завдяки рішенню FrownyFrog!

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

Спробуйте в Інтернеті!

Моє початкове рішення:

J , 33 байти

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

Не щасливий - я майже впевнений, що можна пограти набагато далі.

Пояснення:

Діадична функція, яка приймає стан буфера обміну за свій жорсткий аргумент, аргумент зліва - це n

<:@[ відніміть 1 з лівого аргументу

{вибирає ith елемент (обчислений вище) зі списку праворуч

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

# копія

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

(1<#) підсписки довжиною більше 1

|.&.> обертання кожного скопійованого підпису

<"0@; raze і box - поміщає кожне число в окремий ящик

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

@] робить все дієслово в (...) монадічним

Спробуйте в Інтернеті!


@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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.