Compatta un programma Befunge


17

Befunge è un linguaggio di programmazione esoterico bidimensionale. L'idea di base è che i comandi (a un carattere) siano posizionati su una griglia bidimensionale. Il flusso di controllo attraversa la griglia, eseguendo i comandi su cui passa e cambiando direzione quando colpisce una freccia ( >^<v). I comandi sono basati su stack; vedi questo elenco . Vedi anche http://esolangs.org/wiki/Befunge .

Sono disponibili le specifiche per Befunge-98 .

Problema

Scrivi un programma che trasforma un programma Befunge in una rappresentazione più compatta. Ad esempio, viene stampato il seguente programma 0:

>   0   v

>   @   .

^       <

In questo caso, potrebbe essere compattato senza cambiare il comportamento del programma rimuovendo file di spazi, per dare

>0v
>@.
^ <

Trasformazioni più sofisticate potrebbero ruotare o rispecchiare sequenze di comandi ed eliminare comandi di flusso di controllo non necessari al fine di compattare il programma. Ad esempio, con questo programma:

>12345v
      6
v....7<
.
.
.
@

potresti infilare la fine del programma nel buco:

>12345v
>...@ 6
^....7<

Per il primo esempio, il programma più compatto possibile è

>0.@

È possibile utilizzare qualsiasi trasformazione purché il programma di output fornisca lo stesso risultato.

Programmi di input

I programmi di input sono programmi Befunge-98 validi.

Si può presumere che il programma di input sia deterministico. Cioè, non usa i comandi che leggono lo stato esterno: i comandi di input dell'utente &e ~, il randomizer ?, i comandi di codice auto-modificanti pe g.

Si può presumere che il programma di input sia terminato.

punteggio

Non si tratta di un codice golf, ma di un problema di scrittura di un programma che esegue il codice golf.

L'input è un insieme di casi di test (programmi Befunge che soddisfano le restrizioni di input sopra). Il punteggio totale è la somma dei punteggi per i casi di test.

Punteggio per ogni caso di test

Il punteggio è l'area dello scafo convesso delle celle non vuote nel programma di output, in cui ogni cella viene trattata come un quadrato i cui quattro angoli sono punti reticolari nel piano cartesiano. Ad esempio, un programma di

>   v
 @  <

ottiene un punteggio di 9.5.

Se il programma non termina in un periodo di tempo e memoria ragionevole su un determinato input, il punteggio è quello del programma di input. (Questo perché è possibile aggiungere banalmente un wrapper a tempo limitato che restituisce invariato il programma di input se il programma non termina in tempo.)

Se il programma del test case ha un risultato diverso (o non riesce a terminare) dopo l'elaborazione con il tuo programma, il punteggio è il punteggio del programma di input più una penalità di 100 punti.


8
Cosa deve impedire l'esecuzione del programma fino al completamento e la scrittura di un programma Befunge che stampa lo stesso output?
Keith Randall,

5
Sono ammessi "get" e "put"? Se si consente "put" (codice auto-modificante), sarà difficile fare qualsiasi cosa.
Keith Randall,

2
Da dove inizia l'esecuzione? Angolo in alto a sinistra? In tal caso, puoi spiegare l'output del secondo esempio? .significa numero intero di output, ma se si parte in alto a sinistra, allora non c'è numero intero nello stack di output.
elssar,

1
@elssar yes, .genera un numero intero. Inoltre, quando non ci sono abbastanza parametri nello stack, befunge finge invece che vi sia una quantità sufficiente di zero. Quindi il secondo esempio verrebbe prodotto 000.
daniero,

@KeithRandall: scrivere un nuovo programma con lo stesso output funziona solo per programmi con un output breve. ge pnon sono ammessi (scusate, ho dimenticato quelli; modificato).
Lumaca meccanica

Risposte:


12

Ho trascorso un lungo viaggio in aereo codificandolo. Ho scritto un compilatore pseudo befunge che esegue il programma befunge, estrae i blocchi di base e li presenta in una rappresentazione compatta.

Link al programma .

Quando eseguito con questo programma da 99 bottiglie:

92+9*                           :. v  <
>v"bottles of beer on the wall"+910<
,:
^_ $                             :.v
            >v"bottles of beer"+910<
            ,:
            ^_ $                     v
>v"Take one down, pass it around"+910<
,:
^_ $                           1-v
                                 :
        >v"bottles of beer"+910.:_          v
        ,:
        ^_ $                          ^
                    >v" no more beer..."+910<
                    ,:
                    ^_ $$ @

Genera il seguente output:

92+9*:.019+"llaw eht no "v
v  _v# :"bottles of beer"<
>    ,:    v
^  _v#     <
    >$:.019+"reeb f"v
 v _  v#:"bottles o"<
 >     ,:  v
 ^ _  v#   <
      >$019+"dnuo"v
     v"pass it ar"<
     >" ,nwod eno"v
 v _    v#:"Take "<
 >       ,:v
 ^ _    v# <
        >$1-:v
 v _      v# <
 >         :.019+"reeb "v
  v_  v#   :"bottles of"<
  >        ,v
  ^_  v#   :<
      >    $019+"llaw"v
           v" on the "<
           >"reeb fo "v
^  _^#      :"bottles"<
          >019+"...r"v
v  _v#:" no more bee"<
>    ,:    v
^  _v#     <
    >$$@    

In realtà non è molto più compatto della fonte, ma probabilmente farà di meglio su programmi più grandi / più scarsi.

Il programma è strutturato con un'area di instradamento a sinistra e contenuti di blocco di base a destra. Un blocco di base è di solito disposto in un numero pari di file in modo tale che l'ingresso e l'uscita siano adiacenti all'area di instradamento. Alla fine di ogni blocco di base, il gadget #^_ve le varianti, disposti da destra a sinistra, eseguono il ramo condizionale e instradano il flusso in colonne. All'inizio di ciascun blocco di base, queste colonne vengono instradate nelle righe per il blocco di base di destinazione.

Inoltre, se l'output è breve, genera semplicemente l'output in modo esplicito, in questo modo:

"output">:#,_@

Non ho fatto nulla per ottimizzare i blocchi di base stessi, solo il layout. Fare.

Quindi dove sono i test?


1
il link del codice sorgente sembra essere 500 in questo momento. Configurazione errata del server?
John Dvorak,

1
@JanDvorak: davvero. Fisso.
Keith Randall,

1

Sed, 5 caratteri

Quindi, anche se questo non è codegolf, ecco una soluzione che avrà un buon rapporto tra lunghezza del codice e punteggio, ma non necessariamente un buon punteggio.

/^$/d

Rimuove semplicemente le righe vuote.


10
Il tuo codice non è corretto! Non puoi semplicemente rimuovere le righe vuote. Non riesco a scrivere un codice 2D nei commenti. Ma considera un caso in cui la direzione è verso il basso e viene avviata una stringa costante ( "). Ogni linea vuota deve essere trattata come uno spazio. Se stampiamo quella stringa, il codice che hai generato non ha quegli spazi nell'output!
Saeedn,

3
Guarda il codice in ideone.com/BdcRcf Dovrebbe essere stampato b a. Ma dopo l'accorciamento, verrà stampato ba.
Saeedn,
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.