1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
def remove_insults(input) ctr = 0 input.each do |word| word = word.downcase if word == "stupid" || word == "moron" || word == "dumbass" || word == "retard" i=0 word.length.times do input[ctr][i,1] = "*" i+=1 end end ctr += 1 end puts input.join(" ").to_s end remove_insults "you truly are a moron sir!".split(" ")
Refactorings
No refactoring yet !
jorrel
October 11, 2007, October 11, 2007 16:12, permalink
1 2 3 4 5 6
INSULTS = %w(stupid moron dumbass retart) BAD_CHAR = '*' def remove_insults(input) input.split(' ').collect { |word| INSULTS.include?(word) ? BAD_CHAR * word.size : word }.join(' ') end puts remove_insults("you truly are a moron sir!")
FrankLamontagne
October 11, 2007, October 11, 2007 16:40, permalink
A reversed approach...
1 2 3 4 5 6
def remove_insults(input) insults = ["stupid","moron","dumbass","retard"] insults.each { |insult| input.gsub!(insult,'*' * insult.length) } input end puts remove_insults("You truly are a moron sir!")
Scott Patten
October 11, 2007, October 11, 2007 17:43, permalink
I did it two ways. The first assumed that you had to stick with the input coming in as an array of words. The second let you input it as a sentence, and also removed insults that were 'disguised' by punctuation. This resulted in an ugly reg-exp, so forgive me for that.
I also move the 'put' to the caller in both cases, as that felt more Rubyish to me.
Scott
P.S. I didn't peek at the other solutions first, but it looks like both of my methods were previously done :)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
def remove_insults(input) insults = %w(stupid moron dumbass retard) input.collect do |word| insults.include?(word) ? "*" * word.length : word end.join(" ") end def remove_insults_from_sentence(sentence) insults = %w(stupid moron dumbass retard) insults.each do |insult| sentence.gsub!(/([\s\'\"]+)(#{insult})([\s\'\",\.;]+)/) {"#{$1}#{'*' * $2.length}#{$3}"} end sentence end puts remove_insults("you truly are a stupid moron sir!".split(" ")) puts remove_insults_from_sentence("you truly are a 'stupid' moron, sir!")
macournoyer
October 11, 2007, October 11, 2007 18:02, permalink
I think this is the more Rubyish I can get.
1 2 3 4 5 6 7 8
def remove_insults(sentence) %w(stupid moron dumbass retard).inject(sentence) do |clean_sentence, insult| clean_sentence[insult] = '*' * insult.size if clean_sentence.include? insult clean_sentence end end puts remove_insults("you truly are a 'stupid' moron, sir!")
macournoyer
October 11, 2007, October 11, 2007 18:31, permalink
Huh, my previous solution didn't worked if the word was there twice, here a fixed one, in one line
1 2 3 4 5
def remove_insults(sentence) %w(stupid moron dumbass retard).inject(sentence) { |clean_sentence, insult| clean_sentence.gsub insult, '*' * insult.size } end puts remove_insults("you truly are a 'stupid' moron, stupid sir!")
danielharan
October 11, 2007, October 11, 2007 18:38, permalink
After noticing the issue with repetition, I figured we could also break it with mixing case. Here's a more robust solution ;)
1 2 3 4 5
def remove_insults(input) %w{ stupid moron dumbass retard }.each {|insult| input.gsub!(Regexp.new(insult, true),'*' * insult.length) } input end remove_insults("Stupid wabbit! Stupid, stupid, stupid!")
macournoyer
October 11, 2007, October 11, 2007 18:44, permalink
also refactored mine following Daniel advice but using /.../i syntax
1 2 3 4 5
def remove_insults(sentence) %w(stupid moron dumbass retard).inject(sentence) { |clean_sentence, insult| clean_sentence.gsub /#{insult}/i, '*' * insult.size } end puts remove_insults("you truly are a 'Stupid' moron, stupid sir!")
hungryblank
October 12, 2007, October 12, 2007 13:39, permalink
This solution uses a different regexp
/#{%w( stupid moron dumbass retard ).join('|')}/i
generates this regexp
/stupid|moron|dumbass|retard/i
that can be used to match any insult in the given sentence
1 2 3 4 5
def remove_insults(sentence) sentence.gsub(/#{%w( stupid moron dumbass retard ).join('|')}/i) { |insult| '*' * insult.size } end puts remove_insults("you truly are a 'Stupid' moron, stupid sir!")
namxam
October 17, 2007, October 17, 2007 11:01, permalink
Based on the nice code from macournoyer, I would suggest a slightly different way of calling the method. Why not to extend the String object and make the function available to all strings. Oh, and added a conveenient way to change the "bad" words.
1 2 3 4 5 6 7
class String def to_clean_english(bad_words = %w(stupid moron dumbass retard)) bad_words.inject(self) { |clean_sentence, insult| clean_sentence.gsub /#{insult}/i, '*' * insult.size } end end "you truly are a 'Stupid' moron, stupid sir!".to_clean_english()
Adam
September 30, 2008, September 30, 2008 20:41, permalink
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
class CleanString < String INAPPROPRIATE_WORDS = %w(stupid moron dumbass retard) INAPPROPRIATE_REGEX = Regexp.new(INAPPROPRIATE_WORDS.join("|"), true) attr_reader :unclean def initialize(string) @unclean = string super string.gsub(INAPPROPRIATE_REGEX) { |word| '*' * word.size } end end class String def clean CleanString.new(self) end end >> "You are a stupid moron, dumbass!".clean => "You are a ****** *****, *******!" >> "You are a stupid moron, dumbass!".clean.unclean => "You are a stupid moron, dumbass!"
This snippet is coming from the serie "Rubyize this" you can find on Ruby Fleebie ( http://www.rubyfleebie.com/rubyize-this-3rd-edition)
It's poorly written on purpose! The objective is to let people improve it and make it looks more ruby-like.