Bir beyin-flak klasik tercüman yaz!


18

Brain-Flak (Brainf ** k ve Flak-Overstow arasında bir çarpı), yığın tabanlı ezoterik bir dildir. Bu meydan okuma gönderildiğinden, dil gelişti ve güncellendi, ancak dilin bu ilk revizyonu "beyin-flak klasiği" olarak bilinir.

Bir dizi Brain-Flak klasik kodu alan ve değerlendiren bir program veya işlev yazmalısınız. Ayrıca (olası bir boş) tamsayı listesi de alır. Brain-Flak klasik programının girdileri vardır.

Dil

Brain-Flak'ın 'sol' ve 'sağ' olarak bilinen iki yığını vardır. Aktif yığın soldan başlar. Boş bir yığın açılırsa veya gözetlenirse 0 döndürür. Değişken yoktur. Program başladığında, her giriş sırayla aktif istifin üzerine itilir (böylece son giriş istifin en üstünde olur).

Brain-Flak programındaki tek geçerli karakterler ()[]{}<>ve her zaman dengelenmeleri gerekir . Geçersiz karakterler varsa veya köşeli parantezler eşleşmiyorsa, tanımlanmamış davranışa sahip olursunuz. Her şey geçerlidir.

İki tür işlev vardır: Niladlar ve Monadlar . Bir nilad 0 argüman alan bir fonksiyondur. İşte tüm niladlar:

  • () +1.
  • [] -1.
  • {} Etkin yığını açın.
  • <> Etkin yığını aç / kapat.

Bunlar değerlendirildiklerinde birleştirilirler. Aktif yığının üstünde bir '3' olsaydı, bu pasaj:

()(){}

ile sonuçlanacağından 1 + 1 + active.pop()5. değerlendirmek hangi <>0 değerlendirir.

Monadlar bir argüman alır, bir beyin-Flak kodu. İşte tüm monadlar:

  • (n) Etkin yığın üzerinde 'n' tuşuna basın.
  • [n] 'N' harfini int ve yeni satır olarak yazdır.
  • {foo}Active.peek ()! = 0 iken, foo yapın. 0¹ olarak değerlendirir.
  • <foo> Foo'yu yürütün, ancak 0 olarak değerlendirin.

Bu işlevler ayrıca içindeki değeri de döndürür,

(()()())

3 itecek ve

[()()()]

3 yazdıracak

[(()()())]

Yazdırır ve zorlar 3.

Program yürütme işlemi tamamlandığında, etkin yığında kalan her bir değer tam sayı olarak ve arasında bir satırsonu olarak yazdırılır. Diğer yığındaki değerler göz ardı edilir.

Kurallar:

  • Programınız (-128, 127) aralığındaki sayıları ve yığın boyutunun en az 255'i desteklemesi gerekir. Daha büyük desteklerseniz, harika.

  • Taşma / taşma tanımsız.

Örnek IO:

Boş program:

Giriş: Yok

Çıktı: Yok

İlave. Kaynak:

({}{})

Giriş:

2, 3

Çıktı:

5

Çıkarma. Kaynak:

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

Giriş:

2, 3

Çıktı:

-1

Çarpma işlemi. Kaynak:

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

Giriş:

7, 8

Çıktı:

56

Fibonacci. Kaynak:

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

Giriş:

5

Çıktı:

13
8
5
3
2
1
1

Gerçek makine

{[({})]}

Standart boşluklar uygulanır ve bayt cinsinden en kısa cevap kazanır.


  • ¹: Bu benim açımdan aslında bir hataydı. {...} beyin flak'ın en havalı özelliklerinden biri olan IMO olan tüm çalışmalarının toplamını değerlendirmelidir. Ancak, bu zorluğun amaçları için, 0 olarak değerlendirildiğini varsayalım {...} .

Programın işlemesi gereken minimum tamsayı değeri ile ilgili bir kural var mı?
0 '

Monad neyi {...}değerlendiriyor?
Neil

Çıkarma argümanları hangi sırada? Beklediğim şeyin olumsuzluğunu alıyorum.
Neil

@Neil Bunun için üzgünüm. Monad {...}0 olarak değerlendirilir. Ayrıca, argümanlar sırayla itilir, bu yüzden 2itilir, sonra 3itilir, böylece program başladığında ikinci giriş ( 3) yığının üstündedir. Her iki görevde de açıklığa kavuşacağım.
DJMcMayhem

Yanıtlar:


6

Pip -n , 151 148 101 98 bayt

