# Re: \[SOLUTION\] Text Munger #76

**URL:** <https://www.ruby-forum.com/t/re-solution-text-munger-76/58589>\
**Category:** Ruby\
**Created:** [April 23, 2006, 6:44pm UTC](https://www.ruby-forum.com/t/re-solution-text-munger-76/58589 "2006-04-23T18:44:56Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![gordon321](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/d2c977/32.png) [@gordon321](https://www.ruby-forum.com/u/gordon321)\
**Post date:** [April 23, 2006, 6:44pm UTC](https://www.ruby-forum.com/t/re-solution-text-munger-76/58589/1 "2006-04-23T18:44:56Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![gordon321](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/d2c977/32.png) [@gordon321](https://www.ruby-forum.com/u/gordon321)\
**Post date:** [April 23, 2006, 7:00pm UTC](https://www.ruby-forum.com/t/re-solution-text-munger-76/58589/2 "2006-04-23T19:00:36Z")

</div>

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
