Forum: Ruby Re: [SOLUTION] Text Munger #76

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Gordon Thiesfeld (Guest)
on 2006-04-23 18:44
(Received via mailing list)
Here is my solution:

class String

  def munge
    split(/\b/).munge_each.join
  end

end

class Array

  def munge_each
    map { |word| word.split(//).munge_word }
  end

  def munge_word
    first,last,middle = shift, pop,scramble
    "#{first}#{middle}#{last}"
  end

  def scramble
    sort_by{rand}
  end

end

if __FILE__ == $PROGRAM_NAME

  begin
    puts File.open(ARGV[0], 'r').read.munge
  rescue
    puts "Usage:  text_munge.rb file"
  end

end
Ryan Leavengood (Guest)
on 2006-04-23 19:00
(Received via mailing list)
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
This topic is locked and can not be replied to.