Re: Project Programmer Wanter
- Posted by CChris <christian.cuvier at agricultur?.go?v.fr> Feb 12, 2008
- 938 views
CChris wrote: > > Ret Law wrote: > > > > That sounds good. > > > > Basically what I want is to create output, both as a data text file and as > > screen > > display of the full permutation of a given number of items over a given > > number > > of digits according to a given rule of sucession. > > > > For example: > > > > Items: > > A,B,C,D > > > > # of Digits: > > 3 > > > > Order: > > A,B,C,D, beginning with AAA, ending with DDD and rotating in successive > > order > > across right to left. > > > > Output: > > AAA > > AAB > > AAC > > AAD > > ABA > > ABB > > ABC > > ABD > > ACA > > ACB > > ACC > > ACD > > BAA > > BAB > > BAC > > BAD > > BBA > > BBB > > BBC > > BBD > > BCA > > BCB > > BCC > > BCD > > BDA > > BDB > > BDC > > BDD > > CAA > > CAB > > CAC > > CAD > > CBA > > CBB > > CBC > > CBD > > CCA > > CCB > > CCC > > CCD > > CDA > > CDB > > CDC > > CDD > > DAA > > DAB > > DAC > > DAD > > DBA > > DBB > > DBC > > DBD > > DCA > > DCB > > DCC > > DCD > > DDA > > DDB > > DDC > > DDD > > > > How would that function be implemented to achieve that? > Here is a modified implementation that doesn't keep the whole data in memory, writes both item and symmetric item. It assumes the objects whose arrangements are to be written are byte sized:
function update_counter( sequence counter, -- counter sequence to increment integer start_val, -- usually 1 integer end_val, -- usually len integer len) -- counter assumed length -- increments len counters right to left, returns {} if done or -- new counter & rank of first value changed. if not length(counter) then -- main function will make this call at startup -- create initial value of counter return repeat(start_val,len) & len elsif length(counter)!=len+1 then return 0 -- shouldn't happen end if -- assert: start_val <= end_val for i=len to 1 by -1 do -- all counters have same length, len+1 if counter[i] < end_val then counter[i]+=1 counter[$]=i -- rank of first value changed return counter else counter[i] = start_val end if end for return {} -- the end, or len<=0 end function global procedure enumerate( sequence succession, -- list of objects to appear in order integer n, -- number of digits sequence outfile) -- output file name -- WARNING: no check is made for available space on the medium you write to. -- Writing a file that's too big may result in data loss or physical damage -- to medium. -- AUTHOR WILL DECLINE ANY CLAIM FOR LIABILITY. sequence counter,rev_item,item integer ls,fh ls=length(succession) counter=update_counter("",1,ls,n) item=repeat(0,n) rev_item=repeat(0,n) fh=open(outfile,"wb") if fh=-1 then puts(2,"Could not open output file - bailing out") return end if -- The first byte in the output file is the length of each item. -- Remove the next statement if it will always be 4, for instance puts(fh,n) while compare(counter,{})=1 do for i=counter[$] to n do item[i]=succession[counter[i]] rev_item[i]=succession[$+1-counter[i]] end for puts(fh,item) puts(fh,rev_item) counter=update_counter(counter,1,ls,n) end while close(fh) end procedure global procedure display_output(sequence infile) -- reads what enumerate() has written integer fh,n sequence item,rev_item fh=open(infile,"rb") if fh=-1 then puts(2,"Couldn't locate input file - bailing out.") return end if -- replace next statement with a fixed assignment like n=4 if you removed -- the puts(fh,n) statement in enumerate(). n=getc(fh) -- record length while 1 do item=get_bytes(fh,n) if not length(item) then-- normal termination exit elsif length(item)<n then puts(2,"Input file doesn't hold properly matched strings - halting.") exit end if rev_item=get_bytes(fh,n) if length(rev_item)<n then puts(2,"Input file doesn't hold properly matched strings - halting.") exit end if -- change this statement in order to meet your display requirements printf(1,"%s %s\n",{item,rev_item}) end while close(fh) end procedure
CChris