YRVg;VqR^"{}()<>[]";,8R J,8<>2AL,8("POy|i o0Syl1v0W@y{ }1yPU$+[ ]&@y0 1P$+[ ]"R0" (V{"R1"i}) "^s)y

Girdilerin listesini komut satırı argümanları ve Brain-Flak kodunu (bir satır) stdin'den alır. Çevrimiçi deneyin!

Düzenleme: Çeviri ve değerlendirme stratejisine geçerek benim orijinal yaklaşımın üzerinde bayt bir sürü kaydetti.

Ungolfed ve yorumladı

Bu sürüm aynı zamanda çeviriden kaynaklanan Pip kodunu ve yürütmeden sonra yığın içeriğini gösteren bazı hata ayıklama çıktılarını da içerir.

;;; Setup ;;;

; y is the active stack, l is the off-stack
; y is initialized from command-line arguments
y:RVg   (reversed to put the last input at the top)
; l is preset to empty list by default

; p is the program (read from stdin)
p:q

; Translate from braces to numbers 0-7 (we do this so that the
; later replacement step won't try to replace the braces in the
; Pip code)
p R: ^"()[]{}<>" 0,8

;;; Replace nilads with the appropriate code ;;;

; () => o (variable preset to 1)
p R: 01 "o"

; [] => v (variable preset to -1)
p R: 23 "v"

; {} => POy|i
; Pop y; return that value OR i (variable preset to 0)
p R: 45 "POy|i"

; <> => (V{Syli})
; Eval the code Syl to swap stacks y and l, then return i (i.e. 0)
p R: 67 "(V{Syli})"

;;; Replace monads with the appropriate code ;;;

; ( ) => yPU$+[ ]&@y
; Sum ($+) the inside and push (PU) the sum onto y; return
; the just-pushed value, which is the first element of y (@y)
; y will always be truthy (nonempty), since we just pushed a value onto it
p R: 0 "yPU$+["
p R: 1 "]&@y"

; [ ] => P$+[ ]
; Sum ($+) the inside, print (P) the sum, and return it
p R: 2 "P$+["
p R: 3 "]"

; { } => (V{W@y{ }i})
; Eval the code W@y{ }, which wraps the inside in curly braces
; and runs it while (W) the first element of y (@y) is truthy
; (i.e. not zero, and not nil from an empty stack)
; Then return i (i.e. 0)
p R: 4 "(V{W@y{"
p R: 5 "}i})"

; < > => (V{ i})
; Eval the inside, then return i (i.e. 0)
p R: 6 "(V{"
p R: 7 "i})"

; Debug: print the resulting translated code and a blank line
Pp.n

;;; Run the code ;;;

; Eval the translated code
(Vp)

; Output the active stack, newline-separated
PyJn

; Debug: print the active stack and the off-stack
P"Active stack: ".RPy
"Off-stack: ".RPl

Pip bu zorluktan daha mı yeni?
DJMcMayhem

@DJMcMayhem Hayır ! Ben de meydan okumadan daha yeni özellikler kullanmıyorum.
DLosc

59

Brain-Flak Klasik , 1271 1247 1239 bayt

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

Çevrimiçi deneyin!

{...}Monad'daki durumla ilgili bir hatayı düzeltmek için +4 bayt ve çeşitli golflerden -36 bayt.

1238 bayt kod, -abayrak için +1 bayt (dil bayrağıyla birleştirilebilir).

Bu, artık {...}her test spesifikasyonu başına sıfır olarak değerlendirilir . Brain-Flak'ın kendisinin, {...}7 Mayıs 2016'daki bu düzeltmenin yayınlanmasından iki gün önce bugfix'ten sonraki tüm çalışmaların toplamı olarak değerlendirildiğini unutmayın .

Aşağıdaki kod, Brain-Flak Classic'i {...}tüm çalışmaların toplamı olarak doğru şekilde yorumlar . İki tercüman arasındaki tek fark bir {}niladın yerleştirilmesidir .

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

Çevrimiçi deneyin!

Girdi (her iki tercümana) yorumlamak için Brain-Flak Classic programı, sonra bir satırsonu, sonra boşlukla ayrılmış bir tamsayı listesi. Girişte hiçbir doğrulama yapılmaz. Program veya giriş boş olsa bile, yeni satır gereklidir.

İlk adım, parantezle başlayarak tüm girdileri ayrıştırmaktır:

