Üçüncü Flak!


19

Bu meydan okuma, Nisan 2018 LotM meydan okumasının bir parçası olarak gönderildi


Brain-Flak , burada PPCG'de oldukça ün kazandıran bir turing-tarpit dilidir. Dilin hafıza iki istif tarafından oluşur, ancak "gizli" Üçüncü yığını keşfedildi tarafından Wh e Wizard Beyin Flak programlarını düşünme bazı ilginç yeni yollar açan,.

Peki, o kötü gizli üçüncü yığına daha fazla görünürlük kazandırmaya ne dersiniz? Üçüncü yığının hak ettiği bir tanıma sahip olduğu bir dil oluşturalım! İşte size Üçüncü Flak'ı sunuyorum .

Dil

Üçüncü Flak'ta, üçüncü yığın olarak adlandırılan yalnızca bir yığın vardır. Operatörler Beyin Flak yapmak aynı şekilde üçüncü yığın üzerinde çalışmak, ama burada hiçbir vardır [], {}, <>nilads ve hiçbir {...}monad (Bir Üçüncü Flak programında tek çaresinin karakterlerdir böylece ()[]<>). Her operatörün yaptığı şey (son öğenin yığının en üstünde olduğu bir liste ile üçüncü yığını temsil eden örnekler verilecektir):

  • ()Üçüncü Flak'taki tek iki karakterli operatördür. Üçüncü yığının tepesini 1 arttırır. Örnek: [1,2,3][1,2,4]

  • (, [, <Bir önceki durumda kapsamadığı tüm açma parantezler bir itme 0üçüncü yığına. Örnek: [1,2,3][1,2,3,0]

  • )üçüncü yığından iki eleman çıkarır ve toplamlarını geri iter. Örnek: [1,2,3][1,5]

  • ]üçüncü yığındaki iki öğeyi açar ve ilk öğeyi ikinciden çıkarmanın sonucunu geri iter. Örnek: [1,2,3][1,-1]

  • >üçüncü yığından bir öğe açar. Örnek [1,2,3][1,2]

