1

All characters in input string have the same exact frequency (i.e. occur the same number of times), for example, "xxyyzz" is valid, but "xyyzzz" is not valid.

can anyone provide regex for same.

2 Answers2

4

Without regex, here is something that works:

(count the frequency of each character, and just check that they are all the same)

// Function taken from https://stackoverflow.com/questions/18619785/counting-frequency-of-characters-in-a-string-using-javascript
function getFrequency(string) {
    var freq = {};
    for (var i=0; i<string.length;i++) {
        var character = string.charAt(i);
        if (freq[character]) {
           freq[character]++;
        } else {
           freq[character] = 1;
        }
    }

    return freq;
};

function isValid(string) {
    let freq = getFrequency(string);
    let first = Object.values(freq)[0];
    return Object.values(freq).every(i => i == first);
}

let testStrings = ["xyyzzz", "xxyyzz", "xxyyzzz"];
for (let test of testStrings) {
    console.log(`Is "${test}" valid? ${isValid(test)}`);
}

With regex, and as comments have noticed, it's unlikely that you will have a good solution that applies for any case.

The count method as above is pretty simple and fairly efficient (even though there is probably some room for improvement)

Pac0
  • 21,465
  • 8
  • 65
  • 74
0

Just a combination of regex and e.g. a truthy/falsy check over a list of regex matches can do the job.

The most simple approach I could think of looks like that ...

console.log('xxxYYYzzz'.match(/(.)\1*/g).every((elm, idx, arr) => (elm.length === arr[0].length)));   // passes.
console.log('xxxYYzzzz'.match(/(.)\1*/g).every((elm, idx, arr) => (elm.length === arr[0].length)));   // fails.
console.log('xxxYYYzzzz'.match(/(.)\1*/g).every((elm, idx, arr) => (elm.length === arr[0].length)));  // fails.
.as-console-wrapper { min-height: 100%!important; top: 0; }

... and on top of this proof of concept one could build something similar to the next solution ...

//
//  ... proof of concept test cases ...
//
//  pass: 'xxxYYYzzz'.match(/(.)\1*/g).every((elm, idx, arr) => (elm.length === arr[0].length))
//  fail: 'xxxYYzzzz'.match(/(.)\1*/g).every((elm, idx, arr) => (elm.length === arr[0].length))
//  fail: 'xxxYYYzzzz'.match(/(.)\1*/g).every((elm, idx, arr) => (elm.length === arr[0].length))
//

function testCharacterFrequency(str) {
  const matchList = str.match(/(.)\1*/g) || []; // e.g. ["xxx", "YYY", "zzz"] for (str = 'xxxYYYzzz')
  const harmonyTestLength = (matchList.length >= 2) && matchList[0].length;

  const isHarmonic = !!harmonyTestLength && matchList.every(elm => (elm.length === harmonyTestLength));
  const frequencyLength = (isHarmonic && harmonyTestLength) || -1;

  return {
    isHarmonic,
    frequencyLength
  }
}

console.log("testCharacterFrequency('xxxYYYzzz') : ", testCharacterFrequency('xxxYYYzzz'));
console.log("testCharacterFrequency('xxxYYYzzz') : ", testCharacterFrequency('xxxYYzzzz'));

console.log("testCharacterFrequency('aaaaaBBBBBcccccDDDDDeeeee') : ", testCharacterFrequency('aaaaaBBBBBcccccDDDDDeeeee'));
console.log("testCharacterFrequency('aaaaaBBBBBcccccDDDDDeeeeE') : ", testCharacterFrequency('aaaaaBBBBBcccccDDDDDeeeeE'));
.as-console-wrapper { min-height: 100%!important; top: 0; }
Peter Seliger
  • 11,747
  • 3
  • 28
  • 37