Reputation: 19
Basically want to make 'abc' into 'bcd'. I was thinking if I add the letter the follows the first to the end of the phrase and dropped the original first letter, eventually I'd get the final solution. Got kinda stuck and was hoping someone could shed some light on it for me. Thanks
def encrypt(str)
index = 0
encrypted_str = ""
duration = str.length
until index == str.length
encrypted_str = str + str[0].next
encrypted_str = encrypted_str + encrypted_str.delete(str[index])
index += 1
end
puts encrypted_str
end
#puts "What would you like to encrypt?"
message = "abc"
puts encrypt(message)
Upvotes: 0
Views: 75
Reputation: 230346
Another option, which uses more power of stdlib :)
def original
"abcdefghijklmnopqrstuvwxyz"
end
def replacement
"bcdefghijklmnopqrstuvwxyza"
end
def encrypt(str)
str.tr(original, replacement)
end
def decrypt(str)
str.tr(replacement, original)
end
encrypt('abc') # => "bcd"
decrypt('bcd') # => "abc"
Quite flexible too (compared to succ
-based approach). You can change replacement
alphabet to define arbitrary transformation rules.
Upvotes: 2
Reputation: 110685
ENCRYPT = [*'a'..'z'].zip([*'b'..'z', 'a']).to_h
#=> {"a"=>"b", "b"=>"c",..., "y"=>"z", "z"=>"a"}
DECRYPT = ENCRYPT.invert
#=> {"b"=>"a", "c"=>"b",..., "z"=>"y", "a"=>"z"}
def encrypt(str)
crypt(str, ENCRYPT)
end
def decrypt(str)
crypt(str, DECRYPT)
end
def crypt(str, mapping)
str.gsub(/./, mapping)
end
encrypt('abc') #=> "bcd"
decrypt('bcd') #=> "abc"
encrypt('amnrz') #=> "bnosa"
decrypt('bnosa') #=> "amnrz"
This uses the form of String#gsub that takes a hash as an argument. See also Hash#invert.
Upvotes: 2
Reputation: 6121
Your code analysis..
Since you already initializing encrypted_str
with empty string, there's no need to append it to original string and then slice
it again..that's where it is getting messed up..just do the following..
until index == duration #you are not using duration too if assigned it to a variable
encrypted_str += str[index].next[0]
index += 1
end
Taking the index 0 for next string because 'z'.next
returns aa
An alternative one liner approach would be..
message.each_char.map { |s| s.next[0] }.join
chars
will split the message into individual characters
map
collects the manipulated characters into an array
join
will join individual characters from mapped array to a string again
To Decrypt
encrypted_str.each_char.map { |s| s.eql?('a') ? 'z' : (s.ord-1).chr }.join
Upvotes: 3