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.