İşlev panosu: yapıştır


20

Bu zorluk, Mayıs 2018 Ayın Dili etkinliğinin bir parçası olarak MATL dilinin bazı özellikleri ile ilgilidir . İlişkili zorluk: İşlev panosu: kopyalama .


Giriş

MATL'in fonksiyon panosu , girişleri normal, giriş alma işlevlerine yapılan en son dört çağrının içinde saklar ("kopyalar"). Normal işlevler, MATL'de en yaygın işlev türüdür. Giriş alma , işlevin en az bir giriş alması anlamına gelir. Saklanan pano içeriği yığının üzerine itilebilir ("yapıştırıldı").

Bu meydan okuma pano içeriğini girdi olarak alacaktır. Pano durumunu üreten tüm işlevlerin girdi olarak bir veya daha fazla pozitif tamsayı aldığı varsayılacaktır. Böylece pano durumu bir sayı listesi listesi ile temsil edilebilir. (Panonun gerçekte nasıl doldurulduğu hakkında daha fazla bilgi için ilgili zorluğa bakın; ancak mevcut olan için bu gerekli değildir).

Pano içeriklerini yorumlama

örnek 1

İlk iç liste atıfta En son , böyle devam Böylece pano durumunu işlev çağrısı ve

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

Son işlev çağrısı iki giriş aldı işaret eder, yani 11, 28; ikinci son çağrı girişlerini aldı 12, 16; (Bu pano durumu ilgili zorluğun ilk örneğindeki kod tarafından üretilir).

ÖRNEK 2

Eğer yeterince işlev çağrıları var olmamıştır , panoya bazı sondaki iç listeler boş olacaktır:

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

(Bu sadece 7ve ekleyen bir program tarafından üretilir 5).

ÖRNEK 3

İşlev çağrıları herhangi bir sayıda giriş içerebilir , ancak her zaman en azından 1(giriş almayan işlevler pano durumunu değiştirmez). Böylece aşağıdakiler de mümkündür.

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

Pano içeriğine erişme

İşlev panosunun içeriği, MATL'nin işlevi kullanılarak yığına itilir M(bu arada, normal bir işlev değil, bir pano işlevi). Bu işlev giriş olarak pozitif bir tamsayı alır ve pano içeriğinin bazılarını aşağıdaki gibi yığının üzerine iter. Örnek 1'deki pano durumuna referansla:

[[11, 28], [12, 16], [4], [5, 6]]
  • 1Mtüm girişleri en son işlev çağrısına döndürür . Yani, dikkate alınan örneğin o verir 11, 28.
  • Benzer şekilde, 2M, 3Mve 4Mikinci, üçüncü, tüm giriş geri ve dördüncü son işlev çağrıları. Yani 2Mverir 12, 16; 3Mverir 4; ve 4Mverir 5, 6.
  • Birden fazla giriş alan çağrıları işlevlendirmek için 4belirli girişlerin ötesindeki sayılar . Böylece son girdiyi bu tür en son çağrıya döndürür . Bizim durumumuzda bu verir . önceki bağımsız girdiyi döndürür . ikinci son aramanın son girişini, yani , ve verir . Şimdi verir . İşlev çağrısındaki tek girdi olduğundan girdinin nasıl atlandığına dikkat edin . Son olarak verir .5M286M117M168M129M6410M5

Örnek 3'teki pano durumu için:

[[3], [2, 40, 34], [7, 8, 15], []]
  • 1Mverir 3. 2Mverir 2, 40, 34. 3Mverir 7, 8, 15.
  • 4Mvardır tanımsız davranış sadece üç işlev çağrıları olmuştur, çünkü (bu meydan amaçları için).
  • 5Mverir 34. 6Mverir 40. 7Mverir 2. 8Mverir 15. 9Mverir 8, 10Mverir 7.
  • 11M,, 12M... ayrıca tanımsız davranışa sahiptir .

Meydan okuma

Giriş :

  • panoların listesi, liste listesi veya diğer makul biçimler;
  • pozitif bir tam sayı , n .

Çıktı : giriş olarak nM ile çağırma fonksiyonunun sonucu . Çıktı, açık bir ayırıcıya sahip bir veya birkaç sayı veya liste veya dizi gibi makul bir biçimde olacaktır.

Açıklamalar:

  • Pano durumu dört sayı listesinden oluşur. Takip eden listelerin bazıları örnek 2 ve 3'te olduğu gibi boş olabilir. İstenirse, panoya bu boş listeler olmadan giriş yapabilirsiniz. Böylece örnek 3 olur [[3], [2, 40, 34], [7, 8, 15]].
  • Panodaki tüm sayılar, muhtemelen birden fazla rakamla pozitif tamsayılar olacaktır.
  • N sayısının geçerli olduğu garanti edilir. Yani yukarıdaki örnekte 3, nolamaz 4ya 11.

Ek kurallar:

