Flak Ketiga!

19

Tantangan ini diposting sebagai bagian dari tantangan LotM April 2018


Brain-Flak adalah bahasa turing-tarpit yang telah mendapatkan cukup banyak ketenaran di PPCG. Memori bahasa ini disusun oleh dua tumpukan, tetapi tumpukan ketiga "tersembunyi" ditemukan oleh Wh e di Wizard , yang mengarah ke beberapa cara baru yang menarik untuk memikirkan program Brain-Flak.

Jadi, bagaimana dengan memberikan tumpukan ketiga tersembunyi yang miskin lebih banyak visibilitas? Mari kita membuat bahasa di mana tumpukan ketiga memiliki pengakuan yang layak! Di sini saya hadir Anda Third-Flak .

Bahasa

Di Third-Flak hanya ada satu tumpukan, disebut tumpukan ketiga. Operator bekerja di tumpukan ketiga dengan cara yang sama mereka lakukan di Brain-Flak, tapi di sini tidak ada [], {}, <>nilads dan tidak ada {...}monad (sehingga karakter hanya diterima dalam program Ketiga-Flak adalah ()[]<>). Inilah yang dilakukan oleh setiap operator (contoh akan diberikan mewakili tumpukan ketiga dengan daftar di mana elemen terakhir adalah bagian atas tumpukan):

  • ()adalah satu-satunya operator dua karakter di Third-Flak. Ini meningkatkan bagian atas tumpukan ketiga dengan 1. Contoh: [1,2,3][1,2,4]

  • (, [, <: Semua kurung pembuka yang tidak tercakup oleh kasus sebelumnya mendorong 0ke tumpukan ketiga. Contoh: [1,2,3][1,2,3,0]

  • )muncul dua elemen dari tumpukan ketiga dan mendorong kembali jumlah mereka. Contoh: [1,2,3][1,5]

  • ]muncul dua elemen dari tumpukan ketiga dan mendorong kembali hasil pengurangan yang pertama dari yang kedua. Contoh: [1,2,3][1,-1]

  • >muncul elemen dari tumpukan ketiga. Contoh [1,2,3][1,2]

