-2

I have to make a function that receives a phrase and encrypts it. The cipher is to each letter in alphabet the encrypted letter is 3 letter ahead.

Example

Alphabet: A B C D E F G ... X Y Z
Ciphered: D E F G H I J ... A B C

If this is my alphabet in Ruby:

a = ['a','b','c','d','e'] 

I need to map it to:

a = ['c','d','e','a','b']

I've tried iterate twice the array and remove some indexes but I know I'm missing something.

UPDATE--------------------------------------------------------------------

I've managed to solve the six tests where I receive a phrase and have to encrypts as the test require.

Received phrase: prefiro perder a guerra e ganhar a paz
Phrase expected: suhilur#shughu#d#jxhuud#h#jdqkdu#d#sd}

I realize that to cypher the phrase I should change the letters positions 3 positions ahead in the ascii table.

Example: The letter 'a' should be encrypted as 'd', The letter 'z' should be encrypted as '}' and also the 'space' 3 positions ahead in the ascii table is '#'.

Here follows the code I used to solve this:


def cipher(text)
    key = 3
    cipher_text = text.chars.map {|x| x.ord}
                            .map {|x| x+key}
    cipher_text.map { |x| x.chr }.join
  end

  def decipher(text)
    key = 3
    decipher_text = text.chars.map {|x| x.ord}
                              .map {|x| x-key}
    decipher_text.map { |x| x.chr }.join
  end

  • What is the logic behind mapping? – Fabio Jun 08 '20 at 22:44
  • 2
    Maybe `a.rotate(2)`? – red_menace Jun 08 '20 at 22:53
  • Hi and thanks for your help. I have to make a function that receives a phrase and encrypts it. The cipher is to each letter in alphabet the encrypted letter is 3 letter ahead. Exemple: Our alphabet: A B C D E F G...X Y Z Ciphered:. D E F G H I J...A B C And # means space in the received phrase. – Italo Fasanelli Leomil Jun 08 '20 at 22:58
  • @ItaloFasanelliLeomil : _I've tried iterate twice the array and remove some indexes but I know I'm missing something_ : I don't see any code doing iteration in your question. How can I tell you what you are missing, if I don't see what you already have? – user1934428 Jun 09 '20 at 06:52

3 Answers3

2

For encryption mentioned in the comments use String.tr method

I have to make a function that receives a phrase and encrypts it. The cipher is to each letter in alphabet the encrypted letter is 3 letter ahead.

phrase = "abcd st xyz"

encrypted = phrase.tr("A-Za-z ", "D-ZA-Cd-za-c#")

# => "defg#vw#abc"

Update

Please notice that the letter 'z' (at the end of the phrase) means '}'

You can map xyz character to {|} explicitly

phrase = "prefiro perder a guerra e ganhar a paz"

encrypted = phrase.tr("A-Wa-wXYZxyz ", "D-WA-Cd-wa-c{|}{|}#")

# => "suhilur#shughu#d#jxhuud#h#jdqkdu#d#sd}"
Fabio
  • 31,528
  • 4
  • 33
  • 72
  • Hi Fabio, your solution worked fine in 4 of 6 tests. But this two remaining tests are kinda tricky. The phrase is "prefiro perder a guerra e ganhar a paz" and should encrypts to "suhilur#shughu#d#jxhuud#h#jdqkdu#d#sd}". Please notice that the letter 'z' (at the end of the phrase) means '}'. And I don't have idea how to solve this. – Italo Fasanelli Leomil Jun 08 '20 at 23:29
  • I'm sorry, I'm struggling with my english skills here. Let me express better, I notice that the test is using the ASCII table, for this task we're using the alphabet +3 to encrypts the code. So 'A'(dec 97) means 'D'(dec 100). `A B C D E F G H I J K L M N O P Q R S T U V W X Y Z` Into: `D E F G H I J K L M N O P Q R S T U V W X Y Z { | }` And to get worse I need to make '#' into space. – Italo Fasanelli Leomil Jun 09 '20 at 00:12
  • Configure it explicitly as last sample configures `z` to `}` – Fabio Jun 09 '20 at 00:24
1

Not sure I understand your question, but the data looks like you rotate the elements in the array. In Ruby you have a special method for that.

a = %w[a b c d] #=> ["a", "b", "c", "d"]
a.rotate        #=> ["b", "c", "d", "a"]
a               #=> ["a", "b", "c", "d"]
a.rotate(2)     #=> ["c", "d", "a", "b"]
a.rotate(-3)    #=> ["b", "c", "d", "a"]
Danil Speransky
  • 29,891
  • 5
  • 68
  • 79
  • Since elements are to be rotated in place you may wish to use [Array#rotate!](https://ruby-doc.org/core-2.7.0/Array.html#method-i-rotate-21). – Cary Swoveland Jun 09 '20 at 00:20
0

Given an alphabet:

alphabet = ('A'..'Z').to_a
#=> ["A", "B", "C", "D", "E", ..., "V", "W", "X", "Y", "Z"]

You can create the ciphered one by calling rotate:

ciphered = alphabet.rotate(3)
#=> ["D", "E", "F", "G", "H", ..., "Y", "Z", "A", "B", "C"]

And create a mapping from one to the other:

to_cipher = alphabet.zip(ciphered).to_h
#=> {"A"=>"D", "B"=>"E", "C"=>"F", ..., "X"=>"A", "Y"=>"B", "Z"=>"C"}

Now, to encrypt a given string, we have to run each character through that hash:

'HELLO WORLD!'.each_char.map { |char| to_cipher[char] }.join
#=> "KHOORZRUOG"

Well, almost. That also removed the space and exclamation mark. We can fix this by providing a fallback for characters that don't occur in the hash:

'HELLO WORLD!'.each_char.map { |char| to_cipher.fetch(char, char) }.join
#=> "KHOOR ZRUOG!"

Or, with regular expressions using gsub:

'HELLO WORLD!'.gsub(Regexp.union(to_cipher.keys), to_cipher)
#=> "KHOOR ZRUOG!"
Stefan
  • 109,145
  • 14
  • 143
  • 218