Ruby to Unjumble Words

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



Leave a reply



Submit