permute the lines of a program, a lost art
K. A. Dahlke
eklhad at ihnet.UUCP
Fri Jul 20 08:16:34 AEST 1984
/* shuffle.c: shuffle the lines of a computer program */
/* This program brings back a bit of nostalgia.
* Remember the days of punch-cards? No editors. no interactive setions.
* Wasn't it fun writing a 1,900 line program, and dropping the box of cards
* on the way to the computing center?
* The wind blew your cards all over the campus.
* You then had the pleasure of collecting and sorting them
* before the project was due.
* This aspect of computer science must not be forgotten in the wake
* of ever advancing technology.
* This program can help!!!
* It will randomly permute the lines of a file for you.
*
* cc -s -O -o shuffle shuffle.c
* shuffle file
*
* Your file can be in any language (even assembly).
* We can even extend the concept, try it on a document.
*
* Unfortunately, this program cannot recapture the excitement of collecting
* the cards as they fly in the wind.
* Perhaps a later release will leave each line in a separate
* file, scattered throughout the UNIX directory structure.
* Until then, you can still enjoy sorting your programs.
* Enjoy!!!
*/
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
extern char *malloc();
int fd; /* file descriptor */
off_t flen; /* file length */
char *fstart; /* start of file in memory */
char *fend;
char **lptrs; /* pointers to lines */
char **eptrs;
int nlines;
struct stat filstat;
main(argc, argv)
char **argv;
{
register char *s;
register i;
if(argc!=2){
fprintf(stderr,"usage: shuffle file\n");
exit(1);
}
fd=open(argv[1],O_RDWR);
if(fd<0){
fprintf(stderr,"cannot access %s\n",argv[1]);
exit(1);
}
fstat(fd,&filstat);
if((filstat.st_mode&S_IFMT)!=S_IFREG){
fprintf(stderr,"%s is not a regular file\n",argv[1]);
exit(1);
}
flen=filstat.st_size;
if(!flen) exit(0);
fstart=malloc(flen);
if(!fstart){
fprintf(stderr,"cannot allocate enough memory\n");
exit(1);
}
fend=fstart+flen;
/* read file */
if(read(fd,fstart,flen)<flen){
fprintf(stderr,"bad read on file %s\n",argv[1]);
exit(1);
}
/* count lines */
for(i=0,s=fstart;s<fend;++s)
if(*s=='\n') ++i;
nlines=i;
if(nlines>32767){
fprintf(stderr,"too many lines in file %s\n",argv[1]);
exit(1);
}
if(nlines<2) exit(0);
/* partial line (at EOF) will not be shuffled */
lptrs=(char **)malloc(2*nlines*sizeof(char*));
if(!lptrs){
fprintf(stderr,"cannot allocate enough memory\n");
exit(1);
}
eptrs=lptrs+nlines;
/* set pointers to the beginning and end of each line */
for(s=fstart,i=0;i<nlines;++i){
lptrs[i]=s;
while(*s++!='\n') ;
eptrs[i]=s;
}
shuffle();
}
shuffle(){
register i,j;
extern long time();
srand(time()&32767);
lseek(fd,0,0);
for(i=nlines;i>0;--i){
j=(rand()*i)>>15;
write(fd,lptrs[j],eptrs[j]-lptrs[j]);
lptrs[j]=lptrs[i-1];
eptrs[j]=eptrs[i-1];
}
}
--
Karl Dahlke ihnp4!ihnet!eklhad
More information about the Comp.sources.unix
mailing list