Área de transferência de funções: colar

20

Esse desafio está relacionado a alguns dos recursos da linguagem MATL, como parte do evento de linguagem do mês de maio de 2018 . Desafio associado: Área de transferência de funções: cópia .


Introdução

A área de transferência de funções do MATL armazena ("copia") as entradas das quatro chamadas mais recentes para funções normais de recebimento de entradas. Funções normais são o tipo mais comum de funções no MATL. Entrada de entrada significa que a função recebe pelo menos uma entrada. O conteúdo da área de transferência armazenada pode ser empurrado para a pilha ("colado").

Esse desafio terá o conteúdo da área de transferência como entrada. Será assumido que todas as funções que produziram esse estado da área de transferência usaram um ou mais números inteiros positivos como entradas. Portanto, o estado da área de transferência pode ser representado por uma lista de listas de números. (Para obter mais informações sobre como a área de transferência é realmente preenchida, consulte o desafio relacionado; mas isso não é necessário para o atual).

Interpretando o conteúdo da área de transferência

Exemplo 1

A primeira lista interna refere-se à chamada de função mais recente , etc. Assim, o estado da área de transferência

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

indica que a última chamada de função levou duas entradas, ou seja 11, 28; o segundo última chamada tomou entradas 12, 16; etc. (Este estado da área de transferência é produzido pelo código no primeiro exemplo do desafio relacionado).

Exemplo 2

Se não houver chamadas de função suficientes , algumas listas internas à direita na área de transferência estarão vazias:

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

(Isso é produzido por um programa que simplesmente adiciona 7e 5).

Exemplo 3

As chamadas de função podem ter qualquer número de entradas , mas sempre pelo menos 1(funções que não recebem entradas não alteram o estado da área de transferência). Portanto, o seguinte também é possível.

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

Acessando o conteúdo da área de transferência

O conteúdo da área de transferência da função é empurrado para a pilha usando a função MATL M(que, a propósito, não é uma função normal, mas uma função da área de transferência). Essa função recebe um número inteiro positivo como entrada e empurra parte do conteúdo da área de transferência para a pilha, como segue. Com referência ao estado da área de transferência no exemplo 1:

[[11, 28], [12, 16], [4], [5, 6]]
  • 1Mretorna todas as entradas para a chamada de função mais recente. Assim, por exemplo considerado, dá 11, 28.
  • Da mesma forma, 2M, 3Me 4Mretornar todas as entradas para o segundo, terceiro e chamadas de função quarta mais recentes. Então 2M12, 16; 3M4; e 4M5, 6.
  • Números além de 4selecionar entradas individuais para chamadas de função que receberam mais de uma entrada. Então, 5Mretorna a última entrada para a chamada mais recente . No nosso caso, isso dá 28. 6Mretorna a entrada individual anterior , que é 11. 7Mretorna a última entrada da segunda última chamada, ou seja 16, e 8Mfornece 12. Agora 9M6. Observe como a entrada 4é ignorada porque foi a única entrada em sua chamada de função. Por fim, 10M5.

Para o estado da área de transferência no exemplo 3:

[[3], [2, 40, 34], [7, 8, 15], []]
  • 1M3. 2M2, 40, 34. 3M7, 8, 15.
  • 4Mtem um comportamento indefinido (para os fins deste desafio), porque houve apenas três chamadas de função.
  • 5M34. 6M40. 7M2. 8M15. 9M8, 10M7.
  • 11M, 12M... também têm um comportamento indefinido .

O desafio

Entrada :

  • o estado da área de transferência, como uma lista de listas ou qualquer outro formato razoável;
  • um número inteiro positivo n .

Saída : o resultado da chamada da função Mcom n como entrada. A saída será um ou vários números com um separador inequívoco ou em qualquer formato razoável, como uma lista ou matriz.

Esclarecimentos:

  • O estado da área de transferência consiste em quatro listas de números. Algumas das listas finais podem estar vazias, como nos exemplos 2 e 3. Se preferir, você pode inserir a área de transferência sem essas listas vazias. Então, o exemplo 3 se tornaria [[3], [2, 40, 34], [7, 8, 15]].
  • Todos os números na área de transferência serão números inteiros positivos, possivelmente com mais de um dígito.
  • O número n é garantido como válido. Portanto, por exemplo 3 acima, nnão pode ser 4ou 11.

Regras adicionais:

Casos de teste

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
Luis Mendo
fonte
Podemos pegar um n indexado a 0 ?
Arnauld
3
@Arnauld eu vou dizer não, pois isso é baseado no comportamento real do MATL
Luis Mendo

Respostas:

3

Gelatina , 8 bytes

ḊƇUẎ⁸;⁹ị

Experimente online!

