O ponto chave aqui é a resolução do que chamamos na matemática de permutação, ou seja, todas as distribuições possíveis de um grupo de elementos onde a sua ordem importa e sempre usamos todos os elementos. Uma forma simples e elegante de lidarmos com esse problema é através de recursão.
Como de costume, vamos começar a pensar no caso base para a nossa função recursiva. Como esse é um problema um pouco diferente, talvez seja mais difícil pensar em um caso baso num primeiro momento, mas podemos considerar como sendo o de um array vazio, ou seja, nenhum elemento. Se temos um array vazio, o retorno será um array bidimensional vazio também, então podemos fazer desse o nosso caso base aqui.
function possiblePasswords(chars) { if (chars.length === 0) {
return [[]]
}
}
Agora temos que prosseguir para obter as permutações. Para conseguir isso precisamos fazer com que a nossa função caminhe em direção ao caso base, o que no nosso caso é caminhar em direção ao array vazio. Para isso, podemos retirar o primeiro elemento do array e chamar recursivamente a nossa própria função e obter dela as possibilidades do nosso array com um elemento a menos.
function possiblePasswords(chars) {
if (chars.length === 0) {
return [[]]
}
const removedChar = chars[0]
const partialChars = chars.slice(1)
const partialPossibilites = possiblePasswords(partialChars)
}
Agora vamos assumir que nós já temos as permutações do array com um elemento a menos, tudo que precisamos fazer é obter um array que contém o elemento que removemos em cada uma das posições possíveis, desde o começo até o final do array. Para armazenar isso vamos criar um array para conter todas as possibilidades e iterar sobre o array que recebemos inserindo o elemento removido em cada uma das posições possíveis de cada conjunto. Como o resultado que recebemos já um array bidimensional, dentro de cada array utilizamos uma repetição para construir um novo array que contém o elemento removido e então inserir esse novo conjunto dentro do array que criamos fora do .forEach(). Feito isso, tudo que precisamos fazer é retornar o array de possibilidades, que agora deve conter todas as permutações de caracteres possíveis.
function possiblePasswords(chars) {
if (chars.length === 0) {
return [[]]
}
const removedChar = chars[0]
const partialChars = chars.slice(1)
const partialPossibilites = possiblePasswords(partialChars)
const allPossibilities = []
partialPossibilites.forEach(partialPossibility => {
for (let i = 0; i <= partialPossibility.length; i++) {
const completePossibility = [...partialPossibility.slice(0, i), removedChar, ...partialPossibility.slice(i)]
allPossibilities.push(completePossibility)
}
})
return allPossibilities
}