! anaguniv V0.0
! Sort letters within a word
!
%external %predicate Exists(%string (255) File, %integer %name len)
  %constant %integer os length index = 2
  %record %format osfile array fm (%integer %array element (0:3))
  %record (osfile array fm) osfile array
  %record %format Time stamp fm (%integer low, high)
  %record (time stamp fm) time stamp
  %external %integer %fn %spec Get file information(%c
    %record (osfile array fm) %name osfile array, 
    %record (time stamp fm) %name time stamp,
    %string (255) file name)

  %integer success = Get file information(osfile array,
                                          time stamp,
                                          File)
  %false %if success # 1
  len = osfile array_element(os length index)
  %true
%end

%external %routine loadup(%string (255) file name,
                          %integer address, actual length, max length)
  %external %routine %spec  X Load File (%string (255) file name,
                                         %integer      buffer size,
                                         %integer      address)
  %if max length < actual length %then %start
    print string("File ".file name." of ".itos(actual length,0). %c
                 " bytes is too big for buffer of ". %c
                 itos(max length,0)." bytes".nl)
    %stop
  %finish
  X Load file(file name, max length, address)
%end

%external %routine writeout(%string (255) file name, %integer address, len)
%external %integer %fn %spec Save File (%integer straddr,strlen,
                                     %integer     buffer size,
                                                  address)
%integer cc
  cc = Save file(ADDR(file name)+1, LENGTH(file name), len, address)
  %if cc < 0 %then printstring ("Failed to write out file ".file name.nl) %c
    %and %stop
%end

%external %routine Readword(%byte %array %name c, %integername len)
%byte ch
len = 0
%cycle
  readsymbol(ch) %until 'A'<=ch<='Z' %or 'a'<=ch<='z' %or ch=NL
  c(len)=ch
  %exit %if ch=NL
  len=len+1
%repeat
%end
  

%begin
%constant %integer max dict = 120 000*2

%byte %array dict(0:max dict)
%integer step factor, word length, word index, i

%const %string (*) anagram dict dir = "adfs::0.$.words.longanag."
%string (255) file name
%integer dict length
%byte %array target(0:63)

  %predicate Anagram Found(%c
   %integer subdict beg, subdict end, %integer %name splitp)
  %integer i, word ptr
    %cycle
      %if subdict beg > subdict end %then %false
      splitp=(((subdict end-subdict beg)//step factor)//2)*step factor %c
             +subdict beg
      splitp=splitp+(step factor-(REM(splitp-subdict beg,step factor))) %c
             -step factor

!printstring("beg = ".itos(subdict beg,0).nl)
!printstring("splitp = ".itos(splitp,0).nl)
!printstring("end = ".itos(subdict end,0).nl)

      %if splitp>subdict end %or splitp<subdict beg %then %false

!printstring("checking against ")
!%for i = 0,1,step factor-1 %cycle
!printsymbol(dict(splitp+i))
!%repeat
!newline

      %for i = 0,1,word length-1 %cycle
        %if dict(splitp+i)>target(i) %then %start
          subdict end = splitp-step factor; ->continue2
        %finish
        %if dict(splitp+i)<target(i) %then %start
          subdict beg = splitp+step factor; ->continue2
        %finish
      %repeat
      %true
continue2:
    %repeat
  %end

%routine hquicksort(%integer a, b)
%integer l,r
%byte dump
  %return %if a>=b
  l=a;r=b; dump=target(b)
  %while l<r %cycle
    %while l<r %cycle
      %if target(l)>dump %then target(r)=target(l) %and r=r-1 %and %exit
      l=l+1
    %repeat
    %while l<r %cycle
      %if target(r)<dump %then target(l)=target(r) %and l=l+1 %and %exit
      r=r-1
    %repeat
  %repeat
  target(l)=dump
  hquicksort(a,l-1)
  hquicksort(r+1,b)
%end

%const %integer true=0,false=1
%byteinteger match
%integer last word length = -1, start index

%for word length = 33,-1,2 %cycle
  step factor = (word length+1)*2 { 1 is for NL }
  file name = anagram dict dir.itos(word length,0)
  %if exists(file name, dict length) %start
    printstring("Looking in ".file name.nl)
    loadup(file name, ADDR(dict(0)), dict length, max dict)
    %if REM(dict length, step factor) # 0 %start
      Printstring("??? Summat up - dict length = ".itos(dict length,0).nl)
    %finish
    ! Find and print all anagrams
word index = 0
%cycle
!------------------------------
      newline
      %cycle
        -> end %if word index>dict length
        match=true
        ! Check at word index
        %for i=0,1,word length-1 %cycle
          %if dict(word index+i)#dict(wordindex+i+step factor) %c
            %then match=false
        %repeat
        %exit %if match=true
        word index=word index+step factor
      %repeat
      start index = word index
      ! First pair found

      %cycle
        %if dict(word index+wordlength+1)=16_80 %then -> end {ARGH!!!}
        %for i=word length+1,1,step factor-2 %cycle
          printsymbol(dict(word index+i))
        %repeat
        space
        match=true
        word index=word index+step factor
        -> end %if word index>dict length
        ! Check again
        %for i=0,1,word length-1 %cycle
          %if dict(word index+i)#dict(start index+i) %then match=false
        %repeat
      %repeat %until match=false
!----------------------------
%repeat
  %finish
end:
%repeat
%endofprogram
