Flujo de datos no confiable

8

Su desafío es desarrollar un programa que imite un flujo de transmisión de datos. Su programa debe leer la entrada de stdin y enviarla directamente a stdout. Para hacer que el problema sea más interesante, la secuencia de salida es 'defectuosa' y debe cumplir varios requisitos:

  1. Debería haber un 10% de posibilidades de que cada personaje se cambie +1 código ascii (por ejemplo, 'a' se convierte en 'b', '9' se convierte en ':'), etc.
  2. La entrada y la salida solo deben cubrir valores ascii imprimibles ('!' A '~', decimal 33 a decimal 126, inclusive). Si el +1 aleatorio ocurre en un '~' (decimal 126), un '!' (decimal 33) se debe generar en su lugar.
  3. Si tres caracteres se desplazan aleatoriamente en una fila, el programa debe mostrar "CÓDIGO DE ERROR 4625: ERROR INVERTIRABLE, CONTACTE CON SU ADMINISTRADOR DE SISTEMA" (línea posterior opcional) y detener la ejecución.

Para simplificar el problema, aquí hay algunos otros criterios:

  1. Puede suponer que la entrada siempre será válida; es decir, solo contendrá valores '!' a través de '~'.
  2. El programa debe continuar hasta que tres caracteres se desplacen aleatoriamente en una fila; es seguro asumir que EOF nunca ocurrirá.
  3. La aleatoriedad debe diferir entre corridas; Si su generador de números aleatorios necesita ser sembrado para obtener un resultado único en cada ejecución, entonces su código debe ser inicializado.
  4. Debe escribir un programa, no una función.
  5. Debe tomar la entrada de stdin y escribir la salida en stdout.
  6. No puede utilizar ninguna biblioteca o recurso externo.
  7. Su código debe tener un intérprete o compilador disponible y que funcione libremente.

Aplican reglas estándar de código de golf. El ganador es quien tiene el programa más corto publicado dentro de dos semanas (jueves 20 de febrero de 2014).

Josh
fuente
¿Está bien suponer que habrá un EOF? En particular, ¿puedo leer toda la entrada en la memoria antes de producir cualquier salida, como lo hace normalmente GolfScript?
Ilmari Karonen
@IlmariKaronen probablemente no; no sería posible garantizar suficiente entrada para que su RNG cometa 3 errores consecutivos.
TypeIA
1
@IlmariKaronen según las especificaciones, EOF nunca ocurrirá. La única condición de salida es tres caracteres volteando en una fila.
Josh

Respuestas:

4

Befunge-98, 166 159 156 155 148

Este mejora con respecto a la otra excelente respuesta Befunge con la probabilidad correcta (1/10) y es un poco más compacto:

~>?#v?1+\1>+\:'~1+-4k#x07_$'!>,:3-!#v_
>#?>>>\$\0^>
^<<
A"##  "CT YOUR SYSTEM ADMINISTRATOR"<@,kM'"ERROR CODE 4625: UNRECOVERABLE ERROR, PLEASE CONT
TypeIA
fuente
Algunos comentarios de implementación: xse usa en dos lugares como un "goto". El ajuste de bordes se usa (ab) ampliamente, incluido el control que fluye a través del espacio entre ASEy CONTACT. El contador "3 en una fila" se mantiene en la parte inferior de la pila; la barra invertida se usa para intercambiar y acceder a ella donde sea necesario.
TypeIA
1
Esto es calidad antes de aquí. Realmente me gusta lo que hiciste con la cuerda al final, para permitir el punto de entrada donde lo necesitabas
Cruncher
Intenté muchas cosas este fin de semana para reducir esto y no puedo, ni por un solo personaje. ¡Pero no me he rendido! :)
TypeIA
1
¡Reestructuré el bloque RNG para usar solo tres ?instrucciones (una de las cuales es golpeada por dos caminos, por lo que la probabilidad sigue siendo exactamente 1/10) e hizo algunos otros ajustes menores para eliminar 7 caracteres más!
TypeIA
¡Felicidades por ganar!
Josh
4

C, 168 caracteres

i;main(c){for(srand(&c);i++<3;putchar(rand()%10?i=0,c:c-126?c+1:33))c=getchar();
puts("ERROR CODE 4625: UNRECOVERABLE ERROR, PLEASE CONTACT YOUR SYSTEM ADMINISTRATOR");}

La siembra de esta solución del PRNG aprovecha el hecho de que los sistemas operativos modernos cambian la ubicación de la pila en la memoria en cada ejecución, como una medida básica contra las vulnerabilidades de destrucción de la pila.

