-1

I was going through some questions on HackerRank, that need to sort data a substring alphabetically "the shortest comes first" for example

["cd","cc","cca", "ccb"]

the expected output should be

["cca","ccb","cc","cd"]

my output is shown as follows

["cc","cca","ccb","cd"]

using the following simple code

substring.sort! {|s1,s2|   s1 <=> s2  }

my question is how can I make the sort to match the expected output. I was thinking if I can make the string have the same size and append a large value at the end of the string then I can match the expected output but then I have to clean up the strings afterward.

I am not sure if it is possible in ruby to solve it without a hacky method.

please give me your suggestions.

EDIT Sorry if it was not clear. basically, the algorithm they are using is checking the first letter from the first string and compare it with the second string. if they are the same it will move to the next letter of each string.. and so on... the trick is if they are no the same size it will always sort the shorter string as bigger than the longer if the last letter of the small string is the same as the second string. I will need to give more examples to clarify.

Example 1

["aac","aa","c","cd","da","a","bb","bd"]

Expected output is

["aac","aa","a","bb","bd","c","cd","da"]

Example 2

["d","ca","cb","cc","cca","ccb","ccc"]

Expected output is

["ca","cb","cca","ccb","ccc","cc","d"]

I hope that is more clearer.

  • Appending to a string is not an efficient strategy especially for HackerRank tasks. Nonetheless, better write your version in the question so that we can improve your code. – yzalavin Jan 28 '21 at 12:16
  • 1
    It is quite unclear what you are trying to achieve here. You said "shortest comes first" and then in expected results "cc" is after "cca"? Your output is 100% correct, even though it is same as `ary.sort` output. `sort` is using `<=>` for comparison and will be much faster as no custom block is involved. – BroiSatse Jan 28 '21 at 12:27
  • 1
    "need to sort data a substring alphabetically "the shortest comes first"" – That makes no sense. The two orderings are contradictory. – Jörg W Mittag Jan 28 '21 at 12:35
  • it seems that the sorting method they are using is comparing the size of each letter for the first string to the second string but not the sum of all the letters. and if the first letter is the same size it will check the second letter. – Ismail Al.Mahdi Jan 28 '21 at 17:49

1 Answers1

0

There should be no need for a hacky method, sort is flexible enough.

Your code currently compares s1 to s2 using default Ruby's comparison (<=>). I believe you should compare lengths of s1 and s2 first, returning alphabetical comparison when the lengths are equal.

Another approach is to group the input array by size, then sort each chunk independently, then flatten the array. Something along the lines of:

input_array.group_by(&:size).sort.map(&:last).map(&:sort).flatten

which seems to work like this:

irb(main):025:0> ["defg", "c", "cd", "cc", "cca", "ccb"].group_by(&:size).sort.map(&:last).map(&:sort).flatten
=> ["c", "cc", "cd", "cca", "ccb", "defg"]
Miki
  • 7,052
  • 2
  • 29
  • 39
  • Thank you for the answer, but for the example, you have given here the expected answer will be ["cca","ccb", "cc","c","cd","defg"] – Ismail Al.Mahdi Jan 28 '21 at 17:42
  • it seems that the way it is sorting is based on each letter byte size. it is comparing the first letter from the first string with the second letter and if they are the same it will compare the second letter from each string – Ismail Al.Mahdi Jan 28 '21 at 17:45
  • based on your comment, the sorting seems to be alphabetical first, with shortest last ("cca" is before "c", which is against what the regular sorting would be) in general, there are two approaches: either figuring out how to group elements and then how to sort them within each group, or write a method that sorts two given strings and use that (in this particular case, sorting is done by first letter - if they are equal, the sorting result is equal to the sorting result of the remainder of both strings; and comparing empty string always means it is "greater than" any non-empty) – Miki Feb 01 '21 at 06:41