# Unreliable data stream

Your challenge is to golf a program that mimics a data transmission stream. Your program should read input from stdin and output it directly to stdout. To make the problem more interesting, the output stream is 'faulty', and must meet several requirements:

1. There should be a 10% chance that each character is shifted +1 ascii code (ex 'a' becomes 'b', '9' becomes ':'), etc.
2. The input and output should only cover printable ascii values ('!' through '~', decimal 33 through decimal 126, inclusive). If the random +1 occurs on a '~' (decimal 126), a '!' (decimal 33) should be output instead.
3. If three characters are randomly shifted in a row, the program should output "ERROR CODE 4625: UNRECOVERABLE ERROR, PLEASE CONTACT YOUR SYSTEM ADMINISTRATOR" (trailing newline optional) and halt execution.

To simplify the problem, here are a few other criteria:

1. You can assume the input will always be valid; that is, it will only contain values '!' through '~'.
2. The program should continue on until three characters are randomly shifted in a row; it's safe to assume that EOF will never occur.
3. The randomness must differ across runs; if your random number generator needs to be seeded to get an unique result each run, then your code needs to seed it.
4. You must write a program, not a function.
5. You must take input from stdin and write output to stdout.
6. You may not use any external libraries or resources.
7. Your code must have a freely available and working intrepreter or compiler.

Standard code-golf rules apply. Winner is whoever has the shortest program posted two weeks from now (Thursday, Feb 20th, 2014).

• Is it OK to assume that there will be an EOF? In particular, can I read all the input into memory before producing any output, like GolfScript normally does? – Ilmari Karonen Feb 7 '14 at 18:21
• @IlmariKaronen probably not; it wouldn't be possible to guarantee enough input for your RNG to make 3 consecutive errors. – TypeIA Feb 7 '14 at 18:28
• @IlmariKaronen as per the specs, EOF will never occur. The only exit condition is three characters flipping in a row. – Josh Feb 7 '14 at 18:56

# Befunge-98, 166159156155 148

This one improves on the other excellent Befunge answer with the correct probability (1/10) and is slightly more compact:

~>?#v?1+\1>+\:'~1+-4k#x07_$'!>,:3-!#v_ >#?>>>\$\0^>
^<<
A"##  "CT YOUR SYSTEM ADMINISTRATOR"<@,kM'"ERROR CODE 4625: UNRECOVERABLE ERROR, PLEASE CONT
• Some implementation comments: x is used in two places as a "goto." Edge wrapping is (ab)used extensively, including control flowing through the space gap between ASE and CONTACT. The "3-in-a-row" counter is kept at the bottom of the stack; backslash is used to swap to and access it where needed. – TypeIA Feb 7 '14 at 17:55
• This is quality befunge right here. I really like what you did with the string at the end, to allow the entry point where you needed it – Cruncher Feb 7 '14 at 18:40
• I tried a lot of things this weekend to whittle this down and I can't, even by a single character. But I haven't given up! :) – TypeIA Feb 10 '14 at 23:21
• Restructured the RNG block to use only three ? instructions (one of which is hit by two paths, so the probability is still exactly 1/10) and made some other minor tweaks to shave off 7 more chars! – TypeIA Feb 11 '14 at 15:43
• Congrats on winning! – Josh Feb 21 '14 at 14:05

## C, 168 characters

i;main(c){for(srand(&c);i++<3;putchar(rand()%10?i=0,c:c-126?c+1:33))c=getchar();

This solution's seeding of the PRNG takes advantage of the fact that modern OSes change the stack's location in memory on each run, as a basic measure against stack-smashing exploits.

• You can get rid of the variable c completely by moving the getchar() call into putchar() and using some fancy math... – Josh Feb 7 '14 at 17:39
• I believe you still need to have c so you can test getchar()'s value against 126 in addition to passing it to putchar(). – breadbox Feb 7 '14 at 18:13
• Hence the fancy math...I believe putchar((getchar()-33+(rand()%10?i=0:1))%94+33)) should work. Using your solution as a base, it gets me down to 165 characters. – Josh Feb 7 '14 at 18:38

## 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'
• Could you explain what is that :3while? – Uri Agassi Feb 7 '14 at 7:40
• @UriAgassi the :3 is actually the end of this statement: e=r>0?e-r :3 which sets the value of e (number of sequential errors remaining before we abort) based on r (1 if the last character processed was an error, 0 if not). It's just pushed up against the while to save space :> – Paul Prestidge Feb 7 '14 at 11:32
• And ruby recognizes the while without a space before it? That is so obscure and unreadable! ;) – Uri Agassi Feb 7 '14 at 15:21

## Batch - 359

Open to suggestions to make it completely compliant to the challenge rules.

I will work on making it smaller / better - I wanted to post it while it's working, before I break it.

@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%

There are definitely quite a few ways to golf it down.

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

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

Un-golfed -

@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%

# Befunge-93 (206)

It has 142 non-whitespace characters. Technically it is non-conforming, as it has probability 1/9 not 1/10 to 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 %" > ^^< Run as cat /dev/urandom | tr -dc '!-~' | ./befungee.py -c 100 ../rand. With this input !!!!aaaaaaa~~~~~~~~~~ we get the output !"!!aabaaba~~~!~~~~!! indicating that the errors are correctly handled. • To get the 10% chance would be rather difficult. Each of your 9 would have to split into another 2(throw the third one back). Then 8 of the 18 have to path back to the beginning – Cruncher Feb 7 '14 at 18:17 • @Cruncher that's similar to the approach I used in my Befunge submission, which has correct probability. Four ?s are used and some code paths feed back to the beginning of the RNG as "nops." – TypeIA Feb 7 '14 at 18:34 ## PHP 190 that's the further i could golf it, but i think it's pretty good that it is less than 100 chars from the leading <? 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;} # C# - 346330313309297288278 274 Kinda long but does the job. 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");}} • c=n==0?c+1:0 is shorter than c+=(n==0?1:-c)... – Timwi Feb 7 '14 at 17:16 • (n==1?1:0) is shorter than (n==1?n--:(--n-n)) (and then of course change the later n==0 to n==1) – Timwi Feb 7 '14 at 17:18 • Thanks a lot, you've nearly rewritten the entire program! – user3188175 Feb 7 '14 at 17:28 • You're amazing. – user3188175 Feb 7 '14 at 17:29 • Hm, why the (false)? If anything, don’t you want (true)? – Timwi Feb 7 '14 at 17:34 ## sh bash, on 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 Slightly better than 10% since random will generate numbers between 0 and 32767, so really it's 3,277 in 32,768 odds (10.0006%). Thanks, @Gilles (but not sure what you mean about the while restructure. had some other ideas in the shower, too. • Since you're using bash features (so this is a bash solution, really), you can shorten [$RANDOM -gt 3276 ] to ((RANDOM>3276)) and [ \$[t++] -eq 2 ] to ((t++==2)). I think you can also save a few characters by restructuring as while read -n1 a;((RANDOM>3276))&&…. – Gilles 'SO- stop being evil' Feb 7 '14 at 11:42
• @Gilles Thanks. What do you mean about the while read... part? – Not that Charles Feb 7 '14 at 14:51
• Sorry, I truncated in the wrong place. Make the loop while …;do :;done or until …;do :;done, you should be able to shave a few characters. – Gilles 'SO- stop being evil' Feb 7 '14 at 14:56

# C, 260257237225189 174

My first golf, suggestions appreciated.