Fluxo de dados não confiável

8

Seu desafio é jogar um programa que imita um fluxo de transmissão de dados. Seu programa deve ler a entrada de stdin e enviá-la diretamente para stdout. Para tornar o problema mais interessante, o fluxo de saída está com defeito e deve atender a vários requisitos:

  1. Deve haver uma chance de 10% de que cada caractere seja alterado com +1 código ASCII (ex 'a' se torna 'b', '9' se torna ':'), etc.
  2. A entrada e a saída devem cobrir apenas valores ascii imprimíveis ('!' A '~', de 33 a 126 de decimal, inclusive). Se o +1 aleatório ocorrer em um '~' (decimal 126), um '!' (decimal 33) deve ser impresso.
  3. Se três caracteres forem deslocados aleatoriamente em uma linha, o programa deverá gerar "CÓDIGO DE ERRO 4625: ERRO INCORREVÍVEL, ENTRE EM CONTATO COM O ADMINISTRADOR DO SISTEMA" (seguindo a nova linha opcional) e interrompa a execução.

Para simplificar o problema, aqui estão alguns outros critérios:

  1. Você pode assumir que a entrada sempre será válida; isto é, ele conterá apenas valores '!' através de '~'.
  2. O programa deve continuar até que três caracteres sejam deslocados aleatoriamente seguidos; é seguro assumir que o EOF nunca ocorrerá.
  3. A aleatoriedade deve diferir entre as corridas; se o seu gerador de números aleatórios precisar ser semeado para obter um resultado exclusivo a cada execução, seu código precisará semear.
  4. Você deve escrever um programa, não uma função.
  5. Você deve pegar a entrada do stdin e gravar a saída no stdout.
  6. Você não pode usar bibliotecas ou recursos externos.
  7. Seu código deve ter um interpretador ou compilador disponível e funcionando gratuitamente.

Aplicam-se as regras padrão de código de golfe. O vencedor é quem tiver o programa mais curto postado em duas semanas (quinta-feira, 20 de fevereiro de 2014).

Josh
fonte
Tudo bem assumir que haverá um EOF? Em particular, posso ler toda a entrada na memória antes de produzir qualquer saída, como o GolfScript normalmente faz?
Ilmari Karonen
@IlmariKaronen provavelmente não; não seria possível garantir entrada suficiente para o seu RNG cometer 3 erros consecutivos.
TypeIA
1
@IlmariKaronen de acordo com as especificações, o EOF nunca ocorrerá. A única condição de saída é três caracteres invertidos em uma linha.
217 Josh Josh

Respostas:

4

Befunge-98, 166 159 156 155 148

Este melhora na outra excelente resposta Befunge com a probabilidade correta (1/10) e é um pouco mais compacto:

~>?#v?1+\1>+\:'~1+-4k#x07_$'!>,:3-!#v_
>#?>>>\$\0^>
^<<
A"##  "CT YOUR SYSTEM ADMINISTRATOR"<@,kM'"ERROR CODE 4625: UNRECOVERABLE ERROR, PLEASE CONT
TypeIA
fonte
Alguns comentários de implementação: xé usado em dois lugares como um "ir". O empacotamento de borda é (ab) usado extensivamente, incluindo o controle que flui através do espaço entre ASEe CONTACT. O contador "3 em linha" é mantido na parte inferior da pilha; barra invertida é usada para trocar e acessar onde necessário.
TypeIA
1
Isso é qualidade antes aqui. Eu realmente gosto do que você fez com a corda no final, para permitir o ponto de entrada onde você precisava #
Cruncher
Tentei muitas coisas neste fim de semana para diminuir isso e não posso, nem por um único personagem. Mas eu não desisti! :)
TypeIA
1
Reestruturou o bloco RNG para usar apenas três ?instruções (uma das quais é atingida por dois caminhos, portanto a probabilidade ainda é exatamente 1/10) e fez alguns outros pequenos ajustes para raspar mais 7 caracteres!
TypeIA
Parabéns por ganhar!
21714 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");}

A propagação desta solução do PRNG tira proveito do fato de que os sistemas operacionais modernos alteram a localização da pilha na memória a cada execução, como uma medida básica contra explorações de quebra de pilha.

caixa de pão
fonte
Você pode se livrar da variável ccompletamente movendo a getchar()chamada em putchar()e usar alguma fantasia matemática ...
Josh
Eu acredito que você ainda precisa ter, cpara poder testar getchar()o valor contra 126, além de passá-lo para putchar().
embalagem de pão
Daí a matemática chique ... Eu acredito que putchar((getchar()-33+(rand()%10?i=0:1))%94+33))deveria funcionar. Usando sua solução como base, me reduzi a 165 caracteres.
217 Josh 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
fonte
Você poderia explicar o que é isso :3while?
Uri Agassi
@UriAgassi, na :3verdade, é o fim desta declaração: e=r>0?e-r :3que define o valor de e (número de erros sequenciais restantes antes de abortar) com base em r (1 se o último caractere processado for um erro, 0 se não). É apenas empurrado contra o tempo para economizar espaço:>
Paul Prestidge 07/02
1
E ruby ​​reconhece o whilesem espaço antes dele? Isso é tão obscuro e ilegível! ;)
Uri Agassi
2

