1
\$\begingroup\$

The task:

Given a word W and a string S, find all starting indices in S which are anagrams of W.

For example, given that W is "ab", and S is "abxaba", return 0, 3, and 4.

My solution:

    const anagramOccurrencesOf = (w, s) => {
      const occurrencesCopy = [];
      let sCopy = s.slice(0);
    
      let index = 0;
      while (sCopy.length && index !== -1) {
        index = sCopy.indexOf(w);
        if (index === -1) { break; }
        occurrencesCopy.push((occurrencesCopy[occurrencesCopy.length - 1] + index + 1 || 0));
        sCopy = sCopy.slice(index + 1);
      }
      const occurrencesReverse = [];
      let sReverse = s.split('').reverse().join('');
    
      index = 0;
      while (sReverse.length && index !== -1) {
        index = sReverse.indexOf(w);
        if (index === -1) { break; }
        occurrencesReverse.push( (occurrencesReverse[occurrencesReverse.length - 1] - w.length - index + 1) || s.length - w.length);
        sReverse = sReverse.slice(index + 1);
      }
    
      return [...occurrencesCopy, ...occurrencesReverse].sort((a,b) => a -b);
    };
    
    console.log(anagramOccurrencesOf("ab", "abxaba"));

EDIT: The solution above would find indexes of palindromes. The solution below should find indexes of anagrams:

const sortAlphabetically = x => x.toLowerCase().split('').sort().join('')
const getIndexOfAnagramIn = (s, w) => {
  const wSorted = sortAlphabetically(w);
  const result = []
  for (let i = 0; i < s.length + 1 - w.length; i++) {
    if (sortAlphabetically(s.slice(i, i + w.length)) === wSorted) {
      result.push(i);
    }
  }
  return result;
}

console.log(getIndexOfAnagramIn('abxaba', 'ab'));

\$\endgroup\$
  • \$\begingroup\$ Notice that anagrams are not only reverses. For a word abc there are 6 anagrams. \$\endgroup\$ – vnp Feb 16 at 17:22
  • \$\begingroup\$ Ah, i mistook them with palindromes \$\endgroup\$ – thadeuszlay Feb 16 at 18:50
  • \$\begingroup\$ Shouldn’t the example indices be: 0, 1, 3, 4, 5? \$\endgroup\$ – morbusg Feb 17 at 12:11
  • \$\begingroup\$ Not from what I understood. Why do you think so? @morbusg \$\endgroup\$ – thadeuszlay Feb 17 at 13:23
  • \$\begingroup\$ @thadeuszlay: well, the 4th index confuses me in the example as it is ba, but the 1st index would also be when backwards. \$\endgroup\$ – morbusg Feb 17 at 14:09
2
\$\begingroup\$

This code looks pretty good. I don't see much I would change. This code makes good use of const and let where appropriate.

The only thing that stands out is that splitting a string into an array can be done with the spread syntax instead of calling split().

The first instance:

let sReverse = s.split('').reverse().join('');

Could be changed to

let sReverse = [...s].reverse().join('');

And the other instance:

const sortAlphabetically = x => x.toLowerCase().split('').sort().join('')

Could be changed to:

const sortAlphabetically = x => [...x.toLowerCase()].sort().join('')
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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