# Move to right stack, and push 1 to allow loop to start
<>(())
{
   # While keeping -5 on third stack:
   <>((([][][][][])<

       # Pop bracket or newline k from left stack, and push 0, k-10, k-40, k-60, k-91, k-123 on right stack
       (((({}){})(({})({}))[])({}(({})({}({})({}{}(<>)))))[])

   # Search this list for a zero, and push the number of nonzero entries popped minus 5 
   # (thus replacing the 0 if it was destroyed)
   >{()<{}>}{})

   # Remove rest of list, and push the same number plus 1
   # Result is -4 for {, -3 for [, -2 for <, -1 for (, 0 for newline, or 1 for everything else (assumed closing bracket)
   <{{}}{}>())

# Repeat until newline found
}{}<>

Sonra tamsayılar ayrıştırılır. Bu normalde gerekli olmaz, ancak giriş ASCII olarak alındı. Bunun gümüş bir astarı var: metin girişi, yığın yüksekliği niladına erişimimiz olmadığında işleri basitleştiren yığın yüksekliğini belirlememizi sağlar.

Tamsayılar ikinci yığın üzerinde iki sayıya ayrılır: biri mutlak değer için ve diğeri işaret için. Bunlar daha sonra ilk yığına geri taşınır.

Yorumlanan yığınlar, ilk yığındaki kodun altında aşağıdaki sırayla depolanır: geçerli yığın yüksekliği, geçerli yığın, diğer yığın yüksekliği, diğer yığın. Diğer yığın yüksekliği için 0'ın bu noktada itilmesine gerek yoktur, çünkü ilk okunduğunda örtük bir sıfır olacaktır.

(<((

    # If stack nonempty, register first stack entry.
    {()(((<>))<>)}{}

    # For each byte k of input:
    {

        # Push -3, -13, and k-32
        <({}(([][][])((({})({}))[]{})){})>

        # Evaluate to 1 if space
        # If not space (32):
        ((){[]<

            # If not minus (45):
            ({}{})((){[]<

                # Replace top of right stack (n) with 10*n + (k-48)
                ({}{}<>((({})({})){}{}){})(<>)

            # Else (i.e., if minus):
            >}{}){

                # Remove excess "else" entry and -3
                {}{}

                # Set sign to negative (and destroy magnitude that shouldn't even be there yet)
                <>(<({}{}())>)(<>)}

        # Else (i.e., if space):
        >}{}){

            # Remove working data for byte, and push two more 0s onto right stack
            (<{}{}{}((<>))<>>)

    # Push number of integers found
    }{}}<>)

    # For each integer:
    <{({}[]<

        # Move magnitude back to left stack
        ({}<>)<>

        # If sign is negative, negate
        {(<{}>)<>{<>({}[])}{}<>({}<>)(<>)}{}

    >)}{}

    # Push stack height onto stack
    <>>)

# Push 0
>)

Kodun temsili şimdi sol yığına geri taşınır. Daha sonra işleri kolaylaştırmak için, niladların açılış parantezlerinden 4 çıkarırız, böylece her işlem -1 ila -8 arasında benzersiz bir tamsayıya sahip olur.

# For each bracket in the code:
<>{

    # Push k-1 and evaluate to k
    (({}[])()

    # If not closing bracket:
    {

        # Check next bracket (previously checked, since we started at the end here)
        (<{}>)<><(({})[])>

        # Subtract 4 if next bracket is closing bracket
        # Inverting this condition would save 8 bytes here, but cost 12 bytes later.
        [][][][]{()()()()(<{}>)}{}

    <>}{}

    # Push result onto left stack
    <>)

<>}<>{}

Programın ana kısmı aslında talimatları yorumlamaktır. Ana döngünün her yinelemesinin başlangıcında, geçerli talimat sol yığının üstündedir, altından sonraki her şey aynı yığın üzerinde ve sağ yığındaki her şey. Bunu belirli bir sayfaya açık bir kitap olarak görme eğilimindeyim.

