Minify Brainfuck

22

Twoim wyzwaniem jest zminimalizowanie kodu Brainfuck zgodnie z następującymi zasadami:

  • Usuń wszystko, co nie jest jednym z +-><[].,.
  • Dla każdej grupy z rzędu +lub -znaków, jeśli ilość +S i -S jest taki sam, należy je usunąć.
  • Zrób to samo co powyżej, ale używając >i <.
  • Usuń sekwencje +-><znaków, jeśli nic nie robią. Na przykład powinieneś usunąć +>-<->+<. (Może to być najtrudniejszy i najtrudniejszy do wdrożenia.) Upewnij się, że nie otrzymujesz żadnych fałszywych alarmów, takich jak +>-<+>-<, których nie należy usuwać.

Przypadki testowe:

Wkład

++++++[->++++++<]>.   prints a $
[-]<                  resets tape
>,[>,]<[.<]           reverses NUL terminated input string
++-->><<              does nothing

Wydajność

++++++[->++++++<]>.[-],[>,]<[.<]

Wkład

Should disappear: ++>>+<+++<->-->-<<->-<
Should disappear: +++>-<--->+<
Should stay: +++>-<+>---<

Wydajność

+++>-<+>---<

Możesz zaakceptować wejście i wyjście, jakkolwiek chcesz - stdin / stdout, funkcja itp., Ale wejście może nie być zakodowane na stałe.

To jest , więc wygra najkrótszy kod w liczbie znaków.

Klamka
źródło
4
Wiem, że to stare wyzwanie, ale przypadki testowe są nieodpowiednie. ++>>++<<--powinien generować >>++<<, a to nie było objęte. Dodaj więcej przypadków testowych.
mbomb007
@ mbomb007 czy zbadałeś ostatni przypadek testowy +++>-<+>---<? Można go skrócić, aby uniknąć niepotrzebnego ruchu wskaźnika, ale oczekiwany wynik pozostawia go bez zmian. Rozumiem na podstawie zarówno pytania, jak i odpowiedzi, że Klamka jest fajna, a specyfikacja jest luźna; musimy wyeliminować wszelkie ciągłe +-><sekwencje no-op , jak to wyraźnie zaznaczono, a poza tym dopuszczalne jest dodatkowe minimalizowanie, jak w twoim przykładzie ++>>++<<--, i możemy również dokonywać zmian, o ile nie zmieniają one funkcjonalności kodu, np. >+<+w +>+<.
Mitch Schwartz
@MitchSchwartz "Usuń sekwencje znaków + -> <, jeśli nic nie robią. Na przykład powinieneś usunąć +>-<->+<. (Może to być najtrudniejszy i najtrudniejszy do wdrożenia.) Upewnij się, że nie otrzymujesz żadnych fałszywych trafień, takich jak +>-<+>-<, których nie należy usuwać ”. - to trochę niejasne
mbomb007
@ mbomb007 A drugi i trzeci punkt są zbędne i niepotrzebne, ponieważ są uwzględnione w czwartym punkcie. Więc co? To fajne zadanie. Mój komentarz miał być konstruktywny i zawierać wyjaśnienia, a nie atakować cię. Proszę, weź to tak, jak zamierzałem lub powiedz mi, jak powinienem to powiedzieć inaczej. Ponieważ tak naprawdę nie odniosłeś się do tego, co napisałem; wygląda na to, że próbujesz się bronić, ale nie jesteś konstruktywny. W jaki sposób uważasz to za niejasne? Jak byś to napisał? Czy chcesz edytować pytanie? Czy chcesz zapytać Klamkę?
Mitch Schwartz
1
Och, więc musimy usunąć tylko ciągłe sekwencje?
mbomb007,

Odpowiedzi:

10

REBEL - 104

_/^_$/$</([^][<>.,+-]|\+-|-\+|<>|><)//((?<X>(<|>))+[+-]+(?!\2)(?<-X><|>)+(?(X)(?!)))([+-]+)/$3$1/.+/$>$&

Stosowanie:

Wejście: odczytuje jedną linię ze standardowego wejścia.

Wyjście: Drukuje jeden wiersz na standardowe wyjście.

Anomalie *:

  • Wpisanie _powoduje odczytanie i użycie kolejnej linii, a nie wyprowadzenie niczego.
  • Drugi test kończy ++++>----<zamiast +++>-<+>---<. Ale to w porządku, prawda? ;)
  • >-<+itp. zastępuje się +>-<itp.

Spojler:

Wdrożenie anomalii nr 3 sprawia, że ​​sprawy są dość trywialne.

* To nie jest błąd, to jest funkcja!

Kendall Frey
źródło
„to nie błąd, to funkcja” +1!
Rohan Jhunjhunwala
36

Brainfuck, 579 bajtów

