How do I shuffle the middle letters of every word in a string?
Okay, I'll bite:
def srlabmce(str)
str.gsub(/([\p{L}'])([\p{L}']{2,})([\p{L}'])/) { "#$1#{$2.chars.shuffle.join}#$3" }
end
puts srlabmce("Hard to believe that you could actually understand what you're reading")
# => Hrad to beviele taht you cuold atlculay unantdresd what yoru'e raeindg
See it on repl.it: https://repl.it/@jrunning/TrainedDangerousSlope
Update
I originally used the Regexp /(\S)(\S+)(\S)/
, which counted as a "word" any sequence of three or more non-whitespace characters. This unfortunately counted punctuation as word characters, so e.g. "Hello, world.
" might become "Hlloe, wlodr.
"—the ,
and .
were counted as the last "letters" of the words, and the actual last letters were moved.
I've updated it to use the Regexp /([\p{L}'])([\p{L}']{2,})([\p{L}'])/
. The character class \p{L}
corresponds to the Unicode category "Letters," so it works with basic diacritics, and I threw in '
to match amingilani's implementation.
puts srlabmce("Quem ïd feugiat iaculisé éu mié tùrpus ïn interdùm grâvida, malesuada vivamus nam nullä urna justo conubia torétoré lorem.")
# => Qeum ïd fgieuat iliacusé éu mié tpùurs ïn iedùtnrm girâdva, madueasla vimavus nam nullä unra jutso cnboiua ttoréroé lerom.
Update 2
If we want to add the requirement that no word's letter order may be the same in the output as the input, we can modify the proc passed to gsub
to call itself again until the order has changed:
def srlabmce(str)
replacer = ->*{
if $2.chars.uniq.size < 2 then $&
else
o = $2.chars.shuffle.join
o == $2 ? replacer[] : "#$1#{o}#$3"
end
}
str.gsub(/([\p{L}'])([\p{L}']{2,})([\p{L}'])/, &replacer)
end
We can still make this a one-liner, but its readability quickly deteriorates:
def srlabmce(str)
str.gsub(/([\p{L}'])([\p{L}']{2,})([\p{L}'])/, &(r = ->*{ $2.chars.uniq.size < 2 ? $& : (o = $2.chars.shuffle.join) == $& ? r[] : "#$1#{o}#$3" }))
end
See it on repl.it: https://repl.it/@jrunning/TrainedDangerousSlope-2
Making a flashing console message with ruby
Typically this would be written something like:
0.upto(9) do
STDOUT.print "\rFlash!"
sleep 0.5
STDOUT.print "\r " # Send return and six spaces
sleep 0.5
end
Back in the days when we'd talk to TTY and dot-matrix printers, we'd rapidly become used to the carriage-control characters, like "\r", "\n", "\t", etc. Today, people rarely do that to start, because they want to use the web, and browsers; Learning to talk to devices comes a lot later.
"\r" means return the carriage to its home position, which, on a type-writer moved the roller all the way to the right so we could start typing on the left margin again. Printers with moving heads reversed that and would move the print-head all the way to the left, but, in either case, printing started on the left-margin again. With the console/telnet/video-TTY, it moves the cursor to the left margin. It's all the same, just different technology.
A little more usable routine would be:
msg = 'Flash!'
10.times do
print "\r#{ msg }"
sleep 0.5
print "\r#{ ' ' * msg.size }" # Send return and however many spaces are needed.
sleep 0.5
end
Change msg
to what you want, and the code will automatically use the right number of spaces to overwrite the characters.
Related Topics
How to Prevent My Users to Read My Ruby Code
Rails: Upload a File or Store a Url
Fetching Second Row from CSV File in Ruby
Rails How to Use Associated Model with the Admin Namespace
Sum of Arrays of Different Size
Determining Type of an Object in Ruby
How to Send Notifications to the User Whose Post Received a Comment
Compressed Output Differs from Go to Ruby Implementation
Error Pushing Ruby on Rails to Heroku
Create Multiple Records with Fields_For - Rails
Pass Array Hidden Field in Nested Model Rails
Complete Web Apps in Ruby Without Using Any Frameworks - How Difficult? Pitfalls
Ancestry Gem in Rails and Mutli Nesting
Create a Titleize Method, That Excludes "Little Words"
Selenium Webdriver Take Screenshot of Viewport Only
Vps Apache Config - Invalid Command 'Passengerdefaultruby' After Adding Latest Passenger Gem