Fault-Tolerant Hello World (aka l'intervista)


66

Alla fine della tua intervista, il Male Interviewer ti dice: "Facciamo in modo che tutti i nostri candidati facciano un breve test di codifica, per vedere se sanno davvero di cosa stanno parlando. Non preoccuparti, è facile. E se crei un programma di lavoro, ti offrirò immediatamente il lavoro ". Ti indica di sederti a un computer vicino. "Tutto quello che devi fare è creare un programma Hello World funzionante. Ma" - e sorride ampiamente - "c'è un problema. Sfortunatamente l'unico compilatore che abbiamo su questa macchina ha un piccolo bug. Elimina casualmente un carattere dal file di codice sorgente prima della compilazione. Ok, ci vediamo tra cinque minuti! " E esce dalla stanza, fischiettando allegramente.

Potete garantire che otterrete il lavoro?

L'obiettivo

Scrivi un programma che stamperà Hello, world!sullo standard output anche dopo che un singolo carattere è stato rimosso da qualsiasi posizione nel file. O vieni il più vicino possibile a questo.

Le regole

Nessuna uscita estranea : Hello, world!deve essere l'unica cosa sostanziale stampata sull'output standard. Va bene includere altri personaggi se sono prodotti naturalmente dalla tua lingua preferita - come una nuova riga finale o anche qualcosa di simile [1] "Hello, world!"(ad esempio se stavi usando R), ma deve stampare sempre la stessa cosa ogni volta. Non è possibile stampare Hello, world!Hello, world!o Hello world!" && x==1alcune volte, ad esempio. Sono tuttavia ammessi avvisi.

Test Per verificare il tuo punteggio, devi testare ogni possibile permutazione del programma: testalo con ogni carattere rimosso e vedi se produce l'output corretto. Di seguito ho incluso un semplice programma Perl per questo scopo, che dovrebbe funzionare in molte lingue. Se non funziona per te, crea un programma di test e includilo nella tua risposta.

Punteggio Il tuo punteggio è il numero di volte in cui il tuo programma fallisce . In altre parole, il numero di posizioni individuali nel file in cui l'eliminazione di un carattere impedisce al programma di funzionare. Il punteggio più basso vince. In caso di pareggio, vince il codice più corto.

Trivial Solutions come "Hello, world!"in diverse lingue (punteggio di 15) sono accettabili, ma non vinceranno. Ho almeno trovato una soluzione Perl con un punteggio di 4, che posterò alla fine.

Aggiornamento: il vincitore ufficiale utilizzerà un linguaggio di programmazione completo di Turing e non utilizzerà alcun meccanismo predefinito di stampa Hello, world!. Qualsiasi risorsa esterna (diversa dalle librerie standard per la tua lingua) utilizzata viene considerata parte del programma e soggetta alla stessa cancellazione di 1 carattere. Questi requisiti erano fissati alla scrivania su un post-it. Mi scuso se non li hai visti all'inizio.

Aggiornamento 2: Sì, il tuo programma deve effettivamente eseguire l'attività descritta sopra per ricevere un punteggio! Ciò significa che dovrebbe essere stampato con successo Hello, world!almeno una volta. Questo avrebbe dovuto essere ovvio. Anche le opzioni della riga di comando e altre impostazioni che aggiungono funzionalità fanno parte del programma e sono soggette all'eliminazione di singoli caratteri. Il programma deve svolgere il proprio compito senza alcun input da parte dell'utente. Un errore nella compilazione conta nel conteggio errori.

Buona programmazione e che tu possa ottenere il lavoro. Ma se fallisci, probabilmente non volevi lavorare per quel boss malvagio comunque.

Script di prova Perl:

use warnings;
use strict;

my $program   = 'test.pl';
my $temp_file = 'corrupt.pl';
my $command = "perl -X $temp_file"; #Disabled warnings for cleaner output.
my $expected_result = "Hello, world!";

open my $in,'<',$program or die $!;
local $/;           #Undef the line separator   
my $code = <$in>;   #Read the entire file in.

my $fails = 0;
for my $omit_pos (0..length($code)-1)
{
    my $corrupt = $code;
    $corrupt =~ s/^.{$omit_pos}\K.//s;  #Delete a single character

    open my $out,'>',$temp_file or die $!;
    print {$out} $corrupt;  #Write the corrupt program to a file
    close $out;

    my $result = `$command`;    #Execute system command.
    if ($result ne $expected_result)
    { 
        $fails++;
        print "Failure $fails:\nResult: ($result)\n$corrupt";
    }
}

print "\n$fails failed out of " . length $code;

1
Il carattere cancellato può causare la compilazione del programma? È ancora considerato non funzionante?
Lochok,

@lochok, sì, sarebbe considerato un fallimento. Qualsiasi carattere eliminato che porta a Hello, World!non essere stampato è un errore.


@Walkerneo, grazie! Ho cercato domande simili e non l'ho trovata. Penso che questo sia significativamente diverso, però. In particolare, tale domanda garantisce che devono essere gestite solo le modifiche che comportano un codice sintatticamente valido.

Potresti dare un esempio di "opzioni della riga di comando e altre impostazioni che aggiungono funzionalità"? Intendi switch e impostazioni dati al programma stesso, o usando switch e impostazioni all'interno dell'ambiente di build?
CasaDeRobison,

Risposte:


129

Befunge, Punteggio 0

Penso di averlo risolto: nessuna eliminazione di singoli caratteri cambierà l'output.
L'eliminazione di qualsiasi personaggio dalla riga 1 non cambia nulla, ma continua a scendere nello stesso posto.
Le righe 2 e 3 sono ridondanti. Normalmente viene eseguita la riga 2, ma se si elimina un carattere da esso, <viene perso e la riga 3 prende il comando.
Anche l'eliminazione di newline non la interrompe (ha interrotto la mia versione precedente).
Nessun programma di test, scusa.

EDIT : semplificato molto.

                              vv
@,,,,,,,,,,,,,"Hello, world!"<<
@,,,,,,,,,,,,,"Hello, world!"<<

Una breve spiegazione del flusso:

  1. Befunge inizia l'esecuzione da in alto a sinistra, spostandosi a destra. Gli spazi non fanno nulla.
  2. v gira il flusso di esecuzione verso il basso, quindi scende di una riga.
  3. < gira a sinistra il flusso di esecuzione, quindi legge la riga 2 in ordine inverso.
  4. "Hello, world!"spinge la stringa nello stack. Viene spinto in ordine inverso, perché stiamo eseguendo da destra a sinistra.
  5. ,fa scoppiare un personaggio e lo stampa. L'ultimo carattere premuto viene stampato per primo, il che inverte nuovamente la stringa.
  6. @ termina il programma.

2
+1, ottima soluzione. Non credo sia necessario un programma di test, perché è ovvio che esiste solo un piccolo numero di eliminazioni potenzialmente significative.

4
Così facile da verificare e nessuna discussione in questione. Genio!
Karma Fusebox,

Congratulazioni per un'ottima soluzione.

2
So che questo non è code-golf , ma ecco una versione in 66 byte .
MD XF,

42

Perl, punteggio 0

(147 caratteri)

Ecco la mia soluzione, che sono riuscito a ottenere da 4 a 0:

eval +qq(;\$_="Hello, world!";;*a=print()if length==13or!m/./#)||
+eval +qq(;\$_="Hello, world!";;print()if*a!~/1/||!m/./#)##)||
print"Hello, world!"

Deve apparire tutto su una riga per funzionare; le interruzioni di riga sono solo per "leggibilità".

Trae vantaggio dalla sintassi patologicamente permissiva di Perl. Alcuni punti salienti:

  • Le parole chiave non riconosciute vengono trattate come stringhe. Quindi quando evaldiventa evl, questo non è un errore se una stringa è consentita in quel punto.
  • +Operatore unario , che non fa altro che chiarire la sintassi in determinate situazioni. Questo è utile con quanto sopra, perché function +argument(dove + è unario) diventa string + argument(addizione) quando un nome di funzione viene modificato e diventa una stringa.
  • Molti modi per dichiarare le stringhe: una stringa tra virgolette doppie qq( )può diventare una stringa con virgolette singole q(); una stringa delimitata da parentesi qq(; ... )può diventare una stringa delimitata da un punto e virgola qq; ... ;. #le stringhe interne possono eliminare i problemi di bilanciamento convertendo le cose in commenti.

La lunghezza di questo può probabilmente essere leggermente ridotta, anche se dubito che la soluzione di Ugoren possa essere battuta.


13
+1 per le interruzioni di riga sono solo leggibili ...
Bakuriu,

40

HQ9 +

Questo non mancherà mai di produrre il risultato desiderato quando un personaggio viene eliminato, quindi ottiene un punteggio pari a zero.

HH

Quando inizio?


1
Produce però "ciao, mondo", non "ciao, mondo!" come specificato.
Paul R,

16
Non ha senso, la lingua è stata appena erroneamente specificata sul wiki di esolang;)
skeevey,

11
Buono per te se hanno un compilatore HQ9 + sul computer dell'intervista ... :)

Potresti scrivere il tuo compilatore buggy.
PyRulez,

2
@ mbomb007 Questo interprete stampa Hello, world!per il Hcomando.
Dennis,

12

Befunge-98 , punteggio 0, 45 byte

20020xx""!!ddllrrooww  ,,oolllleeHH""cckk,,@@

Provalo online!

Sebbene sia già stata trovata una soluzione ottimale (e non esiste un pareggio), ho pensato di dimostrare che questo può essere notevolmente semplificato con Befunge 98.

Spiegazione

L' 20020xximposta affidabile delta (gradini del puntatore all'istruzione tra zecche) per (2,0)modo che a partire dalla prima x, viene eseguito solo ogni altro comando. Vedi questa risposta per una spiegazione dettagliata del perché funziona. Successivamente, il codice è semplicemente:

"!dlrow ,olleH"ck,@

Innanzitutto inseriamo tutti i codici personaggio rilevanti nello stack con "!dlrow ,olleH". Quindi ck,significa stampare la parte superiore della pila ( ,), 13 ( cpiù 1) volte ( k). @termina il programma.


11

J, 7 punti

Selezione di ogni lettera con posizione dispari:

   _2{.\'HHeellllo,,  wwoorrlldd!!'
Hello, world!

5
La stessa cosa in golfscript sarebbe 4 punti:'HHeelllloo,, wwoorrlldd!!'2%
cardboard_box

@cardboard_box Sentiti libero di inviarlo. :)
randomra,

Voto perché lo capisco e non mi viene voglia di imbrogliare.
Michael Stern,

3

Befunge-93, Punteggio 0 (63 byte)

So che questa non è una sfida del code-golf, ma ho pensato che sarebbe interessante vedere se la soluzione Befunge-93 esistente potesse essere migliorata in termini di dimensioni. Inizialmente avevo sviluppato questa tecnica per l'uso nella simile sfida Error 404 , ma la necessità di un payload avvolgente in quel caso ha reso la soluzione a 3 linee più ottimale.

Questo non è abbastanza buono come la risposta Befunge-98 di Martin, ma è comunque una riduzione abbastanza significativa della soluzione vincente Befunge-93.

<>>  "!dlrow ,olleH">:#,_@  vv
  ^^@_,#!>#:<"Hello, world!"<<>#

Provalo online!

Spiegazione

Esistono due versioni del payload. Per un programma inalterato, il primo <fa eseguire il programma da destra a sinistra, avvolgendolo fino alla fine della linea, fino a quando non raggiunge una vdirezione verso la seconda linea e una <direzione da sinistra a destra del carico utile.

Un errore sulla seconda riga provoca invece lo <spostamento a sinistra della finale e la sua sostituzione con una >direzione del flusso a destra. Il #comando (bridge) non ha nulla su cui saltare, quindi il codice continua fino a quando non si avvolge e raggiunge ^a all'inizio della riga, indirizzandolo fino alla prima riga, quindi >indirizzandolo direttamente nella destra carico utile sinistro.

La maggior parte degli errori sulla prima riga fa semplicemente vspostare i comandi finali di uno, ma ciò non altera il flusso principale del codice. L'eliminazione del primo <è leggermente diversa, tuttavia, in tal caso il percorso di esecuzione scorre direttamente nel payload da sinistra a destra sulla prima riga.

L'altro caso speciale è la rimozione dell'interruzione di linea. Quando il codice termina alla fine della riga, in questo caso è ora la fine di quella che era la seconda riga. Quando incontra il #comando da destra, questo salta sopra >e quindi continua direttamente nel payload da destra a sinistra.

In caso di dubbi, ho anche testato con lo script perl e ha confermato che "0 fallito su 63".


0

Gol> <> , punteggio 0, 38 byte

<<H"Hello, world!"/
H"Hello, world!" <

La lingua viene rilasciata dopo la sfida.

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.