Lote - 359

Aberto a sugestões para torná-lo completamente compatível com as regras de desafio.

Vou trabalhar para torná-lo menor / melhor - eu queria publicá-lo enquanto estiver trabalhando, antes de quebrá-lo.

@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, existem algumas maneiras de jogar golfe.

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

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

Sem golfe -

@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%
desgrudar
fonte
2

Befunge-93 (206)

Possui 142 caracteres que não são espaços em branco. Tecnicamente, não está em conformidade, pois tem probabilidade 1/9 e não 1/10 de erro.

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    %"
   >   ^^<

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

Com esta entrada !!!!aaaaaaa~~~~~~~~~~, obtemos a saída !"!!aabaaba~~~!~~~~!!indicando que os erros foram tratados corretamente.

Joel Bosveld
fonte
Obter a chance de 10% seria bastante difícil. Cada um dos seus 9 teria que se dividir em outros 2 (jogue o terceiro de volta). Em seguida, 8 dos 18 têm de caminho de volta ao começo
Cruncher
@Cruncher é semelhante à abordagem que usei no meu envio do Befunge, que tem probabilidade correta. Quatro? S são usados ​​e alguns caminhos de código retornam ao início do RNG como "nops".
TypeIA
1

PHP 190

isso é o máximo que eu poderia jogar, mas acho que é muito bom que seja menos de 100 caracteres dos principais

<? 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
fonte
1

C # - 346 330 313 309 297 288 278 274

Meio longo, mas faz o trabalho.

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");}}
user3188175
fonte
1
c=n==0?c+1:0é menor do que c+=(n==0?1:-c)...
Timwi
1
(n==1?1:0)é menor do que (n==1?n--:(--n-n))(e, em seguida, é claro alterar o mais tarde n==0a n==1)
Timwi
Muito obrigado, você quase reescreveu o programa inteiro!
user3188175
Você é incrível.
User3188175
Hum, por que o (false)? Se alguma coisa, você não quer (true)?
Timwi
1

sh bash, no 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

Um pouco melhor que 10%, uma vez que o aleatório irá gerar números entre 0 e 32767, então, na verdade, são 3.277 em 32.768 chances (10.0006%).

Obrigado, @Gilles (mas não sei o que você quer dizer com a reestruturação do tempo. Também tivemos outras idéias no chuveiro.

Não que Charles
fonte
Como você está usando os recursos do bash (então, na verdade, essa é uma solução do bash), é possível encurtar [ $RANDOM -gt 3276 ]para ((RANDOM>3276))e [ $[t++] -eq 2 ]para ((t++==2)). Eu acho que você também pode salvar alguns caracteres, reestruturando como while read -n1 a;((RANDOM>3276))&&….
Gilles 'SO- stop be evil'
@Gilles Obrigado. O que você quer dizer com essa while read...parte?
Não que Charles
Desculpe, eu truncado no lugar errado. Faça o loop while …;do :;doneou until …;do :;done, você poderá raspar alguns caracteres.
Gilles 'SO- stop be evil'
1

C, 260 257 237 225 189 174

Meu primeiro golfe, sugestões 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 é muito aleatório.

A compilação fornecerá avisos.

Obrigado pela ajuda da breadbox e Josh.

millinon
fonte
1
Sugestões iniciais: deixe de fora o #include; C aceitará (com avisos) chamadas para funções não declaradas (dentro dos limites). Use variáveis ​​globais para obter a inicialização zero automática. Encontre maneiras de usar o operador ternário em vez de if/ elseinstruções. Usar forno lugar de whileoferece mais oportunidades para reduzir o número de instruções de nível superior e omitir os colchetes ao redor do corpo do loop. Muito mais que poderia ser mencionado: examine outras soluções C neste site.
embalagem de pão
Obrigado pelas sugestões - achei que o gcc reclamaria sem pelo menos o stdio, mas aparentemente é legal. Eu também tinha uma variável boba ainda chamada 'count'. Parece que o loop for diminuiu bastante também.
millinon
Você pode declarar ne cno escopo global. Isso permitiria descartar a intdeclaração e deixar a inicialização em zero ser automática.
21714 Josh
Decidi usar co valor não inicializado de srand. Eu acho que eu poderia usar &cou &n, em vez disso, que é o breadbox usado.
millinon
Adoro o truque que você criou para eliminar a necessidade de sua segunda variável!
217 Josh Josh