Here is my solution, longer than most but pretty clean IMHO:
class Array
# Just to be different I'm going to use Stephen
# Waits' shuffle from ruby-talk archives (Dec 2005)
# instead of the usual sort_by {rand}
def shuffle
h = Hash.new
self.each { |v| h[rand(1000000000)] = v }
h.keys.sort.collect { |k| h[k] }
end
end
class String
def munge
# Only munge words longer than 3
return self unless self.length > 3
shuffled = middle = self[1..-2].scan(/./)
# Ensure it is shuffled
shuffled = shuffled.shuffle while (shuffled == middle)
self[0..0] + shuffled.join + self[-1..-1]
end
end
class Munger
def self.munge(lines)
lines.collect do |line|
line.gsub(/[A-Za-z]*/) do |word|
word.munge
end
end
end
end
if $0 == __FILE__
# Just read from STDIN
puts Munger.munge(STDIN.readlines)
end