Fehlertolerante Hallo Welt (auch bekannt als das Interview)

66

Am Ende Ihres Interviews sagt Ihnen der Evil Interviewer: "Wir veranlassen alle unsere Bewerber, einen kurzen Codierungstest durchzuführen, um festzustellen, ob sie wirklich wissen, wovon sie sprechen. Machen Sie sich keine Sorgen, es ist einfach. Und wenn Sie erstellen Als Arbeitsprogramm biete ich Ihnen den Job sofort an. " Er weist Sie an, sich an einen Computer in der Nähe zu setzen. "Alles, was Sie tun müssen, ist, ein funktionierendes Hello World-Programm zu erstellen. Aber" - und er grinst breit - "es gibt einen Haken. Leider hat der einzige Compiler, den wir auf diesem Computer haben, einen kleinen Fehler. Er löscht zufällig ein Zeichen aus dem Quellcode-Datei vor dem Kompilieren. Ok, wir sehen uns in fünf Minuten! " Und er geht aus dem Raum und pfeift glücklich.

Können Sie garantieren, dass Sie den Job bekommen?

Die Aufgabe

Schreiben Sie ein Programm, das Hello, world!auch nach dem Entfernen eines einzelnen Zeichens von einer beliebigen Position in der Datei auf die Standardausgabe gedruckt wird . Oder kommen Sie dem so nahe wie möglich.

Die Regeln

Keine überflüssige Ausgabe - Hello, world!muss das einzige Wesentliche sein, das auf die Standardausgabe gedruckt wird. Es ist in Ordnung, andere Zeichen einzuschließen, wenn diese von der Sprache Ihrer Wahl erzeugt werden - wie z. B. eine abschließende Zeile oder etwas Ähnliches [1] "Hello, world!"(z. B. wenn Sie R verwendet haben), aber es muss jedes Mal genau das Gleiche gedruckt werden. Es kann zum Beispiel nicht Hello, world!Hello, world!oder zeitweise gedruckt werden Hello world!" && x==1. Warnungen sind jedoch zulässig.

Testen Um Ihre Punktzahl zu testen, müssen Sie jede mögliche Permutation des Programms testen: Testen Sie es mit jedem entfernten Zeichen und prüfen Sie, ob es die richtige Ausgabe liefert. Ich habe ein einfaches Perl-Programm für diesen Zweck unten aufgeführt, das für viele Sprachen funktionieren sollte. Wenn es bei Ihnen nicht funktioniert, erstellen Sie bitte ein Testprogramm und fügen Sie es Ihrer Antwort bei.

Bewertung Ihre Punktzahl gibt an, wie oft Ihr Programm fehlschlägt . Mit anderen Worten, die Anzahl der einzelnen Positionen in Ihrer Datei, an denen ein Zeichen gelöscht wird, verhindert, dass Ihr Programm funktioniert. Die niedrigste Punktzahl gewinnt. Bei einem Gleichstand gewinnt der kürzeste Code.

Triviale Lösungen wie "Hello, world!"in mehreren Sprachen (Punktzahl 15) sind akzeptabel, aber sie werden nicht gewinnen. Ich habe zumindest eine Perl-Lösung mit einer Punktzahl von 4 gefunden, die ich irgendwann posten werde.

Update: Der offizielle Gewinner wird eine Programmiersprache von Turing-complete verwenden und keinen vordefinierten Mechanismus verwenden, der gedruckt wird Hello, world!. Alle externen Ressourcen (mit Ausnahme der Standardbibliotheken für Ihre Sprache), die verwendet werden, werden als Teil Ihres Programms betrachtet und unterliegen derselben 1-Zeichen-Löschung. Diese Anforderungen wurden auf einem Post-It-Zettel an den Schreibtisch geklebt. Entschuldigung, wenn Sie sie zuerst nicht gesehen haben.

Update 2: Ja, Ihr Programm muss die oben beschriebene Aufgabe erfüllen, um eine Punktzahl zu erhalten! Das heißt, es sollte Hello, world!mindestens einmal erfolgreich gedruckt werden. Das hätte offensichtlich sein müssen. Befehlszeilenoptionen und andere Einstellungen, die Funktionen hinzufügen, gehören ebenfalls zu Ihrem Programm und unterliegen der Löschung einzelner Zeichen. Das Programm muss seine Aufgabe ohne Benutzereingabe erfüllen. Ein Fehler beim Kompilieren zählt in Ihrer Fehleranzahl.

Viel Spaß beim Programmieren und mögt ihr den Job bekommen. Aber wenn du versagst, wolltest du wahrscheinlich sowieso nicht für diesen bösen Boss arbeiten.

