-3

I have strings such as 'pXoX prawa', they might contain a random number of X's. I want to replace these X with polish special characters

['ą', 'ć', 'ę', 'ł', 'ń', 'ó', 'ś', 'ź', 'ż']

and generate strings with all possible variants. In the case of "pXoX prawa" there are two X's, so all the possible combinations are 9^2=81, where 9 is the number of Polish special characters. I could brute force program it, but I wonder if anybody can come up with a 1-2 lines solution. Maybe some recursive coding. Any idea? If you want to use external libraries no problem.

halfer
  • 19,824
  • 17
  • 99
  • 186
Gismo Ranas
  • 6,043
  • 3
  • 27
  • 39
  • 1
    I've voted to re-open the question, but please refrain from adding voting/meta commentary material in posts in the future. It's rather subjective as to whether it is on-topic, but it's also a request for free work, as evidenced by your kind offer to let readers use any libraries they like. There is a view amongst the readership that question authors must have done a minimum of research prior to asking a question. – halfer Mar 20 '18 at 12:31

2 Answers2

1

Using a bit of recursion you should be able to handle multiple 'X's combinations.

Here is a snippet that show it..

var array = ['ą', 'ć', 'ę', 'ł', 'ń', 'ó', 'ś', 'ź', 'ż'];
var input = 'pXoX prawa';

const inputs = input.split("");

//lets store the positions of all the 'X's.
const posX = [];
inputs.forEach((i, ix) => { if(i === 'X') posX.push(ix); });

//lets have a counter for the loop
var c = 0;

function loop(idx) {
  for (let l = 0; l < array.length; l ++) {
    //lets change the letter from array.
    inputs[posX[idx]] = array[l];
    if (idx < posX.length -1) {      
      loop(idx + 1);
    } else {
      //ok all X's are filled for this itteration
      //lets log it.
      c ++;
      console.log(c, inputs.join(""));
    }
  }
}

loop(0);

Please note, this snippet console.log preview will not show all combinations as they flow out of the console's buffer. Look in your browsers console to see all 81.

halfer
  • 19,824
  • 17
  • 99
  • 186
Keith
  • 22,005
  • 2
  • 27
  • 44
1

You can have a generic function that generates all n-combinations with repetitions, and apply each combination to your template:

function* combinationsWithRepetitions(a, n) {
    if (n < 2) {
        yield* a;
        return;
    }

    for (let x of a)
        for (let c of combinationsWithRepetitions(a, n - 1))
            yield [x].concat(c);
}
 
//

chars = 'ABCD'
template = 'X and X'

for (let c of combinationsWithRepetitions(chars, 2))
    console.log(template.replace(/X/g, _ => c.shift()))

Note that since it's implemented as a generator, it will work just fine on arbitrary large inputs.

That's easy to extend to any number of placeholders:

template = 'X and X and X....X'
len = template.match(/X/g).length

for (let c of combinationsWithRepetitions(chars, len))
    etc
georg
  • 211,518
  • 52
  • 313
  • 390