############################################################################ # # Name: collate.icn # # Title: Collate and decollate strings # # Author: Ralph E. Griswold # # Date: June 10, 1988 # ############################################################################ # # These procedures collate (interleave) respective characters of # two strings and decollate such strings by selecting every other # character of a string. produce a string consisting of inter- # leaved characters of s1 and s2. # # collate(s1,s2) collate the characters of s1 and s2. For # example, # # collate("abc","def") # # produces "adbecf". # # decollate(s,i) produce a string consisting of every other # character of s. If i is odd, the odd-numbered # characters are selected, while if i is even, # the even-numbered characters are selected. # ############################################################################ procedure collate(s1,s2) local length, ltemp, rtemp static llabels, rlabels, clabels, blabels, half initial { llabels := "ab" rlabels := "cd" blabels := llabels || rlabels clabels := "acbd" half := 2 ltemp := left(&cset,*&cset / 2) rtemp := right(&cset,*&cset / 2) clabels := collate(ltemp,rtemp) llabels := ltemp rlabels := rtemp blabels := string(&cset) half := *llabels } length := *s1 if length <= half then return map(left(clabels,2 * length),left(llabels,length) || left(rlabels,length),s1 || s2) else return map(clabels,blabels,left(s1,half) || left(s2,half)) || collate(right(s1,length - half),right(s2,length - half)) end # decollate s according to even or odd i # procedure decollate(s,i) static dsize, image, object local ssize initial { image := collate(left(&cset,*&cset / 2),left(&cset,*&cset / 2)) object := left(&cset,*&cset / 2) dsize := *image } i %:= 2 ssize := *s if ssize + i <= dsize then return map(object[1+:(ssize + i) / 2],image[(i + 1)+:ssize],s) else return map(object[1+:(dsize - 2) / 2],image[(i + 1)+:dsize - 2], s[1+:(dsize - 2)]) || decollate(s[dsize - 1:0],i) end