Perl-Testskript:

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;
dkudriavtsev
quelle
1
Kann das gelöschte Zeichen dazu führen, dass das Programm nicht kompiliert? Gilt das immer noch als nicht funktionierend?
Lochok
@lochok, ja, das würde als Misserfolg gelten. Jedes gelöschte Zeichen, das dazu führt, dass es Hello, World!nicht gedruckt wird, ist ein Fehler.
2
Ähnliche Frage: codegolf.stackexchange.com/questions/4486/…
Mowwwalker
@ Walkerneo, danke! Ich habe nach ähnlichen Fragen gesucht und diese nicht gefunden. Ich denke, das ist jedoch deutlich anders. Diese Frage garantiert insbesondere, dass nur Änderungen behandelt werden müssen, die zu einem syntaktisch gültigen Code führen.
Könnten Sie ein Beispiel für "Befehlszeilenoptionen und andere Einstellungen, die Funktionen hinzufügen" geben? Meinen Sie Schalter und Einstellungen, die dem Programm selbst zugewiesen wurden, oder verwenden Sie Schalter und Einstellungen in der Build-Umgebung?
CasaDeRobison

Antworten:

129

Befunge, Score 0

Ich denke, ich habe es geknackt - keine Löschung einzelner Zeichen wird die Ausgabe ändern.
Das Löschen eines Zeichens aus Zeile 1 ändert nichts - es wird immer noch an der gleichen Stelle gelöscht.
Die Zeilen 2 und 3 sind redundant. Normalerweise wird Zeile 2 ausgeführt. Wenn Sie jedoch ein Zeichen aus der <Zeile löschen, wird das Zeichen übersehen und Zeile 3 übernimmt die Verantwortung.
Das Löschen von Zeilenumbrüchen macht es auch nicht kaputt (es hat meine vorherige Version kaputt gemacht).
Kein Testprogramm, sorry.

EDIT : viel vereinfacht.

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

Eine kurze Erklärung des Ablaufs:

  1. Befunge startet die Ausführung von oben links und bewegt sich nach rechts. Leerzeichen machen nichts.
  2. v Dreht den Ausführungsfluss nach unten, sodass er eine Zeile nach unten geht.
  3. < Dreht den Ausführungsfluss nach links, so liest er Zeile 2 in umgekehrter Reihenfolge.
  4. "Hello, world!"schiebt die Zeichenfolge auf den Stapel. Es wird in umgekehrter Reihenfolge verschoben, da wir von rechts nach links ausführen.
  5. ,Knallt ein Zeichen und druckt es aus. Das zuletzt gedrückte Zeichen wird zuerst gedruckt, wodurch die Zeichenfolge erneut umgekehrt wird.
  6. @ Beendet das Programm.
ugoren
quelle
2
+1, tolle Lösung. Ich glaube nicht, dass ein Testprogramm benötigt wird, da es offensichtlich nur eine kleine Anzahl von potenziell signifikanten Löschungen gibt.
4
So einfach zu überprüfen und keine Diskussion beteiligt. Genius!
Karma Fusebox
Herzlichen Glückwunsch zu einer hervorragenden Lösung.
2
Ich weiß, dass dies kein Code-Golf ist , aber hier ist eine Version in 66 Bytes .
MD XF
42

Perl, Score 0

(147 Zeichen)

Hier ist meine Lösung, die ich von 4 auf 0 gebracht habe:

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

Es muss alles in einer Zeile stehen, damit es funktioniert. Zeilenumbrüche dienen nur der "Lesbarkeit".

Es profitiert von Perls pathologisch zulässiger Syntax. Einige Höhepunkte:

  • Barewords, die nicht erkannt werden, werden als Zeichenfolgen behandelt. Wenn also evalwird evl, ist das kein Fehler, wenn an dieser Stelle eine Zeichenfolge zulässig ist.
  • Unärer +Operator, der in bestimmten Situationen nichts anderes tut als die Syntax zu disambiguieren. Dies ist im Zusammenhang mit dem oben function +argumentGesagten nützlich, da (wobei + unär ist) zu string + argument(Addition) wird, wenn ein Funktionsname verkürzt und zu einer Zeichenfolge wird.
  • Es gibt viele Möglichkeiten, Zeichenfolgen zu deklarieren: Eine Zeichenfolge in doppelten Anführungszeichen qq( )kann eine Zeichenfolge in einfachen Anführungszeichen werden q(). Eine durch Klammern begrenzte Zeichenfolge qq(; ... )kann zu einer durch ein Semikolon begrenzten Zeichenfolge werden qq; ... ;. #Durch die Konvertierung von Elementen in Kommentare können in Strings auftretende Probleme behoben werden.

Die Länge davon kann wahrscheinlich etwas reduziert werden, obwohl ich bezweifle, dass die Lösung von ugoren geschlagen werden kann.


quelle
13
+1 für Zeilenumbrüche dienen nur der Lesbarkeit ...
Bakuriu
40

HQ9 +

Dies wird niemals das beabsichtigte Ergebnis verpassen, wenn ein Zeichen gelöscht wird, sodass eine Punktzahl von Null erreicht wird.

