Begin forwarded message: > From: "btbeal" <btbeal / swbell.net> > Date: April 22, 2006 5:00:23 PM CDT > To: <submission / rubyquiz.com> > Subject: Please Forward: Ruby Quiz Submission > > Hello, > > This is my first submission to Ruby Quiz. I wrote up a little > explanation > of how the program works, which you can use or not, as you wish. I > didn't > include a data file to keep it short. Hopefully the tabs will > expand again > when you copy the code into a text editor. > > - Robert Beal (Austin, TX) > > > ------------------------------------------------------------ > Program Explanation (Quiz 76--Text Munging) > > The heart of the program is the function "create_random_permutation". > It creates an array of the numbers 0...length and a second, empty > array. > Then it deletes a number randomly from the first array and appends > the number > to the second array. Afterwards, the second array is returned. > The optional > arguments allow one to shift the range of numbers stored in the > array, and to > shift the indices where the range is stored. > > The second function, "permute_word", first copies its string argument > in order to have a target to copy the permuted letters to. Next > the word > length is calculated; words of 3 letters or less won't change. > Otherwise, > 2 is subtracted from the word's length (to omit the first and last > letters) > and a permutation is calculated in the range (1...length-1). The > letters are > copied from the original to the copy using the permuted values as > subscripts into the target string. Finally, the copy is returned. > > The last function, "munge", reads in a file, munges it, and writes the > results back out to another file. The file is read in as one giant > string, > and two indexes into the string are created. Index #1 points at > the first > letter of a word, and Index #2 points at the first letter past that > word. > Each is moved forward in alternating turns until they bracket a > word, the word > is munged in place, and the process repeats until both indexes wind > up at the > end of the string. > > ------------------------------------------------------------- > The Program (Quiz 76--Text Munging) > > > # Return a permutation of the values (0...length) in an array. > # If "offset" is given, return [offset,...,length+offset]. > # If "pad" is given, return [nil,...,nil, <rest of perm>]. > # If offset == pad, you can index into the array with the > # same set of values that you get out of it. > def create_random_permutation(length, offset=0, pad=offset) > a = Array.new(length) {|i| i + offset} > b = Array.new(pad, nil) > (length - 1).downto(0) {|i| b.push(a.delete_at(rand(i + 1)))} > b > end > alias crp create_random_permutation > > # Given a string, permute the characters in the interior of (a copy > of) the string > # (i.e. leave the first and last characters alone) and return the > result. > def permute_word(word) > word2 = word.clone > if word.length > 3 > p = crp(word.length - 2, 1) > 1.upto(word.length - 2) {|i| word2[p[i]] = word[i]} > end > word2 > end > > # The main program. > # Read a text file, munge all words, and write out the result. > # "Munging" means to permute all the interior letters of a word. > # The first and last letters in the word and all other characters > # (punctuation, blanks, etc.) in the string are left where they are. > # A simple filename (no path, no extension) is the argument; > # the file is assumed to be in the current directory, the input > # extension is .txt, and the output extension is .out. > def munge(name) > infile = name + ".txt" > outfile = name + ".out" > line = File.open(infile) {|f| f.read} > #i1 points at the first character in a word. > #i2 points at the first character after a word. > i1 = i2 = 0; > while i1 < line.length || i2 < line.length > i2 += 1 while i2 < line.length && line[i2, 1] =~ /[[:alpha:]]/ > #in a word > line[i1...i2] = permute_word(line[i1...i2]) > i1 = i2 > i1 += 1 while i1 < line.length && line[i1, 1] !~ /[[:alpha:]]/ > #not in a word > i2 = i1 > end > File.open(outfile, "w") {|f| f.write(line)} > # line > end > > ---------------end-------------------------------- >