Schowek funkcji: wklej

20

Wyzwanie to jest związane z niektórymi funkcjami języka MATL w ramach wydarzenia Język miesiąca miesiąca 2018 . Powiązane wyzwanie: Schowek funkcji: kopia .


Wprowadzenie

Schowek funkcji MATL przechowuje („kopiuje”) dane wejściowe czterech ostatnich wywołań normalnych funkcji pobierających dane. Funkcje normalne są najczęstszym typem funkcji w MATL. Pobieranie danych oznacza, że ​​funkcja pobiera co najmniej jedno wejście. Zapisaną zawartość schowka można wepchnąć na stos („wkleić”).

To wyzwanie weźmie zawartość schowka jako dane wejściowe. Zakłada się, że wszystkie funkcje, które wytworzyły ten stan schowka, przyjęły jedną lub więcej dodatnich liczb całkowitych jako dane wejściowe. Tak więc stan schowka może być reprezentowany przez listę list liczb. (Aby uzyskać więcej informacji na temat faktycznego wypełnienia schowka, zobacz powiązane wyzwanie; ale nie jest to konieczne w przypadku bieżącego).

Interpretacja zawartości schowka

Przykład 1

Pierwsza lista wewnętrzna odnosi się do najnowszego wywołania funkcji, i tak dalej, w ten sposób stan schowka

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

wskazuje, że ostatnie wywołanie funkcji trwało dwa wejścia, a mianowicie 11, 28; przedostatni wezwanie wziął wejść 12, 16; itp. (Ten stan schowka jest generowany przez kod w pierwszym przykładzie pokrewnego wyzwania).

Przykład 2

Jeśli nie ma wystarczającej liczby wywołań funkcji , niektóre końcowe listy wewnętrzne w schowku będą puste:

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

(Jest to wytwarzane przez program, który po prostu dodaje 7i 5).

Przykład 3

Wywołania funkcji mogą mieć dowolną liczbę wejść , ale zawsze przynajmniej 1(funkcje nie przyjmujące danych wejściowych nie zmieniają stanu schowka). Możliwe są również następujące kwestie.

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

Dostęp do zawartości schowka

Zawartość schowka funkcji jest wypychana na stos za pomocą funkcji MATL M(która, nawiasem mówiąc, nie jest normalną funkcją, ale funkcją schowka). Ta funkcja przyjmuje na wejściu dodatnią liczbę całkowitą i wypycha część zawartości schowka na stos, w następujący sposób. W odniesieniu do stanu schowka w przykładzie 1:

[[11, 28], [12, 16], [4], [5, 6]]
  • 1Mzwraca wszystkie dane wejściowe do ostatniego wywołania funkcji. Tak więc, na rozpatrywanym przykładzie, to daje 11, 28.
  • Podobnie 2M, 3Mi 4Mzwrócić wszystkie wejścia do drugiej, trzeciej i czwartej najnowsze wywołania funkcji. Więc 2Mdaje 12, 16; 3Mdaje 4; i 4Mdaje 5, 6.
  • Liczby poza 4wybranymi pojedynczymi wejściami do wywołań funkcji, które wymagały więcej niż jednego wejścia. 5MZwraca więc ostatnie dane wejściowe do ostatniego takiego wywołania. W naszym przypadku daje to 28. 6Mzwraca poprzednie indywidualne wejście, którym jest 11. 7Mzwraca ostatnie wejście drugiego przedostatniego wywołania, czyli 16, i 8Mdaje 12. Teraz 9Mdaje 6. Zwróć uwagę, w jaki sposób dane wejściowe 4są pomijane, ponieważ były to jedyne dane wejściowe w wywołaniu funkcji. Wreszcie 10Mdaje 5.

Dla stanu schowka w przykładzie 3:

[[3], [2, 40, 34], [7, 8, 15], []]
  • 1Mdaje 3. 2Mdaje 2, 40, 34. 3Mdaje 7, 8, 15.
  • 4Mma niezdefiniowane zachowanie (na potrzeby tego wyzwania), ponieważ były tylko trzy wywołania funkcji.
  • 5Mdaje 34. 6Mdaje 40. 7Mdaje 2. 8Mdaje 15. 9Mdaje 8, 10Mdaje 7.
  • 11M, 12M... także niezdefiniowane zachowanie .

Wyzwanie

Wejście :

  • stan schowka, jako listę list lub w dowolnym innym rozsądnym formacie;
  • dodatnia liczba całkowita n .

Wyjście : wynik wywołania funkcji Mz n jako wejściem. Dane wyjściowe będą jedną lub kilkoma liczbami z jednoznacznym separatorem lub w dowolnym rozsądnym formacie, takim jak lista lub tablica.

Wyjaśnienia:

  • Stan schowka składa się z czterech list liczb. Niektóre końcowe listy mogą być puste, jak w przykładach 2 i 3. W razie potrzeby można wprowadzić schowek bez tych końcowych pustych list. Tak stałby się przykład 3 [[3], [2, 40, 34], [7, 8, 15]].
  • Wszystkie liczby w schowku będą dodatnimi liczbami całkowitymi, prawdopodobnie z więcej niż jedną cyfrą.
  • Gwarantowana jest liczba n . Na przykład 3 powyżej nnie może być 4lub 11.

Dodatkowe zasady:

Przypadki testowe

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
źródło
Czy możemy wziąć n indeksowane według 0 ?
Arnauld,
3
@Arnauld Powiem nie, ponieważ jest to oparte na faktycznym zachowaniu MATL
Luis Mendo,

Odpowiedzi:

3

Galaretka , 8 bajtów

ḊƇUẎ⁸;⁹ị

Wypróbuj online!

Erik the Outgolfer
źródło
2
Czy masz coś przeciwko dodaniu wyjaśnienia?
LordColus
@ LordColus ḊƇzaznacz wszystkie nie singletony, Uodwróć i spłaszcz. Dla danych wejściowych pobierane [[11, 28], [12, 16], [4], []][16, 12, 28, 11]wartości 5Mprzelotowe 8M. Teraz dodaj oryginalne dane wejściowe do tej listy ⁸;i indeksuj do listy wynikowej przez inne dane wejściowe ⁹ị.
Lynn,
@ LordColus Ach, przepraszam, dodaję wyjaśnienia tylko na życzenie (ponieważ ninja), ale spałem. Lynn prawie to wyjaśnił, jednak chciałbym dodać, że Unie odwraca wyniku ḊƇ, ale raczej każdy z jego elementów. Tylko gdybym mógł jakoś zmniejszyć ḊƇUẎ⁸;...
Erik the Outgolfer
3

JavaScript (Node.js) , 57 bajtów

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

Wypróbuj online!

To anonimowa funkcja curry. Uruchom to z( function code )(clipboard)(n)

Wyjaśnienie

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
źródło
2

JavaScript (ES6), 72 bajty

Pobiera dane wejściowe w składni curry (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)

Wypróbuj online!

Arnauld
źródło
2

Java 8, 110 bajtów

Lambda (curry) przyjmująca stan schowka jako int[][]cyfrę i liczbę jako inti zwraca intlub int[](pojedyncza liczba może zostać zwrócona przez dowolny typ).

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

Wypróbuj online

Nie golfił

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
źródło
2

05AB1E , 12 bajtów

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

Wypróbuj online!

Wyjaśnienie

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
źródło
2

Łuska , 12 bajtów

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

Wypróbuj online!

Wyjaśnienie

Prawie bezpośredni port odpowiedzi 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]
ბიმო
źródło
2

R , 58 bajtów

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

Wypróbuj online!

Pobiera Mjako listwektory c(); więc zastąpienie [[ze list(, [ze c(i ]ze )powinien przekształcić przypadków testowych do przypadków testowych R.

W przypadku danych wejściowych n<=4z „niezdefiniowanym zachowaniem” zwraca wartość, NULLa dla innych nieprawidłowych danych wejściowych wyrzuca błąd „poza indeksem”.

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
źródło
Prawdopodobnie można by uniknąć używania [n]zamiast [[n]].
JAD
2

Stax , 12 14 13 bajtów

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

Uruchom i debuguj

Wyjaśnienie:

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 bajtów

Å{b≈\☼╣Δ@░ ‼

Rozpakowane:

{vsc{%vfr$r+@}

To jest blok, więc mogę się go pozbyć ]|u, ale nie wiem, czy jest to poprawne, ponieważ pakuje blok.

pustkowie
źródło
2

J , 33 22 bajtów

-11 bajtów (1/3 mniej) dzięki rozwiązaniu FrownyFrog!

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

Wypróbuj online!

Moje wstępne rozwiązanie:

J , 33 bajty

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

Nie jestem szczęśliwy - jestem pewien, że można grać w golfa znacznie dalej.

Wyjaśnienie:

Funkcja dyadyczna, przyjmująca stan schowka jako swój argument, lewy argument to n

<:@[ odejmij 1 od lewego argumentu

{wybiera ielement th (obliczony powyżej) z listy po prawej stronie

(...) cała lista

# Kopiuj

] z listy stanu schowka

(1<#) podlisty o długości większej niż 1

|.&.> obróć każdą skopiowaną podlistę

<"0@; raze and box - umieszcza każdą liczbę w osobnym polu

, dołącz nową listę do listy stanu schowka

@] czyni cały czasownik w (...) monadycznym

Wypróbuj online!

Galen Iwanow
źródło
@FrownyFrog 0;Najbardziej lubię . Dzięki!
Galen Iwanow
To całkowicie twoje rozwiązanie, właśnie
grałem w
2

V + coreutils , 53 45 43 42 40 bajtów

-9 bajty dzięki DJMcMayhem (przy użyciu VGÇ /dponad :,$g/^[^ ]*$/d, D@"ddponad "aDÀddi !!powyżej :.!)!

Moja pierwsza próba V (porady mile widziane!), Poniższy kod używa kółka (np. Dla \xf) dla czytelności:

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

Wypróbuj 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

Wyjaśnienie

Pierwszy wiersz zawiera n, a poniższe wiersze zawierają wpisy schowka, każdy wpis jest oddzielony spacjami, jeśli było wiele danych wejściowych:

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
ბიმო
źródło
1

Czerwony , 91 bajtów

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

Wypróbuj online!

Galen Iwanow
źródło
1

C (gcc) , 176 bajtów

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

Wypróbuj online!

Bierze tablicę jako listę 4 par wskaźników początek / koniec, a następnie n.

Opis:

#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
źródło