如何将字符串中每个单词的中间字母混洗?

时间:2018-05-03 19:43:28

标签: ruby string

尝试重新创建"只有聪明的人才能阅读这个"米姆。这是一个样本:

  

Hrad to blveiee taht aluclty uesdnatnrd waht yor'ue   rdanieg。 hmuan bairn的phaonmneal pweor,aoccdrnig to a   来自Cmabrigde Uinervtisy的rscheearch,sowhs taht它deos nottt in in   哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇!   frist和lsat ltteer在rghit pclae。

     

rset可以是一个taotl mses,你可以坐下来吧   porbelm。

     

Tihs是bcuseae huamn biarn deos not beed ervey lteter by istlef,   但是,作为一个wthe ptatren。 Amzanig吧? Yaeh,你呀   tghuhot slpeling是ipmorantt!

如何创建一个Ruby方法,在我传递的句子中为每个大于3个字母的单词混淆中间单词。

澄清:我已经发布了这个问题并同时回答了这两个问题。问题中没有代码,因为我将其发布在答案中。

3 个答案:

答案 0 :(得分:7)

好的,我会咬人的:

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

在repl.it上查看:https://repl.it/@jrunning/TrainedDangerousSlope

更新

我最初使用Regexp /(\S)(\S+)(\S)/,它将三个或更多非空白字符的任何序列视为“单词”。遗憾的是,将标点符号统计为单词字符,例如“Hello, world.”可能会变为“Hlloe, wlodr.” - ,.被计为单词的最后“字母”,并且实际的最后一个字母已被移动。< / p>

我已将其更新为使用Regexp /([\p{L}'])([\p{L}']{2,})([\p{L}'])/。字符类\p{L}对应于Unicode类别“Letters”,因此它与基本的变音符号一起使用,我投入'以匹配amingilani的实现。

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.

更新2

如果我们想要添加输出中输出中没有单词的字母顺序可能相同的要求,我们可以修改传递给gsub的proc以再次调用自己,直到订单发生变化:

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

我们仍然可以将其作为单行,但其可读性很快就会恶化:

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

在repl.it上查看:https://repl.it/@jrunning/TrainedDangerousSlope-2

答案 1 :(得分:6)

修改:此代码现在可以保证单词不会被意外地加到原始文本中。例如。 read现在将始终加到raed

编辑2:如果不能对字词进行加扰,则会返回原始字词,例如jumble 'feet' # => 'feet'

创建jumble个别单词的方法,并通过mess_up为句子中的每个单词调用

def mess_up(sentence)
  sentence = sentence.downcase.split(' ').map { |e| jumble(e) }.join(' ')
  sentence[0] = sentence[0].upcase
  sentence
end

def jumble(word)
  return word if word.size <= 3
  str = word.split('')
  f = str.shift
  l = str.pop
  return word if str.uniq.size == 1
  str = [f, str.shuffle, l].join('')
  return jumble(str) if word == str
  str
end

mess_up "Hard to believe that you could actually understand what you're reading"
# => "Hrad to bleevie taht you cuold aactlluy unrdnestad waht y'ruoe rendaig"

<强>动机

当我看到帖子时,我做了一个有趣的实验。是要在Gist中推动它,但意识到有人可能会在某个时候搜索它,所以SO是最适合它的地方。

答案 2 :(得分:4)

def scramble(sentence)
  sentence.split.map do |word|
    word.size <= 3 || word[1..-2].squeeze.size == 1 ? word : word[0] +
      word[1..-2].chars.shuffle.join('') + word[-1]
  end.join(' ')
end

scramble "Little Miss Muffat sat on a tuffet"
  #=> "Llitte Miss Mfauft sat on a tffuet"

如果一个混洗的单词(长度为4或更长)必须与原始单词不同,则可以编写以下内容。注意如果除了第一个和最后一个之外的所有字符都相同,则不能将长度为4或更大的单词混洗为与原始单词不同。

def scramble(sentence)
  sentence.split.map do |word|
    word.size <= 3  || word[1..-2].squeeze(word[0]).size == 1 ? word : 
      word[0] + my_shuffle(word[1..-2]) + word[-1]
  end.join(' ')
end

def my_shuffle(str)
  a = arr = str.chars
  loop do
    a = a.shuffle
    break a unless a == arr
  end.join('')
end