Skip to main content
8 of 18
Improved my answer.
user avatar
user avatar

C, 623 673 707 bytes

Source code:

j,c,p[256][256]={0},r;char X[999]="j,c,p[256][256]={0},r;char X[999]=\"@\";main(){char*a=X,*b=X,*Y=X+315,*y;for(y=Y;*a!=64;)*y++=*a++;for(;*b;*y++=*b++)if(*b==34)*y++=92;for(a++;*a;)*y++=*a++;*y=0;for(a=Y;*a;a++)p[*a][*(a+1)]++;c=*Y;do{putchar(c);for(r=j=0;j<256;j++)r+=p[c][j];r=rand()%r;for(j=0;j<256;j++){r-=p[c][j];if(r<0)break;}c=j;}while(c);}";main(){char*a=X,*b=X,*Y=X+315,*y;for(y=Y;*a!=64;)*y++=*a++;for(;*b;*y++=*b++)if(*b==34)*y++=92;for(a++;*a;)*y++=*a++;*y=0;for(a=Y;*a;a++)p[*a][*(a+1)]++;c=*Y;do{putchar(c);for(r=j=0;j<256;j++)r+=p[c][j];r=rand()%r;for(j=0;j<256;j++){r-=p[c][j];if(r<0)break;}c=j;}while(c);}

With newlines and whitespace added for legibility:

01  j,c,p[256][256]={0},r;
02  char X[999]="j,c,p[256][256]={0},r;char X[999]=\"@\";main(){char*a=X,*b=X,*Y=X+315,*y;for(y=Y;*a!=64;)*y++=*a++;for(;*b;*y++=*b++)if(*b==34)*y++=92;for(a++;*a;)*y++=*a++;*y=0;for(a=Y;*a;a++)p[*a][*(a+1)]++;c=*Y;do{putchar(c);for(r=j=0;j<256;j++)r+=p[c][j];r=rand()%r;for(j=0;j<256;j++){r-=p[c][j];if(r<0)break;}c=j;}while(c);}";
03  main(){
04      char*a=X,*b=X,*Y=X+315,*y;
05      for(y=Y;*a!=64;)*y++=*a++;
06      for(;*b;*y++=*b++)if(*b==34)*y++=92;
07      for(a++;*a;)*y++=*a++;*y=0;
08      for(a=Y;*a;a++)p[*a][*(a+1)]++;
09      c=*Y;
10      do{ putchar(c);
11          for(r=j=0;j<256;j++)r+=p[c][j];
12          r=rand()%r;
13          for(j=0;j<256;j++){
14              r-=p[c][j];
15              if(r<0)break;
16          } c=j;
17      }while(c);
18  }

The variable p[][] will contain the occurrences of each character following another. X contains the entire source, with '@' substituted for the value of X, in quotes. The buffer Y will point start at X[315], one character past the end of the initial string, and will use up 624 bytes. (315 + 624 < 999.)

The for-loops on lines 05, 06, and 07 replace the '@' in X with the content of X, escaping double quotes, and stores it in Y.

Line 08 tallies the occurrences of one character following another. And line 09 starts the Markov model at the first character of the program ('j').

The do/while loop from 10 to 17 first outputs the current state of the Markov model, then finds the next state using a random number within the range of all successive occurrences.

Sample output:

j<256;r(;)*Y=0}";j;}whilea=Y;a++31)r;a++=92;dor(a++1564;f(*b=X+;)*b=Y=j+;j;char(r=";*Y=0;*a+;for*a;*a;}chifor*a++)]++156;)]=0)%r(ak;j;j]++){0}c);}whar<0},cha=p[c]=X,*y;}";}c][j<256][j<256;*aifo{c)%r(chin(r X,r=r*b++++=j][*br+=0;forak;*b=X++=0;*Y;for(y={r X[*y;*a;for(;for*y+315,r X,cha+;j=0},*Y;);for(a=0;r++;*y=0}c][*ar=0;}

Edit: Cut down 34 bytes to go from 707 to 673 bytes.

Edit: Cut down 50 bytes to go from 673 to 623 bytes.

user61383