سؤال

I am trying to make a function that takes a jumbled sequence of letters and returns English. For some reason, I can't get word = (word.ord-4).chr to work properly. The secret to the code is that the letters are shifted 4 slots backwards, which is why I'm converting it to an integer first, subtracting 4, and then turning it back to a string.

The loop also appears to be ignoring the fact that I told it to skip a word if it's any of those special characters. What am I doing wrong?

Any suggestions or sources that will bring me closer to solving this problem?

def north_korean_cipher(coded_mesage)
  input = coded_mesage.split('') # splits the coded message into array of letters

  input.each do |word|
    word = (word.ord - 4).chr

    if word == '@' || '#' || '$' || '%' || '^' || '&' || '*'
      next
    end
  end

  print input
end

north_korean_cipher('m^aerx%e&gsoi!')
هل كانت مفيدة؟

المحلول

You want a mapping like this:

input:  abcdefghijklmnopqrstuvwxyz
output: wxyzabcdefghijklmnopqrstuv

Unfortunately your approach doesn't work for the first 4 letters:

("a".ord - 4).chr #=> "]"
("b".ord - 4).chr #=> "^"
("c".ord - 4).chr #=> "_"
("d".ord - 4).chr #=> "`"

I'd use String#tr. It replaces each occurrence in the first string with the corresponding character in the second string:

"m^aerx%e&gsoi!".tr("abcdefghijklmnopqrstuvwxyz", "wxyzabcdefghijklmnopqrstuv")
#=> "i^want%a&coke!"

There's also a "c1-c2 notation to denote ranges of characters":

"m^aerx%e&gsoi!".tr("a-z", "w-za-v")
#=> "i^want%a&coke!"

The documentation further says:

If to_str is shorter than from_str, it is padded with its last character in order to maintain the correspondence.

So it can be used to easily replace the "special characters" with a space:

"m^aerx%e&gsoi!".tr("a-z@#$%^&*", "w-za-v ")
#=> "i want a coke!"

نصائح أخرى

This:

if word == '@' || '#' || '$' || '%' || '^' || '&' || '*'

does not do what you expect it to do, because '#' as a condition will always be true. You can't compare objects like that. You should do something like

if word == '@' || word == '#' || word == '$' || word == '%' || word == '^' || word == '&' || word == '*'

You can write it in a more succinct way by asking:

if %w(@ # $ % ^ & *).include? word

Which checks if word is in the collection of options...

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top