/*
 * Random
 * by K.Veijalainen <veijalai@cc.lut.fi>
 * 
 * Reads in lines from stdin, scrambles their order and then outputs them.
 */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define VERSION "v1.0"

#define DEFAULT_BUFFER_SIZE 8192

struct line_s {
	struct line_s *next;
	unsigned char *text;
};
struct line_s *firstline=NULL;


int main(int argc, char **argv) {
	unsigned char *buffer,*tb;
	struct line_s *curline=NULL;
	char *mark;
	int n=0,l,r,x,len=DEFAULT_BUFFER_SIZE,prevpos=0,pos=0;

	buffer=malloc(DEFAULT_BUFFER_SIZE);
	
	srandom((unsigned int)time(NULL));
	
	/* Read everything */
	while(!(feof(stdin))) {
		/* Malloc space for new line entry.*/
		*(buffer+pos)=getchar();
		/* If we ran out of space, make the buffer larger.*/
		if((pos-prevpos)>=(len-2)) {
			tb=realloc(buffer,2*len);
			len*=2;
			buffer=tb;
		}
		  
		/* Another line read */
		if(*(buffer+pos)==10) {
			if(n==0) 
			  firstline=curline=malloc(sizeof(struct line_s));
			else {
				curline->next=malloc(sizeof(struct line_s));
				curline=curline->next;
			}
			curline->next=NULL;
			/* Malloc space for a string and copy it there.*/		
			curline->text=malloc(pos-prevpos+2);
			strcpy(curline->text,buffer+prevpos);
			/* Inc line count */
			++n;
			/* Mark beginning of new blah.*/
			prevpos=pos+1;
		}
		/* Move to next char */
		++pos;
	}
	
	/* This is for on/off "marks" that are used later.*/
	mark=calloc(n,1);
	
	/* Output lines in random order.*/
	r=random()%n;
	for(l=0;l<n;l++) {
		/* Select random line that is not yet printed.*/
		while(*(mark+r))
		  r=random()%n;
		*(mark+r)=1;
		/* Seek the line data from the linked list.*/
		curline=firstline;
		for(x=0;x!=r;x++)
		  curline=curline->next;
		/* Duubadsadsadas!*/
		printf("%s",curline->text);
	}
	
	exit(0);
}
