Begin forwarded message: > From: Gregory Seidman <Gregory_Seidman / alumni.brown.edu> > Date: April 21, 2006 9:24:49 AM CDT > To: Ruby Quiz <james / grayproductions.net> > Subject: Re: [QUIZ] Text Munger (#76) > > Note that this was sent directly to you, not to the list as a > whole. I was > going for development speed, so waiting until Sunday to submit a > solution > would be... frustrating. Anyhow... > > On Fri, Apr 21, 2006 at 09:34:35PM +0900, Ruby Quiz wrote: > [...] > } -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- > =-=-=-=-=-=-=-= > } by Matthew Moss > [...] > } Your task for this quiz, then, is to take a text as input and > output the text in > } this fashion. Scramble each word's center (leaving the first and > last letters of > } each word intact). Whitespace, punctuation, numbers -- anything > that isn't a > } word -- should also remain unchanged. > > There are a few interesting things about this script: > > - It isn't bothering to rearrange any word that is less than four > letters. > > - It treats capital letters at the beginning of a word, even if > they occur > in the middle of a word. This has two effects. First, acronyms > and other > words in all-caps are not rearranged at all. Words in all-caps don't > register the same when we read them, and rearranging their > letters is > much more disruptive. A word like MacDonald, however, would be > rearranged > as two separate words. The capital letters act as anchors, much > in the > same way that the first and last letters of words do, and cannot be > moved. For example, MacDonald could be rendered MacDonlad and > still be > readable, but MlacdnDao would not be. > > - It isn't bothering to compact or flatten anything before joining. > I do > need a flatten after the scan to get individual tokens instead of an > array of arrays, but I leave in all the nils and just ignore them > as if > they were whitespace or punctuation. They disappear in the join > anyway, > so it doesn't matter. > > - Also, the replacement for actual words is an array of three > elements: a > single-character string, an array of single-character strings, and > another single-character string. The join takes care of that, too. > > The script: > > #!/usr/bin/env ruby > > if /^(-[?])|(-h)|(-help)|(--help)$/ =~ ARGV[0] || ARGV.length > 1 > $stderr.puts "Usage: #{$PROGRAM_NAME} [filename]" > exit 1 > end > > infile = $stdin > if ARGV.length == 1 > infile = File.new(ARGV[0]) rescue begin > $stderr.puts("File not found: '#{ARGV[0]}'") > exit 2 > end > end > > tok_exp = /([a-zA-Z][a-z]*)|([^A-Za-z]+)/ > word_exp = /[a-zA-Z][a-z]{3,}/ > > infile.each_line { |line| puts line.scan(tok_exp).flatten!.map! { | > tok| > if word_exp =~ tok > newtok = [tok[0..0]] > newtok << tok[1...-1].split('').sort_by{rand} > newtok << tok[-1..-1] > else > tok > end > }.join > } >