caja de pan
fuente
Puede deshacerse de la variable cpor completo moviendo la getchar()llamada putchar()y usando algunas matemáticas elegantes ...
Josh
Creo que todavía necesita tenerlo cpara poder probar getchar()el valor contra 126 además de pasárselo putchar().
breadbox
De ahí la matemática elegante ... Creo que putchar((getchar()-33+(rand()%10?i=0:1))%94+33))debería funcionar. Usando su solución como base, me lleva a 165 caracteres.
Josh
2

Ruby, 156

e=3
putc(($_.ord-33+r=rand(10)/9)%94+33)/e=r>0?e-r :3while gets(1)rescue$><<'ERROR CODE 4625: UNRECOVERABLE ERROR, PLEASE CONTACT YOUR SYSTEM ADMINISTRATOR'
Paul Prestidge
fuente
¿Podría explicar qué es eso :3while?
Uri Agassi
@UriAgassi the :3es en realidad el final de esta declaración: e=r>0?e-r :3que establece el valor de e (número de errores secuenciales restantes antes de abortar) en función de r (1 si el último carácter procesado fue un error, 0 si no). Simplemente se empujó contra el tiempo para ahorrar espacio:>
Paul Prestidge
1
¿Y Ruby reconoce el whilesin espacio antes? ¡Eso es tan oscuro e ilegible! ;)
Uri Agassi
2

Lote - 359

Abierto a sugerencias para que sea completamente compatible con las reglas de desafío.

Trabajaré para hacerlo más pequeño / mejor: quería publicarlo mientras funciona, antes de romperlo.

@echo off&setLocal enableDelayedExpansion&for /L %%a in (33,1,126)do cmd/cexit %%a&set %%a=!=exitcodeAscii!
set a=%~1
:l
if defined a (
set c=!a:~0,1!&set a=!a:~1!&set b=0&set/ar=%RANDOM%*10/32768+1
if !r!==1 for /L %%b in (33,1,126)do (
if !b!==1 echo !%%b!>>f
if "!c!"=="!%%b!" set b=1
)
if !b!==1 set/pc=<f&del f
set o=%o%!c!&goto l
) 
echo %o%

Definitivamente hay bastantes maneras de jugar golf.

h:\uprof>UDS.bat "test ing"
tesu inh

h:\uprof>UDS.bat "test ing"
tfsu ing

Sin golf -

@echo off
setLocal enableDelayedExpansion
for /L %%a in (33,1,126) do (
    cmd /c exit %%a
    set %%a=!=exitcodeAscii!
)
set a=%~1
:l
if defined a (
    set c=!a:~0,1!
    set a=!a:~1!
    set b=0
    set /a r=%RANDOM%*10/32768+1
    if !r!==1 for /L %%b in (33,1,126) do (
        if !b!==1  echo !%%b!>>f
        if "!c!"=="!%%b!" set b=1
    )
    if !b!==1 set /p c=<f& del f
    set o=%o%!c!
    goto l
) 
echo %o%
carne sin carne
fuente
2

Befunge-93 (206)

Tiene 142 caracteres que no son espacios en blanco. Técnicamente no es conforme, ya que tiene una probabilidad de 1/9 no 1/10 de error.

v$,_\1+:4-v
~> ^1:  <v_$$"ROTARTSINIMDA METSYS RUOY TCATNOC ESAELP ,RORRE ELBAREVOCERNU :5264 EDOC RORRE">:#,_@
 ^ < < < \
   1     "
 ^0?2^
   ^ 3  +"
> >?>?4^"-
   v 5  !"
 ^8?6> ^"^
   7    %"
   >   ^^<

Corre como cat /dev/urandom | tr -dc '!-~' | ./befungee.py -c 100 ../rand.

Con esta entrada !!!!aaaaaaa~~~~~~~~~~obtenemos la salida !"!!aabaaba~~~!~~~~!!que indica que los errores se manejan correctamente.

Joel Bosveld
fuente
Conseguir el 10% de posibilidades sería bastante difícil. Cada uno de sus 9 tendría que dividirse en otros 2 (lanzar el tercero de vuelta). Entonces 8 de los 18 tienen que volver al principio
Cruncher
@Cruncher que es similar al enfoque que utilicé en mi presentación de Befunge, que tiene la probabilidad correcta. Se usan cuatro? S y algunas rutas de código retroalimentan al comienzo del RNG como "nops".
TypeIA
1

PHP 190

eso es lo más lejos que podría jugarlo, pero creo que es bastante bueno que esté a menos de 100 caracteres del líder