{

    (

        # Get current instruction
        ({})

        # Move all code to left stack, and track the current position in code
        <({()<<>({}<>)>}{})>

        # Push -1, signifying that the code will move forward to just before a matching }.
        # In most cases, this will become 0 (do nothing special) before it is acted upon
        ([])

    # Push instruction minus 1
    )

    # If opening bracket:
    ((){[](<

        # Push instruction+1 and instruction+4
        (({}()()(<>))()()())

        # If instruction+4 is nonzero (not loop monad), replace the earlier -1 with 0 to cancel forward seek
        # This would be clearer as {(<{}>)<>(<{}>)<>}, but that would be unnecessarily verbose
        {(<{}>)<>}

    # Else (i.e., if closing bracket):
    >)}{}<>){

# If closing bracket, parse command
# Post-condition for all: if not moving to {, pop two and push evaluation, 0.
# (For nilads, can assume second from top is 0.)
# If moving to {, pop one, push -3, 0, 0.

        # Seven nested if/else statements, corresponding to eight possible instruction.
        # The "else" statements end with 0 already on the stack, so no need to push a 0 except in the innermost if.
        # Each one beyond the first increments the instruction by 1 to compare the result with 0
        # Each instruction will pop the instruction, leaving only its evaluation (with a 0 on top).
        {}((){[]<
        ({}())((){[]<
        ({}())((){[]<
        ({}())((){[]<
        ({}())((){[]<
        ({}())((){[]<
        ({}())((){[](<

            # -7: pop
            # Pop instruction to reveal existing 0 evaluation
            {}

            # Move code out of the way to access stack
            <>{({}<>)<>}{}

            # Duplicate stack height (only useful if stack height is zero)
            (({}))

            (

                # If stack height nonzero
                {

                    # Save stack height on second stack
                    <{}({}<>)<>>

                    # Pop stack
                    {}

                    # Move stack height back and subtract 1
                    (<<>({}[]<>)>)

                }

                # Move code back to normal position
                <><{({}<>)<>}>{}

            # Evaluate as popped entry (0 if nothing popped)
            )

        # (else)
        >)}{}){

            # -6: -1 nilad
            # Just evaluate as -1
            {}{}(<([])>)

        # (else)
        }>}{}){

            # -5: swap nilad
            # Move code out of the way to access stack
            {}<>{({}<>)<>}{}

            # Number of integers to move: stack height + 1 (namely, the stack height and every entry in the stack)
            ((({})())

            # Move to second stack
            <{({}[]<({}<>)<>>)}>{}

            # Do (stack height + 1) times again
            ){({}[]<><

                # Get stack element
                ({}<><

                    # Move alternate (interpreted) stack to second (real) stack, and push length on top of it
                    ({()<({}[]<({}<>)<>>)>}{}<>)

                # Push current stack element below alternate stack
                ><>)

                # Move alternate stack back above newly pushed element
                <>({()<({}[]<({}<>)<>>)>}{}<>)

            >)}

            # Move code back to normal position
            <>(<{({}<>)<>}>)

        # (else)
        }>}{}){

            # -4: 1
            # Just evaluate to 1
            {}{}(<(())>)

        # (else)
        }>}{}){

            # -3: loop
            # Create zero on stack while keeping existing evaluation
            # This becomes (<{}{}>) in the version that meets the challenge spec
            (<{}>)

            # Move code out of the way to access stack
            <>{({}<>)<>}{}

            # Duplicate stack height
            (({}))

            (

                # If stack height nonzero
                {

                    # Save stack height on second stack
                    <{}({}<>)<>>

                    # Peek at top of stack
                    ({})

                    # Move stack height back
                    (<<>({}<>)>)

                }

                # Move code back to normal position
                <><{({}<>)<>}>

            # Look at peeked entry
            # Remove the {} in the version meeting the challenge spec
            {})

            # If peeked entry is nonzero
            {

                # Replace -3 instruction on third stack
                {}([][][])

                # Replace loop indicator to 0 (to be incremented later to 1)
                <>(((<{}>)

                # Create dummy third stack entry to pop
                <>))

            }

        # (else)
        }>}{}){

            # -2: print
            # Just print evaluation without modifying it
            {}(<([{}])>)

        # (else)
        }>}{}){

            # -1: evaluate as zero
            # Just change evaluation to 0
            {}((<{}>))

        # else
        }>}{}){

            # 0: push
            # Get current evaluation (without modifying it)
            {}(({})

                # Create zero on stack as barrier
                (<()>)

                # Move code out of the way to access stack
                <<>{({}<>)<>}{}

                # Increment stack height and save on other stack
                ({}()<>)<>

            # Push evaluation
            >)

            # Move stack height back (and push zero)
            <>(<({}<>)>)

            # Move code back to normal position
            <>{({}<>)<>}

        }{}

        # Update third stack by adding evaluation to previous entry's evaluation
        # Previous entry's instruction is saved temporarily on left stack
        (<({}<({}<>)<>>{})<>({}<>)>)

        # Increment loop indicator
        # If instruction was loop monad and top of stack was nonzero, this increments 0 to 1 (search backward)
        # Otherwise, this increments -1 to 0 (do nothing)
        <>(<({}())>)

    }{}

    # While holding onto loop indicator
    ({}<

        # Go to immediately after executed symbol
        {({}[]<({}<>)<>>)}{}

    >)

    # If looping behavior:
    {

        # Switch stack and check if searching forward
        ((({}[]<>)

        # If so:
        {

            # Move just-executed { back to left stack, and move with it
            (<{}({}<>)>)

        }{}

        # Either way, we are currently looking at the just-executed bracket.
        # In addition, the position we wish to move to is on the current stack.

        # Push unmodified loop indicator as initial value in search
        ())

        # While value is nonzero:
        <{

            # Add 1
            ({}()

                # Move current instruction to other stack
                <({}<>)<>

                # Check whether next instruction is closing bracket
                (({})[])>

                # If opening bracket, subtract 2 from value
                {[][](<{}>)}{}

            )

        }{}>

        # If searching backward, move back to left stack
        ()){{}(<>)}

    }{}

}