,[<<+>>>>+<<[[<+>>+<-]++++++[>-------<-]>-[-[-[-[--------------[--[<+++++[>-----
-<-]>+[--[<<[-]>>-]]<]>[>>-<<<<<[-]<[<]<<<[<]>>>>>>>>[<]<-[+>]+[->+]>>>>+>[<-]<[
>+<-<]>]<]>[<<<[-]-[<]>>>>>>>>>>>[<]<<<<<<[<]<-[+>]+[-<+]<<<+<[>-<<<]>[-<+<]]]<]
>[+>[-<]<[<<]<[-]>>]]<]+>[-[<-]<[>+>+<<-<]<[-]>+>]<<[>-]>[,>]<]<+<[>]>[>>>[<<<<[
-<]<<<]>>>+>>>>[<<<<->>>>[>>>[-<]>>>>]]]>[<<<[<+[-->>]]>[-[.[-]]]>[<]>[<<++++++[
>+++++++<-]>+>>[<<.>>-]<<++>-[<.>-]+++[<+++++>-]+<<<<<<+>[<<[>->>>>>.[[-]<<<<]<<
<+>>>]>[->->>>>[-]]]<[->+[>>>>>]>>[<]<<<<<<<<[[-]<]>[++.[-]>>>>>>>]<]]>>]<[>>>>>
>>]+[-<<<<<[-]<<],]

Z formatowaniem i kilkoma komentarzami:

,
[
  <<+>> >>+<<
  [
    [<+> >+<-]
    ++++++[>-------<-]
    >-
    [
      not plus
      -
      [
        not comma
        -
        [
          not minus
          -
          [
            not period
            --------------
            [
              not less than
              --
              [
                not greater than
                <+++++[>------<-]>+
                [
                  not open bracket
                  --
                  [
                    not close bracket
                    <<[-]>>-
                  ]
                ]
                <
              ]
              >
              [
                greater than
                >>-<<
                <<<[-]<[<]<<<[<]
                >>>>>>>>[<]
                <-[+>]
                +[->+]
                >>>>+>[<-]
                <[>+<-<]
                >
              ]
              <
            ]
            >
            [
              less than
              <<<[-]-[<]
              >>>> >>>>>>>[<]
              <<<<<<[<]
              <-[+>]
              +[-<+]
              <<<+<[>-<<<]
              >[-<+<]
            ]
          ]
          <
        ]
        >
        [
          minus
          +>[-<]
          <[<<]
          <[-]>>
        ]
      ]
      <
    ]
    +>
    [
      plus
      -[<-]
      <[>+>+<<-<]
      <[-]>+>
    ]
    <<
    [
      comma or period or bracket
      >-
    ]
    >[,>]
    <
  ]
  comma or period or bracket or eof
  <+<
  [
    start and end same cell
    >
  ]
  >
  [
    >>>
    [
      <<<<[-<]<<<
    ]
    >>>+>>>>
    [
      start right of end
      <<<<->>>>
      [>>>[-<]>>>>]
    ]
  ]
  >
  [
    <<<
    [
      <+[-->>]
    ]
    >[-[.[-]]]
    >[<]
    >
    [
      <<++++++[>+++++++<-]>+>>
      [<<.>>-]
      <<++>-[<.>-]
      +++[<+++++>-]
      +<<<<< <+>
      [
        <<
        [
          go left
          >->>>>>.
          [[-]<<<<]
          <<<+>>>
        ]
        >
        [
          toggle left right
          ->->>>>[-]
        ]
      ]
      <
      [
        toggle right left
        ->+[>>>>>]>>[<]
        <<<<<<<<
        [
          [-]<
        ]
        >
        [
          go right
          ++.[-]
          >>>>>>>
        ]
        <
      ]
    ]
    >>
  ]
  <[>>>>>>>]
  +[-<<<<<[-]<<]
  ,
]

Wykorzystuje to to samo podejście, co rozwiązanie Keitha Randalla, minimalizując wszystkie ciągłe sekwencje +-<>optymalnie przez symulację. Na przykład +++>-<+>---<staje się ++++>----<i >+<+<<+>+<->>>>staje +<+>>+>.

Wypróbuj online. (Jeśli wartość bezwzględna symulowanej komórki zbliży się do 256, wystąpią problemy z przepełnieniem).

Ogólna struktura to

while not EOF:
  while not EOF and next char not in ",.[]":
    process char
  print minified sequence (followed by the char in ",.[]" if applicable)

Taśma jest podzielona na 7-komórkowe węzły; na początku wewnętrznej pętli układ pamięci to

0 s 0 c 0 a b

gdzie sjest flagą logiczną dla komórki początkowej, cjest bieżącym znakiem, ajest ujemną częścią symulowanej wartości komórki (plus jedna) i bjest dodatnią częścią symulowanej wartości komórki.

Podczas drukowania zmniejszonej sekwencji układ pamięci ma postać

d n e 0 0 a b

gdzie djest flagą logiczną dla kierunku ai bsą takie jak poprzednio (ale stają się jeden / zero po wydrukowaniu) ni esą niezerowe dla węzła końcowego; njest związany z tym, ile razy węzeł był widziany, i ejest wartością znaku, który zatrzymał pętlę wewnętrzną (plus jeden).

Pierwotnie rozważałem śledzenie większej ilości informacji na węzeł: skrajnie lewy i prawy węzeł jako flagi boolowskie oraz położenie węzła w stosunku do węzła początkowego i końcowego. Ale możemy tego uniknąć, patrząc w razie potrzeby na sąsiednie komórki i wykonując skanowanie lewej i prawej strony w celu znalezienia węzła początkowego.

