Why is it returning false?

Write a method that takes in a string and an array of indices in the string. Produce a new string, which contains letters from the input string in the order specified by the indices of the array of indices.

def scramble_string(string, positions)   
  i=0 
  while i<string.length 
    string[i]=string[positions[i]]
    i+=1 
  end   
  return string 
end

Tests for #scramble_string

scramble_string("abcd", [3, 1, 2, 0]) == "dbca"
# => false
scramble_string("markov", [5, 3, 1, 4, 2, 0]) == "vkaorm"
# => false

Hi marin, looks like you overwrite the string variable while you assign the chars, i would change the algorithm starting with something like that:

def scramble_string(string, positions)
  res = ''
  positions.each do |i|
    res << string[i]
  end
  res
end
1 Like

Hi fabiomux,

Thanks a lot! I was stuck for 2 days here.
So that’s the reason for needing an extra variable like ?
I don’t really understand <positions.each do [i]> part, but what I do understand is that I can’t just change the string directly without overwriting it and that’s why I need another variable like that helps me point to the initial string and change it.
Does that sound right?

Thanks,
Marin

1 Like

Yes Marin you need an extra variable (support variable i think is its name in english) where store the scrambled chars keeping the original untouched to don’t lose the original reference to that chars you are moving.

Assuming that ‘Hello’ is the string to scramble and the wanted order is “4,0,2,3,1” we have with your algorithm:

# step 1 (i = 0, string = Hello)
string[0] = string[4]
# string = oello
    
# step 2 (i = 1, string = oello)
string[1] = string[0]
# string = oollo

… and so on…

Just watch how in the first step you lost the letter “H” which has been replaced with “o”, that means you lost the original string and the next steps will never give you the wanted result.

Using a support variable as i did:

# step 1 (i = 0, string = Hello, res = '')
res << string[4]
# res = o, string = Hello

# step 2 (i = 1, string = Hello, res = o)
res << string[0]
# res = oH, string = Hello

… and so on…

That way you never lose the original string and finally get the correct result.

If you are looking to a more elegant and Ruby way you can dig among classes and methods and get something like that (just notice how the string variable is still left untouched and a new variable is created by map and given as a result for the latest but not least join method)

def scramble_string(string, positions)
  positions.map { |idx| string[idx]}.join
end
2 Likes

Thank you so much for the very detailed and helpful explanation!

1 Like