Ana döngüden çıktıktan sonra kodun tamamı sağ yığın üzerindedir. Sol yığındaki tek şey sıfır ve yorumlanan iki yığıntır. Doğru çıktıyı üretmek basit bir konudur.

# Pop the zero
{}

# Output current stack
{({}[]<[{}]>)}{}

# Discard other stack to avoid implicit printing
{({}[]<{}>)}{}

12
: Ey ne ... Tamam, hemen cömertçe. İyi iş! : D
DJMcMayhem

4
Bunu düzleştireyim ... yorumlanacak dil için bir tercüman yarattınız. YoDawg
tisaconundrum

Tamam, neden sadece 2 basamaklı bir upvote numarası var?
NieDzejkob

Akümülatörün doğru bir şekilde uygulanması konusunda iyi bir iş {...}, ki bu modern beyin-flak ve (bence) beyin-flak klasiği için doğru davranış, ancak {...}0 olarak değerlendirilen zorlukta yazdım . Bu işlevselliği kaldırarak, orijinal olarak teknik olarak daha doğru olduğu için orijinali saklamak güzel olsa da (bu meydan okuma için sadece yanlış)
DJMcMayhem

@DJMcMayhem Düzeltildi. Sadece tüm yorumcuyu Brain-Flak'ın varsayımsal versiyonuna taşımamı sağlayın.
Nitrodon

8

APL, 255 257 bayt

b←{S←(⌽⍺)⍬
e←{0=⍴⍵:0
v+∇⊃_ v←∇{r←⊂2↓⍵
'()'≡n←2↑⍵:r,1
'[]'≡n:r,¯1
'{}'≡n:r,{i←⊃⊃⊃S⋄S[1]↓⍨←1⋄i}⍬
'<>'≡n:r,0⊣S⌽⍨←1
r←⊂⍵↓⍨i←0⍳⍨(+\c=⍵)-+\')]>}'['([<{'⍳c←⊃⍵]=⍵
i←1↓¯1↓c←i↑⍵
'('=c←⊃c:r,S[1],⍨←⍺⍺i
'['=c:r,+⎕←⍺⍺i
'{'=c:r,{0≠⊃⊃⊃S:∇e i⋄0}⍬
'<'=c:r,0⊣⍺⍺i}⍵}
⎕←⍪⊃S⊣e⍵}

Bu, programı sağ argümanı ve program girdisini sol argümanı olarak alır, yani:

      2 3 b '({}{})'
5
      2 3 b '({}<>){({}[])<>({}[])<>}<>'
¯1
      7 8 b '({}<>)<>({}[]){({}[])<>(({}))<>}<>{({}<>{})<>}<>'
56
      5 b '<>((()))<>{({}[])<>({}<>)<>(({})<>({}<>))<>}<>'
13
 8
 5
 3
 2
 1
 1

Ungolfed sürümü: burada .


7

APL (Dyalog Klasik) , 146 bayt

↑⍕¨s⊣{⍎⍕1 ¯1'(s↓⍨←1)⊢⊃s' '0⊣s t←t s' 's,⍨←+/∇¨a' '⎕←+/∇¨a' '∇{×⊃s:∇⍺⍺¨a⋄0}0' '0⊣+/∇¨a'[(⊃⍵)+4×⍬≢a1↓⍵]}¨⍎∊(')',⍨'(',¨⍕¨⍳4)[0,4,⍨'([{<'⍳⍞]⊣s←⌽⎕⊣t←⍬