HH

Wann fange ich an?

Skeevey
quelle
1
Es produziert "Hallo, Welt", nicht "Hallo, Welt!" wie angegeben.
Paul R
16
Unsinn, die Sprache wurde im esolang-Wiki einfach falsch angegeben;)
skeevey
11
Gut für dich, wenn sie einen HQ9 + -Compiler auf dem Interviewcomputer haben ... :)
Sie könnten Ihren eigenen Buggy-Compiler schreiben.
PyRulez
2
@ mbomb007 Dieser Interpreter druckt Hello, world!für den HBefehl.
Dennis
12

Befunge-98 , Score 0, 45 Bytes

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

Probieren Sie es online!

Obwohl bereits eine optimale Lösung gefunden wurde (und es keinen Tie Breaker gibt), dachte ich, ich würde zeigen, dass dies mit Befunge 98 erheblich vereinfacht werden kann.

Erläuterung

Der 20020xxsetzt das Delta (die Schritte des Befehlszeigers zwischen Ticks) zuverlässig auf, (2,0)so dass ab dem ersten xnur jeder zweite Befehl ausgeführt wird. In dieser Antwort finden Sie eine detaillierte Erklärung, warum dies funktioniert. Danach lautet der Code lediglich:

"!dlrow ,olleH"ck,@

Zuerst schieben wir alle relevanten Zeichencodes mit auf den Stapel "!dlrow ,olleH". Dann ck,heißt es, die Oberseite des Stapels ( ,) 13 ( cplus 1) mal ( k) zu drucken . @Beendet das Programm.

Martin Ender
quelle
11

J, 7 Punkte

Auswahl jedes Buchstabens mit ungerader Position:

   _2{.\'HHeellllo,,  wwoorrlldd!!'
Hello, world!
randomra
quelle
5
Dasselbe in golfscript würde 4 Punkte sein:'HHeelllloo,, wwoorrlldd!!'2%
cardboard_box
@cardboard_box Fühlen Sie sich frei, es einzureichen. :)
randomra
Upvoting, weil ich es verstehe und es sich nicht nach Schummeln anfühlt.
Michael Stern
3

Befunge-93, Score 0 (63 Bytes)

Ich weiß, dass dies keine Code-Golf-Herausforderung ist, aber ich dachte, es wäre interessant zu sehen, ob die vorhandene Befunge-93-Lösung hinsichtlich der Größe verbessert werden könnte. Ich hatte diese Technik ursprünglich für die Verwendung in der ähnlichen Fehler 404- Herausforderung entwickelt, aber die Notwendigkeit einer umhüllenden Nutzlast in diesem Fall machte die 3-Zeilen-Lösung optimaler.

Dies ist nicht ganz so gut wie Martins Befunge-98-Antwort, aber es ist immer noch eine ziemlich deutliche Reduzierung der erfolgreichen Befunge-93-Lösung.

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

Probieren Sie es online!

Erläuterung

Es gibt zwei Versionen der Nutzlast. Bei einem unveränderten Programm <bewirkt das erste, dass das Programm von rechts nach links ausgeführt wird und bis zum Ende der Zeile umgebrochen wird, bis es eine vWeiterleitung in die zweite Zeile und eine <Weiterleitung von links in die Version von links nach rechts erreicht der Nutzlast.

Ein Fehler in der zweiten Zeile führt dazu, dass das Finale <nach links verschoben und >stattdessen durch ein Richten des Flusses nach rechts ersetzt wird. Der #(Brücken-) Befehl hat nichts zu überspringen, daher setzt sich der Code nur fort, bis er umbrochen wird und a ^am Zeilenanfang erreicht, bis er in die erste Zeile und dann >direkt in die Rechts-zu-Rechts- Zeile umgeleitet wird. Nutzlast verlassen.

Die meisten Fehler in der ersten Zeile bewirken nur, dass die endgültigen vBefehle um eins verschoben werden. Dies ändert jedoch nichts am Hauptfluss des Codes. Das Löschen der ersten <ist jedoch etwas anders - in diesem Fall fließt der Ausführungspfad direkt in die Nutzdaten von links nach rechts in der ersten Zeile.

Der andere Sonderfall ist die Beseitigung des Zeilenumbruchs. Wenn der Code bis zum Ende der Zeile umgebrochen wird, ist dies in diesem Fall das Ende der ehemaligen zweiten Zeile. Wenn er #von rechts auf den Befehl stößt , springt dieser über die >und fährt damit direkt in die Nutzlast von rechts nach links fort.

Im Zweifelsfall habe ich auch mit dem Perl-Skript getestet und bestätigt, dass "0 von 63 fehlgeschlagen" ist.

James Holderness
quelle
0

Gol> <> , Score 0, 38 Bytes

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

Die Sprache wird nach der Herausforderung freigegeben.

jimmy23013
quelle