Test senaryoları

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 indeksli n alabilir miyiz ?
Arnauld

3
Bu Matl gerçek davranışına dayanmaktadır olarak @Arnauld ben hayır demek için gidiyorum
Luis Mendo

Yanıtlar:


3

Jöle , 8 bayt

ḊƇUẎ⁸;⁹ị

Çevrimiçi deneyin!


2
Bir açıklama eklemeyi düşünür müsünüz?
LordColus

@ LordColus ḊƇtüm tekil olmayanları seçer, Utersine ve düzleştirir. Girdi için [[11, 28], [12, 16], [4], []]bu alır [16, 12, 28, 11], 5Maracılığıyla değerleri 8M. Şimdi orijinal girişi bu listeye ekleyin ⁸;ve diğer girdinin sonuç listesine ekleyin ⁹ị.
Lynn

@LordColus Ah, üzgünüm, sadece istek üzerine açıklamalar ekliyorum (çünkü ninja), ama uyuyordum. Lynn hemen hemen açıkladı, ancak eklemek istiyorum U, bunun sonucunu tersine çevirmez ḊƇ, aksine her bir unsurunu tersine çevirir . Sadece bir şekilde azaltabilirsem ḊƇUẎ⁸;...
Outgolfer Erik



3

JavaScript (Node.js) , 57 bayt

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

Çevrimiçi deneyin!

Bu anonim, curried bir işlevdir. Şununla çalıştır( function code )(clipboard)(n)

açıklama

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 bayt

Körili sözdiziminde girdi alır (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)

Çevrimiçi deneyin!



2

Java 8, 110 bayt

Pano durumunu bir int[][]ve bir sayı olarak alan intve dönen intveya int[](tek bir sayı her iki türden de döndürülebilir ) olarak alan bir lambda (curried ).

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

Çevrimiçi Deneyin

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

2

05AB1E , 12 bayt

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

Çevrimiçi deneyin!

açıklama

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

Kabuk , 12 bayt

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

Çevrimiçi deneyin!

açıklama

Haskell cevabının hemen hemen doğrudan bir limanı:

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

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

Çevrimiçi deneyin!

Alır Mbir şekilde listvektörler c(); değiştirilmesi böylece [[ile list(, [ile c(ve ]ile) R, test durumları içine test durumlarda dönüştürmek gerekir.

n<=4"Tanımlanmamış davranış" olan girdiler , döndürür NULLve diğer geçersiz girdiler için, "alt simge sınırların dışına" hatası atar.

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

Muhtemelen [n]yerine kullanarak kaçmak olabilir [[n]].
JAD

2

Stax , 12 14 13 bayt

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

Çalıştır ve hata ayıkla

Açıklama:

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 bayt

Å{b≈\☼╣Δ@░ ‼

ambalajsız:

{vsc{%vfr$r+@}

Bu bir blok, bu yüzden kurtulabilirim ]|u, ama bir blok paketlediğinden bunun geçerli olup olmadığını bilmiyorum.


2

J , 33 22 bayt

FrownyFrog'un çözümü sayesinde -11 bayt (1/3 daha kısa)!

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

Çevrimiçi deneyin!

İlk çözümüm:

J , 33 bayt

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

Mutlu değil - çok daha fazla golf olabilir eminim.

Açıklama:

Pano durumunu son argüman olarak alan ikili bir fonksiyon, sol argüman n

<:@[ sol argümandan 1 çıkarma

{isağdaki listeden th elemanını (yukarıda hesaplanan) seçer

(...) tüm liste

# kopya

] pano durumu listesinden

(1<#) uzunluğu 1'den büyük alt listeler

|.&.> kopyalanan her alt listeyi döndür

<"0@; ustura ve kutu - her sayıyı ayrı bir kutuya koyar

, yeni listeyi pano durumu listesine ekle

@] tüm fiili (...) monadik yapar

Çevrimiçi deneyin!


@FrownyFrog 0;En çok hoşuma gitti . Teşekkürler!
Galen Ivanov

Bu tamamen sizin çözümünüz, sadece golf :)
FrownyFrog

2

V + coreutils , 53 45 43 42 40 bayt

DJMcMayhem sayesinde -9 bayt ( VGÇ /dtekrar :,$g/^[^ ]*$/d, D@"ddtekrar "aDÀddve !!tekrar kullanarak :.!)!

V'deki ilk denemem (ipuçları hoş geldiniz!), Aşağıdaki kod okunabilirlik için daire içine alınmış karakterler (örn. İçin \xf) kullanıyor:

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

Çevrimiçi deneyin!

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

açıklama

İlk satır n içerir ve aşağıdaki satırlar panonun girişlerini içerir, birden fazla giriş varsa her giriş boşlukla ayrılır:

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 bayt

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

Çevrimiçi deneyin!

Diziyi 4 başlangıç ​​/ bitiş işaretçi çiftinin listesi olarak alır, ardından n.

Açıklama:

#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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.