Ve işte dilin diğer kuralları:

  • Yürütmenin başında üçüncü yığın yalnızca tek bir 0 içerir.

  • Boş []veya <>bir programın içinde olması yasaktır (Third-Flak'ın semantiğini takip ederse yine de noops olacaklar, ancak aslında Brain-Flak'ta burada yeniden yaratılması mümkün olmayan farklı bir anlamı var).

  • Parantezler, programın sonunda sondaki kapanış parantezlerinin eksik olması dışında, her zaman dengelenmelidir. Örnek olarak, [()<(()geçerli bir Üçüncü Flak programıdır (ve programın sonundaki üçüncü yığın [1,0,1]).

  • Bir program yalnızca izin verilen altı karakteri içerebilir ()[]<>. Programların boş olmadığı garanti edilir.

Not: Önceki kurallarda boş bir yığından gelmeniz gereken durumlarla uğraşmanız gerekmediği ima edilir.

Meydan okuma

Basit, Üçüncü Flak için bir tercüman yaz. Programınız bir Third-Flak programı girdi olarak almalı ve program sonunda üçüncü yığının durumunu çıktı olarak döndürmelidir.

Çıktı biçiminiz, üçüncü yığının durumunu net bir şekilde okumak mümkün olduğu sürece esnektir ve aynı sayı her zaman aynı şekilde kodlanır (Bu sadece açık bir şekilde olmayan herhangi bir çıktı biçiminin hile yapmaya çalışmak iyidir).

Çıktı seçiminiz, zorluğu önemsizleştirmediği sürece yönetebileceğiniz sayı aralığını kısıtlayabilir (bu, varsayılan bir boşluk olacağından ).

Test senaryoları

Her test durumu için ilk satır giriştir ve ikinci satır çıktı yığını, yığının üst kısmının son öğe olduğu boşlukla ayrılmış bir sayı listesi olarak temsil edilir.

[()<(()
0 1 0 1

[((((()()()()()))
0 0 0 5

((([()][()][()])))
-3

[<<(((()()()())(((((
0 0 0 0 0 4 0 0 0 0 0

[()]<(([()])><[()]
-1 0 -1

(())(()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(()()()()())(())(())(())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(()()()()())(())(())(())(())(())(())(()())(())(())(())(()())(()()()())(())(()()()()())(()())(()())(()())(()()())(())(()())(())(()()()()())(()())(()()()()())(())(())(())(())(())(()())(())(())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(()())(()())(()())(()())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(()()())(()())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(())(())(()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(()()())(())(()()())(())(())(())(()())(()()())(()())(())(()()()()())(()())(())(()()())(())(()()()()())(())(())(())(()()())(())(())(())(()())(())(()())(()()()())(())(())(()()()()())(()())(()())(())(()()())(())(())(())(())(()()())(()())(())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()())(())(()()()()())(()()()()())(())(()()())(())(())(()())(())(()()()()())(())(()()()()())(())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(()()()()())(())(()()()()())(())(())(())(()())(())(()()()()())(())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()()()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(())(()())(()()()())(())(())(()())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(()())(()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(()()())(())(())(()())(())(())(()()()()())(()()()())(()())(()())(()()())(())(()())(())(()()()()())(()())(()()()()())(())(())(())(()()()())(()()()())(()()
718 2

Yığın 0 ile başlatıldı mı? Aksi takdirde [()], boş bir yığından haşhaş hakkında endişelenmemiz gerekmeyen kuralı
Jo King

1
@JoKing Yep: "Yürütmenin başında üçüncü yığın yalnızca tek bir 0 içerir". Belki bu kısmı biraz vurgulamalıyım, kaçırmak çok kolay olurdu diye korktum.
Leo

Hata! Bunu nasıl özlediğimi bilmiyorum
Jo King

7
Çarpılan e hala e.
Buğday Büyücüsü

2
Herkes bu göremiyorsanız, üzerinde çarpı eolan burada .
user202729

Yanıtlar:


21

Brain-Flak , 276 bayt

{({}<>)<>}<>{(((()()()()()){})((({}){})())(({})({}{}([{}])(<>))))((()()(){[()]<{}>}{}){()<{{}}>}{}<<>({}({})())>{()(<{}>)}{}<>)<>}<>{(([{}]()<>)){{}({}())((){[()](<({}())((){[()](<({}())((){[()](<{}([{}]{})>)}{}){(<{}{}>)}{}>)}{}){(<{}({}{})>)}{}>)}{}){(<{}{}({}())>)}}{}<>}<>

Çevrimiçi deneyin!

Bunun olacağını bilmek zorundaydın.


4

Retina 0.8.2 , 64 48 46 bayt

\(\)
_
[([<]
¶
+1`¶(.*)\)|(.*)¶\2]|¶.*>
$1
%`_

Çevrimiçi deneyin! Yığını aşağıdan yukarıya doğru çıkarır. Yalnızca negatif olmayan tamsayılarla çalışır ve son test durumu çok yavaştır, bu nedenle bağlantı yalnızca üç test durumu içerir. Açıklama: Yığın programdan dolaylı olarak önce gelir, bu nedenle tek bir sıfırı temsil eden boş dize olarak başlar. ()Nilad bir haline getirilir _diğer açık parantez karşılaştı gibi yığın için bir sıfır itme yeni satır haline ise, tekli saymak kullanılan. Daha sonra kapatma braketleri, yığının doğru olması için her seferinde bir tane işlenir; )iki eleman bir araya üst ekleme, önceki yeni satır siler, ]üst eleman silmekte ve böylece çıkartarak yığında önceki elemanından eşleştirir ve>sadece üst öğeyi siler. Son olarak, yığın ondalık sayıya dönüştürülür. Düzenleme: @Leo sayesinde 2 bayt kaydedildi.


Ne $3için? (büyük cevap, her neyse!)
Leo

@Leo Bu önceki bir golf oyunundan ayrıldı. Tespit ettiğiniz için teşekkürler!
Neil

4

Python 3 , 14514412212 116109104 bayt

Leo sayesinde -7 bayt!

Ve - 5 Lynn'e teşekkürler!

s=[0]
for i in input().replace('()',' '):s+=i in']>) 'and(i<'!'or(2-ord(i)%5)*s.pop())+s.pop(),
print(s)

Çevrimiçi deneyin!

Oldukça standart uygulama. Şimdi okunabilir değil. Başlangıç ​​ve bitiş parantezleri arasında kontrol etmenin daha kısa bir yolunu bulamadığım için hayal kırıklığına uğradım.

Tek gömlekli bazı girişimler:

  • 124 bayt (anonim işlev):

    lambda c:[s.append(i in']>) 'and(i<'!'or~-']>)'.index(i)*s.pop())+s.pop())or s for s in[[0]]for i in c.replace('()',' ')][0]
  • 115 bayt (tam program):

    s=[0];[s.append(i in']>) 'and(i<'!'or~-']>)'.index(i)*s.pop())+s.pop())for i in input().replace('()',' ')];print(s)

Ekleme, basit atamadan rahatsız edici bir şekilde daha uzun


~-']>)'.index(i)olabilir (2-ord(i)%5)4 bayt kaydedin.
Lynn

2

Ruby , 98 91 bayt

->s{a=[i=0];s.chars{|c|a<<("([<"[c]?s[i,2]["()"]?1:0:a.pop*~-"]>)".index(c)+a.pop);i+=1};a}

Çevrimiçi deneyin!

İlk kodum, Jo King'in Python cevabına benzer şekilde çalıştı, böylece kaynak karakterleri arasında döngü yapmadan önce tüm ()alt dizeleri başka bir karakterle, farklı bir operatör olarak değiştirdik.

Ancak, en azından Ruby'de, bunu yapmamak için golfçü olduğu ortaya çıktı, daha ziyade biraz daha hantal bir yaklaşım benimsedi. Burada, ikaynak dizgideki konumumuzu takip eden ek bir indeksleyici tutuyoruz ve bir açılış paranteziyle karşılaşıldığında, mevcut + sonraki karakterlerin operatörü s[i,2]oluşturup oluşturmadığını kontrol ediyoruz (). Bu durumda, yığının üstüne 0 yerine 1'i iteriz ve kapanışın bir )sonraki adımda işini yapmasına izin veririz .


1

05AB1E , 25 bayt

΄()1:v"0+0\0->"žuykè.V})

Çevrimiçi deneyin!

açıklama

Î                           # initialize the stack with 0 and the input
 „()1:                      # replace any occurrence of "()" in the input with 1
      v                }    # for each char y in this string
                žuyk        # get its index in the string "()[]<>{}"
       "0+0\0->"    è       # use this to index into the string "0+0\0->"
                     .V     # eval
                        )   # wrap the stack in a list


1

R , 182177 bayt

function(P){for(k in utf8ToInt(gsub("\\(\\)",7,P))%%8){if(k%in%0:4)F=c(0,F)
if(k==7)F[1]=F[1]+1
if(k==1)F=c(F[2]+F[3],F[-3:0])
if(k==5)F=c(F[2]-F[1],F[-2:0])
if(k==6)F=F[-1]}
F}

Çevrimiçi deneyin!

Yığının üst kısmının ilk ve yığının alt kısmının son olduğu yığını döndürür.

Swaplar ()ile 7daha sonra ve kod noktaları dizeleri daha ile daha kolay ve işe golfier olan ayrı sayısal değerleri almak için 8 mod hesaplar.

R'deki bir vektörün başlangıcı ile çalışmak daha golfçü, bu yüzden yığını bu şekilde inşa ediyoruz.

Sonra a )veya ne zaman k==1göreceğine göre yığını daha fazla sıfır ekler.


1

CJam , 29 bayt

0q")]>([<""+-;U"er"U+"/')*~]p

Çevrimiçi deneyin!

0q                              Push 0, input
  ")]>([<""+-;U"er              Translate )]>([< to +-;UUU
                  "U+"/')*      Replace U+ by )
                          ~     Eval as CJam code
                           ]p   Wrap and pretty-print stack

1

Seylan, 285 266 bayt

function f(variable String c){variable Integer[]s=[0];value o=>[s[0]else nothing,s=s.rest][0];void u(Integer i)=>s=[i,*s];while(c!=""){if(c[0:2]=="()"){u(1);c=c.rest;}switch(c[0])case(')'){u(o+o);}case(']'){u(-o+o);}case('>'){noop(o);}else{u(0);}c=c.rest;}return s;}

Çevrimiçi deneyin!

(Leo'nun önerisi nedeniyle 19 bayt kurtarıldı.)

Biçimlendirilmiş ve yorumlanmış:

// Interpreter for ThirdFlak
// Question:    /codegolf//q/163242/2338
// This answer: /codegolf//a/163403/2338
//
// This function takes the code as a string, and returns the value
// of the stack as a sequence of Integers.
function f(variable String c) {
    // stack, in the beginning just a single 0.
    // Top element of the stack is the first, because push + pop is easier this way.
    variable Integer[] s = [0];
    // pop – used like an Integer variable (not a function – this saves the `()`), but has side effects.
    value o =>
        // `s[0]` is the first element of the stack. We tell the compiler
        // that it is non-null (otherwise we'll get an error at run time)
        // using the `else nothing`. `s.rest` is `s` without its first element.
        // Both together are wrapped into a 2-tuple, of which we then take just
        // the first element, to have both together in an expression instead
        // the longer way using an accessor block with a temporary variable and a return.
        // value o {
        //   value r = s[0] else nothing;
        //   s = s.rest;
        //   return r;
        // }
        [s[0] else nothing, s = s.rest][0];
    // push
    void u(Integer i) =>
        // a tuple enumeration, using the spread argument.
        s = [i, *s];
    // the main loop
    while (c != "") {
        if (c[0:2] == "()") {
            // »`()` is the only two-characters operator in Third-Flak. It increases the top of the third stack by 1.«
            // As `)` alone adds the two top elements together, we can just push a one here, and let the handling for `)` do the rest.
            u(1);
            c = c.rest;
        }
        switch (c[0])
        case (')') {
            // »`)` pops two elements from the third stack and pushes back their sum.«
            u(o + o);
        }
        case (']') {
            // »`]` pops two elements from the third stack and pushes back the result of subtracting the first from the second.«
            // As the o written first is the first one, we can't write this as a subtraction.
            u(-o + o);
        }
        case ('>') {
            // »`>` pops an element from the third stack.«
            // `o;` alone is not a valid statement, so we pass it to the `noop` function.
            noop(o);
        }
        else {
            // all other valid code characters are `(`, `[`, `<`, which all just push a 0.
            u(0);
        }
        c = c.rest;
    }
    return s;
}

Çevrimiçi deneyin!


Ceylon'u gerçekten bilmiyorum, ama belki de anahtarın ilk vakasını kaldırabilir ve tüm açılış braketlerini yönetmek için başka bir parçayı kullanabilirsiniz :)
Leo

Hmm, sanırım bu işe yarayabilir ... geçersiz giriş için davranışı değiştirir, ama bu bir sorun değil.
Paŭlo Ebermann
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.