Minimizza Brainfuck


22

La tua sfida è minimizzare il codice Brainfuck , secondo queste regole:

  • Rimuovi tutto ciò che non fa parte di +-><[].,.
  • Per qualsiasi gruppo di consecutivi +o -caratteri, se la quantità di +s ed -s è la stessa, rimuoverli.
  • Fai come sopra, ma con >e <.
  • Rimuovi le sequenze dei +-><personaggi se non fanno nulla. Ad esempio, è necessario rimuovere +>-<->+<. (Questa potrebbe essere la più difficile e la più difficile da implementare.) Assicurati di non avere falsi positivi, come +>-<+>-<, che non dovrebbero essere rimossi.

Casi test:

Ingresso

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

Produzione

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

Ingresso

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

Produzione

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

Puoi accettare input e output come preferisci - stdin / stdout, una funzione, ecc., Ma l'input potrebbe non essere codificato.

Questo è , quindi vincerà il codice più breve nel conteggio dei caratteri.


4
So che questa è una vecchia sfida, ma i casi di test sono inadeguati. ++>>++<<--dovrebbe produrre >>++<<, e questo non è stato coperto. Aggiungi altri casi di test.
mbomb007,

@ mbomb007 hai esaminato l'ultimo caso di test +++>-<+>---<? Può essere abbreviato per evitare inutili movimenti del puntatore, ma l'output previsto lo lascia invariato. La mia comprensione basata sull'esame sia della domanda che delle risposte è che Doorknob è forte con le specifiche prese in modo impreciso; dobbiamo eliminare le +-><sequenze contigue non operative come esplicitamente dichiarato, e oltre a ciò è lecito fare una minimizzazione extra come nel tuo esempio ++>>++<<--, e possiamo anche fare riorganizzazioni purché non cambino la funzionalità del codice, ad es. >+<+in +>+<.
Mitch Schwartz,

@MitchSchwartz "Rimuovi le sequenze dei caratteri + -> <se non fanno nulla. Ad esempio, dovresti rimuoverlo +>-<->+<. (Potrebbe essere il più difficile e difficile da implementare.) Assicurati di non avere falsi positivi, come +>-<+>-<, che non dovrebbe essere rimosso. " - Questo è un po 'vago
mbomb007,

@ mbomb007 E il secondo e il terzo punto elenco sono ridondanti e non necessari perché sono inclusi nel quarto punto elenco. E allora? È un bel compito. Il mio commento doveva essere costruttivo e fornire chiarimenti, non attaccarti. Per favore, prendilo come volevo, o dimmi come avrei dovuto dirlo diversamente. Perché non hai veramente affrontato ciò che ho scritto; sembra che tu stia cercando di difenderti senza essere veramente costruttivo. In che modo lo trovi vago? Come lo riscriveresti? Vuoi modificare la domanda? Vuoi chiedere Doorknob?
Mitch Schwartz,

1
Oh, quindi dobbiamo solo rimuovere le sequenze contigue?
mbomb007,

Risposte:


10

RIBELLE - 104

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

Uso:

Input: legge una riga dallo stdin.

Output: stampa una riga su stdout.

Anomalie *:

  • L'inserimento _provoca la lettura e l'utilizzo di un'altra riga, anziché l'output di nulla.
  • Il secondo test emette ++++>----<invece di +++>-<+>---<. Ma va bene, vero? ;)
  • >-<+ecc. vengono sostituiti con +>-<ecc.

spoiler:

L'implementazione dell'anomalia n. 3 rende le cose abbastanza banali.

* Non è un bug, è una funzione!


"non è un bug è una caratteristica" +1!
Rohan Jhunjhunwala,

36

Brainfuck, 579 byte

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

Con formattazione e alcuni commenti:

,
[
  <<+>> >>+<<
  [
    [<+> >+<-]
    ++++++[>-------<-]
    >-
    [
      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
          ++.[-]
          >>>>>>>
        ]
        <
      ]
    ]
    >>
  ]
  <[>>>>>>>]
  +[-<<<<<[-]<<]
  ,
]

Questo utilizza lo stesso approccio della soluzione di Keith Randall, minimizzando tutte le sequenze contigue di in +-<>modo ottimale mediante simulazione. Ad esempio, +++>-<+>---<diventa ++++>----<e >+<+<<+>+<->>>>diventa +<+>>+>.

Provalo online. (Se il valore assoluto di una cella simulata si avvicina a 256, ci saranno problemi di overflow.)

La struttura generale è

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

Il nastro è diviso in nodi a 7 celle; all'inizio del ciclo interno, il layout di memoria è

0 s 0 c 0 a b

dove sè un flag booleano per la cella iniziale, cè il carattere corrente, aè la parte negativa del valore della cella simulata (più uno) ed bè la parte positiva del valore della cella simulata.

Quando viene stampata la sequenza minimizzata, il layout di memoria è

d n e 0 0 a b

dove dè un flag booleano per la direzione, ae bsono come prima (ma diventano uno / zero quando stampati) e ne esono solo diversi da zero per il nodo finale; nè correlato a quante volte il nodo è stato visto ed eè il valore del carattere che ha interrotto il ciclo interno (più uno).

Inizialmente ho considerato di tenere traccia di più informazioni per nodo: nodo più a sinistra e più a destra come flag booleani e posizione del nodo in relazione ai nodi iniziale e finale. Ma possiamo evitarlo guardando le celle vicine quando necessario e eseguendo scansioni sinistra e destra per trovare il nodo iniziale.

Quando si stampa la sequenza minimizzata e si decide come spostare il puntatore simulato, possiamo adottare un approccio generale: iniziare allontanandosi dal nodo finale (in una direzione arbitraria se i nodi iniziale e finale sono uguali), girare all'estrema sinistra e all'estrema destra nodi e stop in base al numero di volte in cui il nodo finale è stato visto: 3 volte se i nodi iniziale e finale sono uguali, altrimenti 2.


2
Fonte: brainfuck. Target: brainfuck. +1
Erik the Outgolfer,


1
Lascerò che questo attiri un po 'di attenzione e assegnerò la generosità in un giorno o due
lirtosiast

1
@MitchSchwartz Ti è capitato di testare il tuo codice con il tuo codice? In realtà potresti accorciarlo! #meta
WallyWest,

1
@WallyWest (che sembra risparmiare 7 byte!) Nevermind, il codice nel permalink ha interruzioni di riga.
Dennis,

7

Python, 404 caratteri

Questo codice esegue una perfetta ottimizzazione di tutte le sottosequenze di +-<>. Un po 'più di quanto hai chiesto, ma il gioco è fatto.

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) 

Funziona simulando le +-<>operazioni sul nastro t. sè la posizione iniziale sul nastro ed pè la posizione corrente. Dopo la simulazione, capisce in [a,b]che misura deve essere operato e fa tutto il +/- in un passaggio ottimale.


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 (per favore perdona l'uso di bit.ly qui, l'intero URL romperà il markdown)

Versione non compressa (con codice di debug):

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

Un modo alternativo di pubblicare demo di Coffeescript è usare JSFiddle . Sul margine sinistro è presente un riquadro di configurazione "Lingue" che consente di utilizzare CoffeeScript anziché JS.
Peter Taylor,

@PeterTaylor Grazie, sapevo già di JSFiddle, ma non che fosse in grado di usare CoffeeScript
TimWolla il

Questo non riesce >+.-<, producendo la stringa vuota invece di lasciarla invariata.
Mitch Schwartz,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.