Podczas drukowania zminimalizowanej sekwencji i decydowania o tym, jak przesunąć symulowany wskaźnik, możemy przyjąć ogólne podejście: zacznij od oddalenia się od węzła końcowego (w dowolnym kierunku, jeśli węzły początkowy i końcowy są takie same), odwróć się w lewo i prawo węzły i zatrzymaj na podstawie liczby wyświetleń węzła końcowego: 3 razy, jeśli węzły początkowy i końcowy są takie same, w przeciwnym razie 2.

Mitch Schwartz
źródło
2
Źródło: brainfuck. Cel: pieprzenie mózgu. +1
Erik the Outgolfer
2
Spełnia to nieokreśloną nagrodę
Destructible Lemon
1
Pozwolę, aby przyciągnęło to trochę uwagi i
nagrodzę
1
@MitchSchwartz Czy zdarzyło Ci się przetestować kod pod kątem kodu? Możesz go skrócić! #meta
WallyWest
1
@WallyWest (Wygląda na to, że pozwala zaoszczędzić 7 bajtów!) Nieważne, kod w permalinkie ma podział linii.
Dennis
7

Python, 404 znaków

Ten kod doskonale optymalizuje wszystkie podciągi +-<>. Trochę więcej, niż prosiłeś, ale proszę bardzo.

M=lambda n:'+'*n+'-'*-n                                                           
def S(b):                                                                         
 s=p=0;t=[0];G,L='><'                                                             
 for c in b:                                                                      
  if'+'==c:t[p]+=1                                                                
  if'-'==c:t[p]-=1                                                                
  if G==c:p+=1;t+=[0]                                                             
  if L==c:s+=1;t=[0]+t                                                            
 if p<s:k=len(t)-1;t,p,s,G,L=t[::-1],k-p,k-s,L,G                                  
 r=[i for i,n in enumerate(t)if n]+[s,p];a,b=min(r),max(r);return(s-a)*L+''.join(M(n)+G for n in t[a:b])+M(t[b])+(b-p)*L                                           
s=b=''                                                                            
for c in raw_input():                                                             
 if c in'[].,':s+=S(b)+c;b=''                                                     
 else:b+=c                                                                        
print s+S(b) 

Działa poprzez symulację +-<>operacji na taśmie t. sto pozycja początkowa na taśmie i pbieżąca pozycja. Po symulacji określa zakres [a,b], na którym należy operować, i wykonuje wszystkie +/- w jednym optymalnym przejściu.

Keith Randall
źródło
1

CoffeeScript - 403 397

i=prompt().replace /[^\]\[,.+-><]/g,''
x=(c)->
 t={};p=n=0
 for d in c
  t[p]?=0;switch d
   when'+'then n=1;t[p]++;when'-'then n=1;t[p]--;when'<'then p--;when'>'then p++
 (n=0if v!=0)for k,v of t;n
s=e=0;((e++;(i=(i.substr 0,s)+i.substr e;e=s=0)if x (i.substr s,e-s).split "")while(i[e]||0)!in['[',']',0];e=++s)while s<=i.length
r=/(\+-|-\+|<>|><|^[<>]$)/g
i=i.replace r,'' while r.test i
alert i

Demo (proszę wybaczyć użycie bit.ly tutaj, cały URL złamałby przecenę)

Wersja nieskompresowana (z kodem debugowania):

console.clear()
input = """Should disappear: ++>>+<+++<->-->-<<->-<
Should disappear: +++>-<--->+<
Should stay: +++>-<+>---<"""

input = input.replace /[^\]\[,.+-><]/g, ''
console.log input

execute = (code) ->
  stack = {}
  item = 0
  console.log code
  nop = false
  for char in code
    switch char
      when '+' then nop = true; stack[item]?=0;stack[item]++
      when '-' then nop = true; stack[item]?=0;stack[item]--
      when '<' then item--
      when '>' then item++
  console.debug stack
  (nop = false if v != 0) for k,v of stack
  nop
start = 0
end = 0

while start <= input.length
 while input.charAt(end) not in [ '[', ']', '' ]
  end++
  if execute (input.substring start, end).split("")
    input = (input.substring 0, start) + input.substring end
    end = start = 0
    console.log input
 end = ++start
input = input.replace /(\+-|-\+|<>|><|^(<|>)$)/g, '' while /(\+-|-\+|<>|><)/.test input
console.log 'Result: ' + input
TimWolla
źródło
Alternatywnym sposobem publikowania wersji demonstracyjnych Coffeescript jest użycie JSFiddle . Na lewym marginesie znajduje się panel konfiguracji „Języki”, który pozwala używać CoffeeScript zamiast JS.
Peter Taylor,
@PeterTaylor Dzięki, wiedziałem wcześniej o JSFiddle, ale nie to, że jest on w stanie używać CoffeeScript
TimWolla
To się nie udaje >+.-<, wytwarzając pusty ciąg zamiast pozostawiać go bez zmian.
Mitch Schwartz