Disqualifying consecutive characters in an Alphabetical Order. Sol [ASCII Format]

Viewed 129

I was given this problem by my friend. The question asks to remove all the alphabetically consecutive characters from the string input given. So I did it using Javascript, I need expert help if I performed it precisely.

I thought using Array.prototype.reduce will be the best way, do we have other possible ways?

/**
 * @author Abhishek Mittal <abhishekmittaloffice@gmail.com>
 * @description function can deal with both any types followed in a consecutive manner in ASCII Chart.
 * @param {string} str 
 */
function improvise(str) {
    // Backup for original input.
    const bck = str || '';
    const bckArr = bck.split('').map( e => e.charCodeAt(0)); // converting the alphabets into its ASCII for simplicity and reducing the mayhem.

    let result = bckArr.reduce( (acc, n) => {
            // Setting up flag
            let flag1 = n - acc.rand[acc.rand.length - 1];
            let flag2 = n - acc.temp;

            if(flag1 === 1 || flag2 === 1) {
                (flag2 !== NaN && flag2 !== 1) ? acc.rand.pop() : null; // update the latest value with according to the case.
                acc.temp = n
            }else{
                acc.rand.push(n); // updating the random to latest state.
                acc.temp = null;
            }

        return acc;

    }, {rand: [], temp: null} /* setting up accumulative situation of the desired result */) 

    result = result.rand.map(e => String.fromCharCode(e)).join('')
    return result ? result : '' ;
}

function init() {
    const str = "ab145c";
    const final = improvise(str);
    console.log(final)
}
init();

Well, the output is coming out to be correct. Input: ab145c Output: 1c

2 Answers

There's no way to solve this using any remotely reasonable regular expression, unfortunately.

I think it would be a lot clearer to use .filter, and check whether either the next character or the previous character is consecutive:

const code = char => char
? char.charCodeAt(0)
: -2; // will not be === to any other codes after addition or subtraction
  
function improvise(str) {
  return [...str]
    .filter((char, i) => {
      const thisCode = code(char);
      return (
        thisCode !== code(str[i - 1]) + 1
        && thisCode !== code(str[i + 1]) - 1
      );
    })
    .join('');
}

console.log(improvise('ab145c'));

(alternatively, you could check only whether the next character is consecutive, but then you'd have to check the validity of the last character in the string as well)

If you need continuously replace characters until no consecutive characters remain, then keep calling improvise:

const code = char => char
? char.charCodeAt(0)
: -2; // will not be === to any other codes after addition or subtraction
  
function improvise(str) {
  return [...str]
    .filter((char, i) => {
      const thisCode = code(char);
      return (
        thisCode !== code(str[i - 1]) + 1
        && thisCode !== code(str[i + 1]) - 1
      );
    })
    .join('');
}

let result = 'hishakmitalaaaaabbbbbbcccccclmnojqyz';
let same = false;
while (!same) {
  const newResult = improvise(result);
  if (newResult !== result) {
    result = newResult;
    console.log(result);
  } else {
    same = true;
  }
}
console.log('FINAL:', result);

Well, that's great code but it doesn't gives the exact solution to the problem, see:

INPUT: hishakmitalaaaaabbbbbbcccccclmnojqyz

i got

Output: shakmitalaaaabbbbcccccjq

you see 'ab' & 'bc' remains intact, we need to increase the number of loops maybe to check those, can increase complexity as well. But, my solution doesn't as well gives me the answer I desire e.g. for the above string I should get

ishakmitalaacccjq

but rather my solution gives

shakmitalcccccjq

hope you understand the question. We need a change in the way we traverse throughout the string.

Related