Dado um conjunto de fórmulas como este:
bacb
bcab
cbba
abbc
Forneça um algoritmo que encontre o número de resultados exclusivos que você pode obter quando cada variável for substituída por "0" ou "1" em todas as fórmulas.
Existem (k!)^2
fórmulas, cada uma com 2k-1
variáveis e k^2
termos. Expresse seus assintóticos em termos de k
.
O algoritmo mais rápido vence. Em caso de empate, a solução com menor uso de memória assintótica vence. Se ainda houver empate, o primeiro post vence.
Para o exemplo acima, os seguintes resultados podem ser obtidos substituindo as variáveis:
1110, 0110, 1001, 0100, 1000, 0000, 0010, 1101, 1111, 0001, 1011, 0111
Portanto, a resposta correta é 12. Entre outras, 1010
não pode ser feita usando as fórmulas acima.
Fiz mais três casos de teste, com as respectivas soluções de 230 , 12076 e 1446672 .
a
,b
... é uma variável ? E sempre temos apenas um número desigual de variáveis? Não importa quanto tempo a sequência de variáveis é e quantas fórmulas são dadas?Respostas:
Mathematica, tempo O (k ^ 2 (k!) ^ 2)
Espero ter calculado a complexidade do tempo corretamente. Entrada é uma lista de fórmulas como
{"bacb","bcab","cbba","abbc"}
. É executado em menos de 30 segundos para cada caso de teste na minha máquina, mas quem se importa com os tempos absolutos?Explicação:
&
no final a torna uma função pura, com#
referência ao primeiro argumento,#2
sendo o segundo argumento, etc.Length[*..*]
ocupa o comprimento da lista contida nela.Union@@(*..*)
pega a lista contida e a fornece como argumentos paraUnion
, que retorna uma lista dos elementos exclusivos em qualquer um de seus argumentos.*..*&/@#
assume uma função pura e mapeia-a sobre a lista de fórmulas, para que{a,b,c}
se torne{f[a],f[b],f[c]}
. Observe que nas funções puras aninhadas,#n
refere-se aos seus argumentos mais internos.Fold[*..*&,#,*..*]
pega uma função acumuladora, valor inicial e lista, e retornaf[f[...[f[starting value,l_1],l_2],...],l_n]
.Union[Characters[#]]
pega todos os caracteres da fórmula atual e obtém todos os elementos exclusivos, fornecendo as variáveis.Flatten[*..*]
achata seu argumento, de modo que{{{a},b},{{c,{d}}}}
se torna{a,b,c,d}
.{*..*,*..*}
é simplesmente uma maneira de combinar os dois resultados usando o descrito acimaFlatten
.StringReplace[#,#2->"0/1"]
pega o resultado anterior e o retorna com a variável atual substituída por0
ou1
.fonte
k
como variável no seu tempo? Ainda assim, tempo fatorial! Ufa!k
". Além disso, eu tive que fazer umGeneralUtilities`Benchmark
para cada método usado.