Как мне перетасовать средние буквы каждого слова в строке? - PullRequest
0 голосов
/ 03 мая 2018

Попытка воссоздать мем «Только умные люди могут прочитать этот» мем. Вот образец:

Рад твоему блаженству, что ты умеешь просить прощения за твою жизнь rdanieg. Феонмнеал Пвеор Хмуана Бэрна, поиск в Cmabrigde Uinervtisy, так что он не должен быть в Что бы ни было в мире, так это то, что нужно. Первый и второй человек находятся в центре внимания.

rset может быть taotl mses, и вы можете читать его без porbelm.

Tihs - bcuseae the huamn biarn deos not raed ervey lteter by thetlef, но wrod как wlohe ptatren. Амзаниг, а? Да ты ауляс Тхухот сплелинг был ипморант!

Как создать метод Ruby, который смешивает средние слова для каждого слова, превышающего 3 буквы, в предложении, которое я пропускаю.

Уточнение: Я опубликовал этот вопрос и отвечу на оба вопроса одновременно. В вопросе нет кода, потому что я разместил его в ответе.

Ответы [ 3 ]

0 голосов
/ 03 мая 2018

Хорошо, я укушу:

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

Обновление

Первоначально я использовал регулярное выражение /(\S)(\S+)(\S)/, которое считало «словом» любую последовательность из трех или более непробельных символов. Это, к сожалению, считается пунктуацией как символами слова, например, «Hello, world.» может стать «Hlloe, wlodr.» - , и . были посчитаны как последние «буквы» слов, а фактические последние буквы были перемещены.

Я обновил его, чтобы использовать регулярное выражение /([\p{L}'])([\p{L}']{2,})([\p{L}'])/. Класс символов \p{L} соответствует Unicode-категории "Буквы", поэтому он работает с основными диакритическими знаками, и я добавил ', чтобы соответствовать реализации 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, чтобы он вызывался сам до тех пор, пока порядок не изменится:

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

0 голосов
/ 03 мая 2018
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
0 голосов
/ 03 мая 2018

Редактировать: этот код теперь гарантирует, что слова не могут быть случайно зашифрованы в их исходном тексте. Например. 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 является лучшим местом для этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...