Hello World tolerante a fallas (también conocido como la entrevista)


66

Al final de su entrevista, Evil Interviewer le dice: "Hacemos que todos nuestros solicitantes tomen una breve prueba de codificación, para ver si realmente saben de qué están hablando. No se preocupen; es fácil. Y si crea un programa de trabajo, te ofreceré el trabajo de inmediato ". Él te indica que te sientes frente a una computadora cercana. "Todo lo que tiene que hacer es crear un programa Hello World que funcione. Pero", y él sonríe ampliamente, "hay un problema. Lamentablemente, el único compilador que tenemos en esta máquina tiene un pequeño error. Elimina aleatoriamente un personaje del archivo de código fuente antes de compilar. Ok, ¡nos vemos en cinco minutos! " Y sale de la habitación, silbando alegremente.

¿Puede garantizar que obtendrá el trabajo?

La tarea

Escriba un programa que imprima Hello, world!a la salida estándar incluso después de que se elimine un solo carácter de cualquier posición en el archivo. O acércate lo más posible a esto.

Las normas

Sin salida extraña : Hello, world!debe ser lo único sustantivo impreso en la salida estándar. Está bien incluir otros caracteres si el idioma de su elección los produce naturalmente, como una nueva línea final o incluso algo así [1] "Hello, world!"(por ejemplo, si estaba usando R), pero debe imprimir exactamente lo mismo cada vez. No se puede imprimir Hello, world!Hello, world!o Hello world!" && x==1parte del tiempo, por ejemplo. Las advertencias, sin embargo, están permitidas.

Pruebas Para poder determinar su puntaje, debe probar cada posible permutación del programa: pruébelo con cada carácter eliminado y vea si produce la salida correcta. He incluido un simple programa Perl para este propósito a continuación, que debería funcionar para muchos idiomas. Si no funciona para usted, cree un programa de prueba e inclúyalo en su respuesta.

Puntaje Su puntaje es la cantidad de veces que su programa falla . En otras palabras, el número de posiciones individuales en su archivo donde eliminar un carácter impide que su programa funcione. La puntuación más baja gana. En caso de empate, gana el código más corto.

Las soluciones triviales como "Hello, world!"en varios idiomas (puntaje de 15) son aceptables, pero no van a ganar. Al menos he encontrado una solución Perl con un puntaje de 4, que eventualmente publicaré.

Actualización: el ganador oficial utilizará un lenguaje de programación completo de Turing y no utilizará ningún mecanismo predefinido que imprima Hello, world!. Cualquier recurso externo (que no sean las bibliotecas estándar para su idioma) que se utiliza se considera parte de su programa y está sujeto a la misma eliminación de 1 carácter. Estos requisitos estaban pegados al escritorio en una nota adhesiva. Disculpas si no los viste al principio.

Actualización 2: Sí, ¡su programa tiene que cumplir la tarea descrita anteriormente para recibir una puntuación! Lo que significa que debería imprimirse correctamente Hello, world!al menos una vez. Esto debería haber sido obvio. Los interruptores de línea de comandos y otras configuraciones que agregan funcionalidad también cuentan como parte de su programa y están sujetos a la eliminación de un solo carácter. El programa debe cumplir su tarea sin ninguna intervención del usuario. Una falla en la compilación cuenta en su cuenta de fallas.

Programación feliz, y que consigas el trabajo. Pero si fracasas, probablemente no quieras trabajar para ese jefe malvado de todos modos.

Script de prueba de 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
¿Puede el carácter eliminado hacer que el programa no se compile? ¿Todavía se cuenta como que no funciona?
lochok

@lochok, sí, eso contaría como un fracaso. Cualquier carácter eliminado que Hello, World!no se imprima es un error.


@ Walkerneo, gracias! Busqué preguntas similares y no encontré esa. Sin embargo, creo que esto es significativamente diferente. En particular, esa pregunta garantiza que solo se deben manejar las modificaciones que resultan en un código sintácticamente válido.

¿Podría dar un ejemplo de "interruptores de línea de comandos y otras configuraciones que agregan funcionalidad"? ¿Te refieres a los interruptores y configuraciones dados al programa mismo, o al uso de interruptores y configuraciones dentro del entorno de construcción?
CasaDeRobison

Respuestas:


129

Befunge, Puntuación 0

Creo que lo descifré: ninguna eliminación de un solo carácter cambiará la salida.
La eliminación de cualquier carácter de la línea 1 no cambia nada: aún se reduce en el mismo lugar.
Las líneas 2 y 3 son redundantes. Normalmente, la línea 2 se ejecuta, pero si elimina un carácter, <se omite y la línea 3 se hace cargo.
Eliminar nuevas líneas tampoco lo rompe (sí rompió mi versión anterior).
No hay programa de prueba, lo siento.

EDITAR : simplificado mucho.

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

Una breve explicación del flujo:

  1. Befunge comienza a ejecutarse desde la parte superior izquierda, moviéndose a la derecha. Los espacios no hacen nada.
  2. v gira el flujo de ejecución hacia abajo, por lo que baja una línea.
  3. < gira el flujo de ejecución hacia la izquierda, por lo que lee la línea 2 en orden inverso.
  4. "Hello, world!"empuja la cuerda a la pila. Se empuja en orden inverso, porque estamos ejecutando de derecha a izquierda.
  5. ,aparece un personaje y lo imprime. El último carácter empujado se imprime primero, lo que invierte la cadena una vez más.
  6. @ termina el programa

