Numero di output univoci sostituendo le variabili


9

Dato un insieme di formule come questa:

bacb
bcab
cbba
abbc

Fornisci un algoritmo che trova il numero di risultati univoci che puoi ottenere quando ogni variabile viene sostituita da "0" o "1" in ogni formula.

Ci sono (k!)^2formule, ognuna con 2k-1variabili e k^2termini. Esprimi i tuoi asintotici in termini di k.

Vince l'algoritmo più veloce. In caso di pareggio, la soluzione con un utilizzo di memoria asintotica inferiore vince. Se questo è ancora un pareggio, il primo post vince.


Per l'esempio sopra, è possibile acquisire i seguenti risultati sostituendo le variabili:

1110, 0110, 1001, 0100, 1000, 0000, 0010, 1101, 1111, 0001, 1011, 0111

Quindi la risposta corretta è 12. Tra l'altro, 1010non può essere fatto usando le formule sopra.

Ho realizzato altri tre casi di test, con rispettive soluzioni di 230 , 12076 e 1446672 .


Chiarimento: qual è k nella domanda? È solo una costante astratta?
isaacg,

@isaacg Sì. È per evitare legami tra soluzioni più veloci per formule meno grandi ma più grandi, per esempio.
orlp,

Quindi ogni lettera a, b... è una variabile ? E abbiamo sempre solo un numero irregolare di variabili? Non importa quanto è lunga la sequenza di variabili e su quante formule ti vengono date?
Flawr,

@flawr La relazione esatta tra il numero di variabili, il numero di termini e il numero di formule è data nella domanda.
orlp,

'Può essere' significa che puoi ottenere fino a $ (k!) ^ 2 $ formule o ci sono esattamente $ (k!) ^ 2 $ formule? Oltre a ciò, hai qualche domanda per un algoritmo con quelle specifiche? Lo sto solo chiedendo perché le specifiche sembrano essere abbastanza arbitrarie.
Flawr,

Risposte:


2

Mathematica, O (k ^ 2 (k!) ^ 2) tempo

Length[Union@@(Fold[Flatten[{StringReplace[#,#2->"0"],StringReplace[#,#2->"1"]}]&,#,Union[Characters[#]]]&/@#)]&

Spero di aver calcolato correttamente la complessità temporale. L'input è un elenco di formule come {"bacb","bcab","cbba","abbc"}. Funziona in meno di 30 secondi per ogni caso di test sulla mia macchina, ma a chi importa dei tempi assoluti?

Spiegazione:

  • Prima di tutto, &alla fine lo rende una funzione pura, con #riferimento al primo argomento, #2essendo il secondo argomento, ecc.
  • Length[*..*] prende la lunghezza dell'elenco contenuto al suo interno.
  • Union@@(*..*)prende l'elenco contenuto e lo fornisce come argomento per Union, che restituisce un elenco degli elementi univoci in uno dei suoi argomenti.
  • *..*&/@#prende una funzione pura e la mappa sulla lista delle formule, così {a,b,c}diventa {f[a],f[b],f[c]}. Si noti che nelle funzioni pure annidate, si #nriferisce ai suoi argomenti più interni.
  • Fold[*..*&,#,*..*]accetta una funzione di accumulatore, un valore iniziale, un elenco e restituisce f[f[...[f[starting value,l_1],l_2],...],l_n].
  • Union[Characters[#]] prende tutti i caratteri nella formula corrente e ottiene tutti gli elementi unici, dandoci le variabili.
  • Flatten[*..*]appiattisce il suo argomento, così {{{a},b},{{c,{d}}}}diventa {a,b,c,d}.
  • {*..*,*..*}è semplicemente un modo per combinare i due risultati usando quanto sopra Flatten.
  • StringReplace[#,#2->"0/1"]prende il risultato precedente e lo restituisce con la variabile corrente sostituita con 0o 1.

Perché stai usando kcome variabile nel tuo tempo? Comunque, tempo fattoriale! Accidenti!
theonlygusti,

L'op ha detto: "Esprimi i tuoi asintotici in termini di k". Inoltre, ho dovuto fare un GeneralUtilities`Benchmarkper ogni metodo utilizzato.
LegionMammal978,

Vuoi aggiungere una semplice descrizione in inglese del tuo algoritmo? Non ho familiarità con Mathematica, quindi non posso verificare la tua soluzione.
orlp,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.