3
\$\begingroup\$

The challenge was to find the missing letter in an array in alphabetical order.

Find the missing letter in the passed letter range and return it.

If all letters are present in the range, return undefined.

My solution was this:

function fearNotLetter(str) {
  var letters = str.split('');
  var codes = [];
  var missing = 0;
  var start = 0 , next = 0 , c = 0;
  for(var i= 0; i < letters.length; i++){
    var charcode = letters[i].toString();
    codes.push(charcode.charCodeAt());
  }
  for(var j = 1; j < codes.length; j++){
    start = codes[j] -1;
    if(codes.indexOf(start) === -1){
      missing += start;
    }

  }
  if(missing === 0){
    return undefined
  }else {
    return String.fromCharCode(missing);
  }
}

I am wondering whether I have followed some bad practices or used dry code which might cause problems in a later use. Thanks in advance.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ It would be useful if you explained in more detail what your code does. From the current description it's not very clear. A sample input and output would be helpful. \$\endgroup\$
    – kyrill
    Apr 10, 2017 at 10:40
  • 1
    \$\begingroup\$ This is actually an interesting problem in terms of efficiency / possible optimization. The current asymptotic time complexity is quadratic, but it can be done in linear time. Also, judging by the fromCharCode at the end, you assume there is only one missing letter. If that's the case, you can just break out of the second for instead of adding start to missing and proceeding to process the rest of codes. \$\endgroup\$
    – kyrill
    Apr 10, 2017 at 11:15

2 Answers 2

4
\$\begingroup\$

In general, you don't need to split the string and then process the array. Simply you must start from the first letter and store its charcode and then process the next later and check with the incremented charcode. If there is a difference than just break.

function f(str) {
    if (str && 0 < str.length) {
        var desCharCode = str.charCodeAt(0);
        for (var i = 1; i < str.length; ++i) {
            ++desCharCode;
            if (str.charCodeAt(i) != desCharCode) {
                return String.fromCharCode(desCharCode);
            }
        }
    }

    return undefined;
}
\$\endgroup\$
4
  • 2
    \$\begingroup\$ Also, f is a wonderful name for a function. \$\endgroup\$
    – kyrill
    Apr 10, 2017 at 11:46
  • \$\begingroup\$ @kyrill: Quoting the first line of question: The challenge was to find the missing letter in an array in alphabetical order (emphasis mine). And what's regarding letter repetitions – you are right in here. Solution to this would be really simple, though. \$\endgroup\$
    – Przemek
    Apr 10, 2017 at 19:14
  • 1
    \$\begingroup\$ @Przemek I misunderstood the description. My understanding was that the alphabetical order determines which missing letter is the "first missing letter", not that the input is sorted. And of course in that case this solution, possibly with the edit you suggested, is superior to mine. \$\endgroup\$
    – kyrill
    Apr 10, 2017 at 19:40
  • 1
    \$\begingroup\$ @kyrill: Well, taken into account assumptions about input sequence that can be made, Velial's answer is indeed more efficient. But it's still good to have your answer in here, in case anyone wanted to perform such check for unsorted string. Your code's style is far better too, by the way. \$\endgroup\$
    – Przemek
    Apr 10, 2017 at 19:46
1
\$\begingroup\$

\$O(n)\$ time solution which is functionally equivalent to @Ozan's original solution.

Does not require the string to be sorted, nor to contain no duplicates.

function fearNotLetter(str) {
  let codes = {};
  let min = str.charCodeAt(0),
      max = min;

  for (let i = 0, l = str.length; i < l; i++) {
    const c = str.charCodeAt(i);

    codes[c] = true;

    if (c < min) {
      min = c;
    } else if (c > max) {
      max = c;
    }
  }

  for (let i = min+1; i < max; i++) {
    if (codes[i] === undefined) {
      return String.fromCharCode(i);
    }
  }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.