Çevrimiçi deneyin!

bir klasik başka yorumlama :)


6

Python 3, 429 bayt

import re
S='s+=[v];v=0';T='v+=s.pop()';i=0
d={'()':'v+=1','(':S,')':'a+=[v];'+T,'[]':'v-=1','[':S,']':'print(v);'+T,'<>':'a.reverse()','<':S,'>':T,'{}':'v+=0if a[-1]==""else a.pop()','{':S+';while a[-1]:','}':T}
def r(m):global i;t=m.group();i-=(t=='}');s=' '*i;i+=(t=='{');return''.join(s+r+'\n'for r in d[t].split(';'))
def g(c,*a):
 a,s,v=['']+list(a),[],0;exec(re.sub(r'[<({[]?[]})>]?',r,c));
 while a[-1]!="":print(a.pop())

Gibi kullanılır g('[{}{}]', 2, 3)

re.subBrain-flak kaynağını python'a "derlemek" için kullanır ve daha sonra python'u çalıştırır. (hata ayıklama için, python kodunun bir listesini almak için execile değiştirin print)

Döngüler kodda çok fazla bayt yerken iç içe doğru girintili.


3

Python, 616 bayt

Talimatlar:

  1. Python ile çalıştırın
  2. Listeyi [1,2,...]format olarak girin ve enter tuşuna basın
  3. Programı yapıştır / yaz, sonra tekrar enter tuşuna basın
  4. Bitti

Temel olarak, bu programın yaptığı, Brain-flak kodunu iç içe listelere özyineli olarak "derlemek" ve bu listeyi özyineli olarak yorumlamaktır. Muhtemelen ikisini birleştirmenin bir yolu var ...

Daha sonra mantığı yeniden deneyeceğim.

y="([{<)]}>"
w,z,g=print,len,input
def c(s):
 if z(s)<1:return[]
 t,i,o=[],1,0
 t.append(y.index(s[0]))
 while z(t)>0:
  x=y.index(s[i])
  if x<4:t.append(x)
  else:o=t.pop()
  i+=1
 r=[[o,c(s[1:i-1])]]
 r.extend(c(s[i:]))
 return r
p=lambda t:t.pop()if z(t)>0 else 0
k=lambda t:t[z(t)-1]if z(t)>0 else 0
r,l=[],eval(g())
a=l
def i(u):
 v=0
 global a
 for t,n in u:
  if t<1:
   if n:o=i(n);v+=o;a.append(o)
   else:v+=1
  if t==1:
   if n:o=i(n);v+=o;w(o)
   else:v-=1
  if t==2:
   if n:
    while k(a)!=0:i(n)
   else:v+=p(a)
  if t>2:
   if n:i(n)
   elif a==l:a=r
   else:a=l
 return v
i(c(g()))
for n in a:w(n)

3

Perl 5.6, 419414 bayt

Biraz golf yaptım ama muhtemelen iyileştirme için bir kapsam var. Biraz okunabilirlik için buraya satırlar ve sekmeler eklendi:

use Text::Balanced extract_bracketed;
$s=shift;
@a=reverse@ARGV;
sub p
{
    my($c)=@_;
    my$s=0;
    while(my$n=extract_bracketed($c)){
        $s+='()'eq$n||'{}'eq$n&&shift@a;
        $s-='[]'eq$n;
        @t=@a,@a=@i,@i=@t if'<>'eq$n;
        my$m=chop($n);
        $n=substr($n,1);
        if($n){
            p($n)while'}'eq$m&&$a[0];
            p($n)if'}'ne$m;
            $s+=$v,unshift@a,$v if')'eq$m;
            $s+=$v,print"n=$n m=$m v=$v\n"if']'eq$m;
        }
    }
    $v=$s;
}
p($s);
foreach(@a){
    print"$_\n";
}

1

Python 2 , 361 , 348 bayt

c,s=input();s=s,[]
a=s[0]
def w():global a,s;s=s[::-1];a=s[0];return 0
def p(c):a.append(c);return c
def n(c):print c;return c
z=lambda c:0
def l(f):
 global a
 while a and a[-1]:f()
 return 0
for x,y in zip("() ( [] {} <> [ < { } ] >".split(),"+1 +p( -1 +(len(a)and(a.pop())) +w() +n( +z( +l(lambda: ) ) )".split()):c=c.replace(x,y)
exec c
print a

Çevrimiçi deneyin!

@Mr sayesinde 13 bayt kaydedildi. Xcoder!

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.