Erik, o Outgolfer
fonte
2
Você se importa de adicionar uma explicação?
LordColus
O @LordColus ḊƇseleciona todos os não-singletons, Uinverte e achata. Para entrada que [[11, 28], [12, 16], [4], []]obtém [16, 12, 28, 11], os valores de 5Mthrough 8M. Agora, anexe a entrada original a esta lista ⁸;e indexe-a na lista resultante pela outra entrada ⁹ị.
Lynn
@ LordColus Ah, desculpe, eu só adiciono explicações a pedido (porque ninja), mas eu estava dormindo. Lynn explicou bastante, no entanto, gostaria de acrescentar que Unão inverte o resultado ḊƇ, mas sim cada um de seus elementos. Só se eu pudesse de alguma forma reduzir ḊƇUẎ⁸;...
Erik o Outgolfer
4

Haskell , 56 51 47 bytes

-5 -9 bytes graças ao Laikoni (correspondência de padrão para garantir comprimento> 1 e usando do-notation sobre a compreensão da lista)!

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

Experimente online!

Sem ponto, 58 55 bytes

-3 bytes graças ao Laikoni (movendo ([]:)e substituindo id)!

Como alternativa, poderíamos usar esta versão pointfree

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

ბიმო
fonte
3

JavaScript (Node.js) , 57 bytes

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

Experimente online!

Esta é uma função anônima com curry. Execute-o com( function code )(clipboard)(n)

Explicação

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
fonte
2

JavaScript (ES6), 72 bytes

Recebe entrada na sintaxe de 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)

Experimente online!

Arnauld
fonte
2

Java 8, 110 bytes

Um lambda (com curry) assumindo o estado da área de transferência como um int[][]e o número como inte retornando intou int[](um único número pode ser retornado por qualquer um dos tipos).

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

Experimente Online

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
fonte
2

05AB1E , 12 bytes

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

Experimente online!

Explicação

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
fonte
2

Casca , 12 bytes

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

Experimente online!

Explicação

Praticamente uma porta direta da resposta 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]
ბიმო
fonte
2

R , 58 bytes

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

Experimente online!

Toma Mcomo um listdos vetores c(); portanto, substituir [[por list(, [por c(e ]com )deve transformar os casos de teste em R. casos de teste.

Para entradas n<=4com "comportamento indefinido", retornos NULLe para outras entradas inválidas, gera um erro "subscrito fora dos limites".

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
fonte
Provavelmente poderia se safar usando em [n]vez de [[n]].
JAD
2

Stax , 12 14 13 bytes

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

Execute e depure

Explicação:

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 bytes

Å{b≈\☼╣Δ@░ ‼

Desembalado:

{vsc{%vfr$r+@}

Este é um bloco, para que eu possa me livrar dele ]|u, mas não sei se isso é válido, pois está compactando um bloco.

wastl
fonte
2

J , 33 22 bytes

-11 bytes (1/3 menor), graças à solução da FrownyFrog!

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

Experimente online!

Minha solução inicial:

J , 33 bytes

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

Não feliz - tenho certeza de que pode ser jogado muito mais longe.

Explicação:

Uma função diádica, tomando o estado da área de transferência como seu argumento rígido, o argumento da esquerda é n

<:@[ subtrair 1 do argumento esquerdo

{seleciona o ith elemento (calculado acima) da lista à direita

(...) a lista inteira

# cópia de

] da lista de estados da área de transferência

(1<#) os sublistas com comprimento maior que 1

|.&.> gire cada sub-lista copiada

<"0@; raze and box - coloca cada número em uma caixa separada

, anexar a nova lista à lista de estados da área de transferência

@] torna o verbo inteiro em (...) monádico

Experimente online!

Galen Ivanov
fonte
@FrownyFrog Eu gosto 0;mais. Obrigado!
Galen Ivanov
Isso é totalmente a sua solução, apenas golfed :)
FrownyFrog
2

Coreutils V + , 53 45 43 42 40 bytes

-9 bytes graças a DJMcMayhem (usando VGÇ /dmais :,$g/^[^ ]*$/d, D@"ddmais "aDÀdde !!mais :.!)!

Minha primeira tentativa de V (dicas bem-vindas!), O código abaixo está usando caracteres circulados (por exemplo, for \xf) para facilitar a leitura:

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

Experimente online!

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

Explicação

A primeira linha contém n e as linhas abaixo contêm as entradas da área de transferência, cada entrada é separada por espaços se houver várias entradas:

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
ბიმო
fonte
1

Vermelho , 91 bytes

func[b n][a: copy[]foreach c b[if 1 < length? c[append a reverse copy c]]pick append b a n]

Experimente online!

Galen Ivanov
fonte
1

C (gcc) , 176 bytes

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

Experimente online!

Toma a matriz como uma lista de 4 pares de ponteiros de início / fim e, em seguida, n.

Descrição:

#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
fonte