2
+1, gran solución. No creo que se necesite un programa de prueba, porque es obvio que solo hay un pequeño número de eliminaciones potencialmente significativas.

44
Tan fácil de verificar y sin discusión involucrada. ¡Genio!
Karma Fusebox

Felicidades por una excelente solución.

2
Sé que esto no es code-golf , pero aquí hay una versión en 66 bytes .
MD XF

42

Perl, puntaje 0

(147 caracteres)

Aquí está mi solución, que logré obtener de 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!"

Debe aparecer todo en una línea para funcionar; los saltos de línea son solo para "legibilidad".

Se beneficia de la sintaxis patológicamente permisiva de Perl. Algunos puntos destacados:

  • Las palabras desnudas que no se reconocen se tratan como cadenas. Entonces, cuando se evalconvierte evl, eso no es un error si una cadena es permisible en ese punto.
  • +Operador unario , que no hace más que desambiguar la sintaxis en ciertas situaciones. Esto es útil con lo anterior, porque function +argument(donde + es unario) se convierte en string + argument(adición) cuando el nombre de una función se destruye y se convierte en una cadena.
  • Muchas formas de declarar cadenas: una cadena con comillas dobles qq( )puede convertirse en una cadena con comillas simples q(); una cadena delimitada por paréntesis qq(; ... )puede convertirse en una cadena delimitada por un punto y coma qq; ... ;. #Las cadenas internas pueden eliminar problemas de equilibrio al convertir las cosas en comentarios.

La duración de esto probablemente puede reducirse un poco, aunque dudo que la solución de ugoren pueda ser superada.


13
+1 para saltos de línea son solo para legibilidad ...
Bakuriu

40

HQ9 +

Esto nunca dejará de producir el resultado deseado cuando se elimina un personaje, por lo que obtiene una puntuación de cero.

HH

¿Cuando empiezo?


1
Sin embargo, produce "hola, mundo", no "¡Hola, mundo!" Como se especificó.
Paul R

16
Tonterías, el idioma se especificó incorrectamente en la wiki de esolang;)
skeevey

11
Bien por ti si tienen un compilador HQ9 + en la computadora de la entrevista ... :)

Podrías escribir tu propio compilador con errores.
PyRulez

2
@ mbomb007 Este intérprete imprime Hello, world!para el Hcomando.
Dennis

12

Befunge-98 , puntaje 0, 45 bytes

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

Pruébalo en línea!

Aunque ya se ha encontrado una solución óptima (y no hay un desempate), pensé en demostrar que esto se puede simplificar considerablemente con Befunge 98.

Explicación

El 20020xxestablece de forma fiable el delta (los pasos del puntero de instrucción entre las garrapatas) a (2,0)fin de que a partir de la primera x, sólo se ejecuta cada dos comandos. Vea esta respuesta para una explicación detallada de por qué esto funciona. Luego, el código es simplemente:

"!dlrow ,olleH"ck,@

Primero empujamos todos los códigos de caracteres relevantes en la pila con "!dlrow ,olleH". Entonces ck,significa imprimir la parte superior de la pila ( ,), 13 ( cmás 1) veces ( k). @termina el programa


11

J, 7 puntos

Seleccionar cada letra con posición impar:

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

55
Lo mismo en golfscript sería de 4 puntos:'HHeelllloo,, wwoorrlldd!!'2%
cardboard_box

@cardboard_box Siéntase libre de enviarlo. :)
randomra

Votar porque lo entiendo, y no se siente como hacer trampa.
Michael Stern

3

Befunge-93, Puntuación 0 (63 bytes)

Sé que este no es un desafío de código de golf, pero pensé que sería interesante ver si la solución Befunge-93 existente podría mejorarse en términos de tamaño. Originalmente había desarrollado esta técnica para su uso en el desafío similar Error 404 , pero la necesidad de una carga útil envolvente en ese caso hizo que la solución de 3 líneas fuera más óptima.

Esto no es tan bueno como la respuesta Befunge-98 de Martin, pero sigue siendo una reducción bastante significativa en la solución ganadora Befunge-93.

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

Pruébalo en línea!

Explicación

Hay dos versiones de la carga útil. Para un programa inalterado, el primero <hace que el programa se ejecute de derecha a izquierda, envolviendo hasta el final de la línea, hasta que lo vdirige hacia la segunda línea y lo <dirige hacia la versión de izquierda a derecha de la carga útil.

Un error en la segunda línea hace que la final <se desplace hacia la izquierda y se reemplace con una >dirección del flujo hacia la derecha. El #comando (bridge) no tiene nada sobre lo que saltar, por lo que el código continúa hasta que se envuelve y llega ^a al comienzo de la línea, dirigiéndolo hacia la primera línea y luego >dirigiéndolo directamente hacia el derecho a izquierda carga útil.

La mayoría de los errores en la primera línea solo hacen que los vcomandos finales se desplacen en uno, pero eso no altera el flujo principal del código. Sin <embargo, eliminar el primero es ligeramente diferente; en ese caso, la ruta de ejecución simplemente fluye directamente hacia la carga útil de izquierda a derecha en la primera línea.

El otro caso especial es la eliminación del salto de línea. Cuando el código se envuelve al final de la línea, en este caso ahora es el final de lo que solía ser la segunda línea. Cuando encuentra el #comando desde la derecha, salta sobre el >y, por lo tanto, continúa directamente en la carga útil de derecha a izquierda.

En caso de que haya alguna duda, también probé con el script perl y confirmó que "0 falló de 63".


0

Gol> <> , puntaje 0, 38 bytes

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

El lenguaje se lanza después del desafío.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.