<? while($a=fread(STDIN,1)){if(!rand(0,9)){$a=$a=='~'?'!':chr(ord($a)+1);@$i+=1;$i>2&&die("ERROR CODE 4625: UNRECOVERABLE ERROR, PLEASE CONTACT YOUR SYSTEM ADMINISTRATOR");}else$i=0;echo$a;}
Einacio
fuente
1

C # - 346 330 313 309 297 288 278 274

Un poco largo pero hace el trabajo.

using System;class m{static void Main(){int c=0;var r=new Random();while(c<3){int n=r.Next(10);var j=Console.In.Read();Console.Write((char)(n<1?j>'}'?'!':++j:j));c=n<1?c+1:0;}Console.Write("ERROR CODE 4625: UNRECOVERABLE ERROR, PLEASE CONTACT YOUR SYSTEM ADMINISTRATOR");}}
usuario3188175
fuente
1
c=n==0?c+1:0es más corto que c+=(n==0?1:-c)...
Timwi
1
(n==1?1:0)es más corto que (n==1?n--:(--n-n))(y luego, por supuesto, cambia el más tarde n==0a n==1)
Timwi
¡Muchas gracias, casi has reescrito todo el programa!
user3188175
Eres increíble.
user3188175
¿Por qué (false)? En todo caso, ¿no quieres (true)?
Timwi
1

sh bash, en OSX, 211 , 208 , 203 , 200 , 196 , 185

IFS=
while read -n1 a;do
((RANDOM>3276))&&echo $a&&t=0||{
tr !-}~ \"-~!<<<$a
((t++==2))&&echo ERROR CODE 4625: UNRECOVERABLE ERROR, PLEASE CONTACT YOUR SYSTEM ADMINISTRATOR&&exit
}
done

Ligeramente mejor que el 10% ya que aleatorio generará números entre 0 y 32767, por lo que realmente es 3,277 en 32,768 probabilidades (10,0006%).

Gracias, @Gilles (pero no estoy seguro de lo que quieres decir con la reestructuración de tiempo. También tenía algunas otras ideas en la ducha.

No es que Charles
fuente
Dado que está utilizando las funciones de bash (por lo que esta es una solución de bash, realmente), puede acortar [ $RANDOM -gt 3276 ]hacia ((RANDOM>3276))y [ $[t++] -eq 2 ]hacia ((t++==2)). Creo que también puede guardar algunos caracteres reestructurando como while read -n1 a;((RANDOM>3276))&&….
Gilles 'SO- deja de ser malvado'
@Gilles Gracias. ¿Qué quieres decir con la while read...parte?
No es que Charles
Lo siento, me trunqué en el lugar equivocado. Haz el bucle while …;do :;doneo until …;do :;donedeberías poder afeitar algunos caracteres.
Gilles 'SO- deja de ser malvado'
1

C, 260 257 237 225 189 174

Mi primer golf, sugerencias apreciadas.

n;main(){for(srand(&n);n!=3;putchar((getchar()+(rand()%10==7?!!++n:(n=0))-33%94)+33));puts("ERROR CODE 4625: UNRECOVERABLE ERROR, PLEASE CONTACT YOUR SYSTEM ADMINISTRATOR");}

7 es muy aleatorio.

Compilar te dará advertencias.

Gracias por la ayuda de breadbox y Josh.

Millinon
fuente
1
Sugerencias iniciales: dejar fuera de #include; C aceptará (con advertencias) llamadas a funciones no declaradas (dentro de los límites). Use variables globales para obtener una inicialización cero automática. Encuentre formas de usar el operador ternario en lugar de if/ elsedeclaraciones. El uso foren lugar de whilebrinda más oportunidades para reducir el número de declaraciones de nivel superior y omitir los corchetes alrededor del cuerpo del bucle. Mucho más que podría mencionarse: examine otras soluciones de C en este sitio.
breadbox
Gracias por las sugerencias: pensé que gcc se quejaría sin al menos stdio, pero aparentemente es genial. También tenía una variable tonta todavía llamada 'cuenta'. Parece que el bucle for también se reduce mucho.
Millinon
Puede declarar ny cen el ámbito global. Esto le permitiría descartar la intdeclaración y permitir que la inicialización a cero sea automática.
Josh
Decidí usar cel valor no inicializado en srand. Supongo que podría usar &co en su &nlugar, que es lo que utiliza breadbox.
Millinon
¡Me encanta el truco que se te ocurrió para eliminar la necesidad de tu segunda variable!
Josh