Dan berikut ini adalah aturan bahasa lainnya:

  • Pada awal eksekusi, tumpukan ketiga hanya berisi 0 tunggal.

  • Dilarang memiliki bagian yang kosong []atau <>di dalam suatu program (mereka toh akan menjadi noops jika mengikuti semantik Flak Ketiga, tetapi mereka sebenarnya memiliki arti yang berbeda dalam Brain-Flak yang tidak mungkin dibuat ulang di sini).

  • Tanda kurung harus selalu seimbang, kecuali fakta bahwa tanda kurung penutup di akhir program bisa hilang. Sebagai contoh, [()<(()adalah program Third-Flak yang valid (dan stack ketiga di akhir program adalah [1,0,1]).

  • Suatu program hanya dapat berisi enam karakter yang diizinkan ()[]<>. Program dijamin tidak kosong.

Catatan: ini tersirat oleh aturan sebelumnya bahwa Anda tidak perlu berurusan dengan situasi di mana Anda harus keluar dari tumpukan kosong.

Tantangan

Sederhana, tulis penerjemah untuk Third-Flak. Program Anda harus mengambil sebagai input program Third-Flak dan kembali sebagai keluaran status tumpukan ketiga di akhir program.

Format output Anda fleksibel selama dimungkinkan untuk secara jelas membaca dari situ tumpukan ketiga dan angka yang sama selalu dikodekan dengan cara yang sama (Ini hanya cara untuk mengatakan bahwa format output apa pun yang bukan cara yang terang-terangan) untuk mencoba curang tidak masalah).

Pilihan output Anda dapat membatasi rentang angka yang dapat Anda kelola selama ini tidak meremehkan tantangan (karena ini akan menjadi celah default ).

Uji kasus

Untuk setiap kasus uji, baris pertama adalah input, dan baris kedua tumpukan output diwakili sebagai daftar angka yang dipisahkan dengan spasi di mana bagian atas tumpukan adalah elemen terakhir.

[()<(()
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
Leo
sumber
Apakah tumpukan diinisialisasi dengan 0? Kalau tidak, [()]langgar aturan bahwa kita tidak perlu khawatir muncul dari tumpukan kosong
Jo King
1
@JoKing Yep: "Di awal eksekusi, tumpukan ketiga hanya berisi satu 0". Mungkin saya harus menyoroti bagian itu sedikit, saya takut itu akan terlalu mudah untuk dilewatkan.
Leo
Ups, saya tidak tahu bagaimana saya melewatkannya
Jo King
7
Dicoret e masih e.
Wheat Wizard
2
Jika ada yang tidak bisa melihat itu, yang dicoret eada di sini .
user202729

Jawaban:

21

Brain-Flak , 276 byte

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

Cobalah online!

Anda harus tahu ini akan datang.

Nitrodon
sumber
4

Retina 0.8.2 , 64 48 46 byte

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

Cobalah online! Mengeluarkan tumpukan dari bawah ke atas. Hanya berfungsi dengan bilangan bulat non-negatif, dan kotak uji terakhir terlalu lambat, sehingga tautannya hanya mencakup tiga kotak uji. Penjelasan: Tumpukan secara implisit mendahului program, sehingga dimulai sebagai string kosong, yang mewakili nol tunggal. The ()nilad adalah berubah menjadi _yang digunakan untuk menghitung dalam unary, sedangkan kurung terbuka lainnya berubah menjadi baris baru yang mendorong nol ke stack seperti yang ditemui. Kurung tutup kemudian diproses satu per satu sehingga tumpukan akan benar; yang )menghapus baris sebelumnya, menambahkan atas dua elemen bersama-sama, ]menghapus elemen atas dan cocok dari elemen sebelumnya pada stack sehingga mengurangkan itu, dan>hapus saja elemen teratas. Akhirnya tumpukan dikonversi ke desimal. Sunting: Disimpan 2 byte berkat @Leo.

Neil
sumber
Untuk apa ini $3? (jawaban yang bagus, sih!)
Leo
@ Leo Itu sisa dari golf sebelumnya. Terima kasih telah melihatnya!
Neil
4

Python 3 , 145 144 132 122 116 109 104 byte

-7 byte terima kasih kepada Leo!

Dan - 5 terima kasih untuk Lynn!

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

Cobalah online!

Implementasi standar yang cantik. Tapi tidak bisa dibaca sekarang. Saya kecewa saya tidak bisa menemukan cara yang lebih pendek untuk memeriksa antara tanda kurung awal dan akhir.

Beberapa upaya satu kalimat:

  • 124 byte (fungsi anonim):

    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 byte (program penuh):

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

Tambah lebih mengganggu daripada tugas biasa

Jo King
sumber
~-']>)'.index(i)bisa (2-ord(i)%5)untuk menyimpan 4 byte.
Lynn
2

Ruby , 98 91 byte

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

Cobalah online!

Kode awal saya bekerja sama dalam semangat untuk menjawab Python Jo King, sehingga sebelum perulangan melalui karakter sumber kami mengganti semua ()substring dengan karakter lain, sebagai operator yang berbeda.

Namun, setidaknya di Ruby, ternyata pegolf tidak melakukan ini, tetapi lebih memilih pendekatan yang sedikit lebih rumit. Di sini, kami mempertahankan pengindeks tambahan imelacak posisi kami di string sumber, dan setiap kali braket pembuka ditemui, kami melakukan lookahead memeriksa apakah karakter kami saat ini + berikutnya s[i,2]membentuk ()operator. Dalam hal ini kami mendorong 1 bukannya 0 di atas tumpukan, dan biarkan penutup )melakukan tugasnya di langkah berikutnya.

Kirill L.
sumber
1

05AB1E , 25 byte

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

Cobalah online!

Penjelasan

Î                           # 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
Emigna
sumber
1

R , 182 177 byte

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}

Cobalah online!

Mengembalikan tumpukan, tempat bagian atas tumpukan lebih dulu dan bagian bawah tumpukan adalah yang terakhir.

Bertukar ()dengan 7dan kemudian menghitung poin kode mod 8 untuk mendapatkan nilai numerik yang berbeda, yang lebih mudah dan lebih cocok untuk bermain golf daripada string.

Ini golfier untuk bekerja dengan awal vektor dalam R, jadi kami membangun stack dengan cara itu.

Kemudian ia melihat ), atau kapan k==1, ia menambahkan nol ekstra ke bagian atas tumpukan karena pemain golf menambahkannya dan menghapusnya.

Giuseppe
sumber
1

CJam , 29 byte

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

Cobalah online!

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

Ceylon, 285 266 bytes

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

Cobalah online!

(Disimpan 19 byte karena saran oleh Leo.)

Diformat dan dikomentari:

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

Cobalah online!

Paŭlo Ebermann
sumber
Saya tidak benar-benar tahu Ceylon, tapi mungkin Anda bisa menghapus case pertama dari switch dan menggunakan bagian lain untuk mengatur semua tanda kurung buka :)
Leo
Hmm, saya kira itu bisa berhasil ... itu akan mengubah perilaku untuk input yang tidak valid, tapi itu tidak masalah.
Paŭlo Ebermann