perm filename SORT.SAI[USE,CSR] blob sn#291230 filedate 1977-07-01 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00002 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	a program to sort the ONHAND.DSK file, in lexicographic order
C00011 ENDMK
C⊗;
comment a program to sort the ONHAND.DSK file, in lexicographic order
	according to report number;
comment the program uses a simple implementation of the QUICKSORT algorithm
	(Knuth, vol III, pp 116-125);
begin "quicksort"

   require "⊂⊃" delimiters;
   define crlf=⊂'15&'12⊃, til=⊂step 1 until⊃, ff=⊂('14)⊃, bsize=⊂1000⊃, lf=⊂('12)⊃, M=⊂16⊃;

   integer i,j,L,R,K,P,stack_ptr, inchan, outchan, brchar, eof, flag, n;
   comment i and j are temporary vars, L and R are the bounds of the subset that
      we are currently sorting, P is the `middle value', which corresponds to
      the permutation value of the division between the two sets;
   integer tempint, type;
   integer bfflf, babs;
   integer array key, permute[0:bsize+1];
   comment key is the number of the report (used for sorting), permute is used
      to record eventual changes in the order of the file;

   string infile, outfile, st, temp;

   label new_step, high, low, insert_sort, finish;

   string array title[1:bsize];
   integer array stack[1:20];

   procedure push (value integer val);
	if stack_ptr>20 then print("stack overflow",crlf)
	else begin stack[stack_ptr]←val; stack_ptr←stack_ptr+1; end;

   procedure pop (reference integer val);
   begin "pop"
	stack_ptr←stack_ptr-1;
	if stack_ptr < 1 then print("stack underflow",crlf)
	else val←stack[stack_ptr]; end "pop";
	
   setbreak(bfflf←getbreak,ff&lf,null,"IA");
   setbreak(babs←getbreak,"|",null,"IS");

   comment first, read in the file of titles, and initialize the appte arrays;
   open(inchan←getchan,"DSK",0,2,0,450,brchar,eof);
   open(outchan←getchan,"DSK",0,0,2,0,0,eof);
   stack_ptr←1;

   for i←1 til bsize do permute[i]←i;
   do begin 
	print("input file?"); infile←inchwl; lookup(inchan,infile,flag)
   end until ¬flag;
   do begin
	print("output file?"); outfile←inchwl; enter(outchan,outfile,flag)
   end until ¬flag;

   i←1;
   while true do begin
	do temp ← st←input(inchan,bfflf) until lop(st)="*" or eof;
	if eof then done;
	comment type is used to group the reports according to project;
 	type ← if st="A" then 0 else if st="C" then 2000 else 4000;
	key[i] ← intscan(st,brchar) + type;
	if equ(st[2 to 5],"SAME") then title[i-1]←title[i-1]&temp
	else begin title[i]←temp; i←i+1; end;
   end;
   n ← i-1;
   print("number of reports=",n,crlf);

   comment use dummy keys K[0]=-∞, K[n+1]←+∞;
   key[0]←-1;  key[n+1]←10000;
  
   L←1; R←N;
   
   comment when we have decided which subset to sort, and set L and R, we start here;
new_step: if R-L < M then goto insert_sort;

   i←L;  j←R;  K←key[permute[L]];  P←permute[L];
   comment P will be the record at the division between the sets;
   
high: while key[permute[j]]>K do j←j-1;

   if j ≤ i then begin
      permute[i]←P; goto finish; end;
   comment exchange the two records, and continue, coming up from the low end;
   permute[i] ← permute[j];
   i←i+1;

low: while key[permute[i]]<K do i←i+1;

   if j ≤ i then begin permute[j]←P; i←j; end
   else begin permute[j]←permute[i]; j←j-1; goto high; end;
   comment exchange, and come from the high end;

finish:
   comment we've partitioned the subfile from L to R into three parts.
   	Push the largest onto the stack, for later sorting, and sort the
	smaller one;
   if R=i then R←i-1 else if L=i then L←i+1 else
   if R-i > i-L then begin
      push(i+1); push(R); R←i-1;
   end else begin
      push(L); push (i-1); L←i+1; 
   end;

goto new_step;

insert_sort:
comment when the subset we're sorting gets small enough (arbitrarily set at 16),
	we come here, and finish with a simple insertion sort;
   for j←L+1 til R do begin
      K←key[permute[j]]; P←permute[j]; i←j-1;
      while key[permute[i]]>K ∧ i≥L do begin
	 permute[i+1]←permute[i]; i←i-1; end;
      permute[i+1]←P;
   end;

comment now pop the stack, to get one of the pairs that we have previously stored;
if stack_ptr > 1 then begin
   pop(R); pop(L); goto new_step;
end;

comment the keys and permutations are now sorted. Now print out the list,
	in sorted order;
for i←1 til n do begin
	out(outchan,title[permute[i]]);
	if i mod 55 = 54 then out(outchan,ff);
end;

close(outchan);
end "quicksort";