Gerrymandering con Logic Gates


16

La funzione maggioritaria è una funzione booleana che accetta tre input booleani e restituisce il più comune. Ad esempio, se maj(x,y,z)è la funzione maggioritaria e Tindica vero e Findica falso, allora:

maj(T,T,T) = T
maj(T,T,F) = T
maj(T,F,F) = F
maj(F,F,F) = F

Questa domanda riguarda la scrittura di funzioni booleane come composizioni di funzioni maggioritarie. Un esempio di una composizione a 5 livelli delle funzioni maggioritarie è (x1,x2,x3,x4,x5) => maj(x1,x2,maj(x3,x4,x5)). Questa funzione restituisce il seguente output su questi vettori di input di esempio:

(T,T,F,F,F) => maj(T,T,maj(F,F,F)) = maj(T,T,F) = T
(T,F,T,T,F) => maj(T,F,maj(T,T,F)) = maj(T,F,T) = T
(T,F,T,F,F) => maj(T,F,maj(T,F,F)) = maj(T,F,F) = F
(F,F,F,T,T) => maj(F,F,maj(F,T,T)) = maj(F,F,T) = F

Compito

Scrivere un programma che inserisca un numero intero positivo n e un elenco di n lunghezza di vettori di valori booleani e produca un albero di porte maggioritarie che ritorni vero su tutti i vettori dati, se possibile. La funzione può restituire vero o falso su vettori non nell'elenco dei vincoli.

  • L'elenco dei vettori può essere inserito in qualsiasi formato desiderato. Se preferisci, invece di inserire il vettore, puoi inserire l'elenco delle posizioni reali nel vettore. Quindi, per esempio, [TTF,TFT,FTT]oppure [[T,T,F],[T,F,T],[F,T,T]]oppure [[1,2],[1,3],[2,3]](elenco di posizioni vere) vanno bene.

  • L'output può essere in qualsiasi formato di albero valido. Ad esempio, maj(maj(x1,x2,x3),x4,x5)funziona. Probabilmente vorrai usare numeri singoli come stand-in per variabili, come in [[1,2,3],4,5]. Anche lo smalto inverso 123m45mva bene, per esempio.

  • Se non è presente alcuna funzione, il programma dovrebbe generare un errore o generare un valore di falso.

  • Se ci sono più funzioni che funzionano, il tuo programma può restituire una qualsiasi di esse. Non è necessario semplificare la funzione. Ad esempio, maj(x1,x1,x2)o x1sono equivalenti.

punteggio

Questo è il codice golf: vince la soluzione più breve in byte.

Casi test:

Si noti che ci sono molti output possibili per ciascuno di questi casi, quindi è necessario scrivere uno script checker che converte l'output in una funzione e verificare che la funzione restituisca true su ciascuno dei vettori di input specificati.

Input: 3, [TFF]
Output: 1 or [1,1,2] or [1,[1,2,2],[1,1,3]] or other equivalent

Input: 3, [TFF,FTF]
Output: Falsey or error (it's not possible)

Input: 3, [TTF,TFT]
Output: [1,2,3] or 1 or other equivalent

Input: 3, [TTF,TFT,FTT]
Output: [1,2,3] or [1,3,2] or other equivalent

Input: 4, [TTFF,TFTF,FFTT]
Output: Falsey or error

Input: 4, [TTTF,TTFT,TFTT,FTTT]
Output: [1, 2, 3] or [2,3,4], or many other options

Input: 5, [TTTFF,FTTFT,TFFFT]
Output: [1,[1,[1,2,5],[2,4,5]],3] or many other options 

Input: 6, [TTTFFF,FTFTTF,TFFTFT]
Output: [1, 2, 4] or [1, [1, 2, 4], [2, 3, 4]] or others

Input: 5, [TTTFF,TTFTF,TTFFT,TFTTF,TFTFT,TFFTT,FTTTF,FTTFT,FTFTT,FFTTT]
Output: [[1, [1, 3, 5], 4], [1, 2, [2, 4, 5]], [2, 3, [3, 4, 5]]] or others

Input: 7, [TTTTFFF,TTTFTFF,TTTFFTF,TTTFFFT,TTFTTFF,TTFTFTF,TTFTFFT,TTFFTTF,TTFFTFT,TTFFFTT,TFTTTFF,TFTTFTF,TFTTFFT,TFTFTTF,TFTFTFT,TFTFFTT,TFFTTTF,TFFTTFT,TFFTFTT,TFFFTTT,FTTTTFF,FTTTFTF,FTTTFFT,FTTFTTF,FTTFTFT,FTTFFTT,FTFTTTF,FTFTTFT,FTFTFTT,FTFFTTT,FFTTTTF,FFTTTFT,FFTTFTT,FFTFTTT,FFFTTTT]
Output: [[[1, [1, [1, 4, 7], 6], 5], [1, [1, 3, [3, 6, 7]], [3, 5, [5, 6, 7]]], [3, 4, [4, [4, 5, 7], 6]]], [[1, [1, [1, 4, 7], 6], 5], [1, 2, [2, [2, 5, 7], 6]], [2, [2, 4, [4, 6, 7]], [4, 5, [5, 6, 7]]]], [[2, [2, [2, 4, 7], 6], 5], [2, 3, [3, [3, 5, 7], 6]], [3, [3, 4, [4, 6, 7]], [4, 5, [5, 6, 7]]]]]

"La composizione 5-ary delle funzioni maggioritarie è (x1, x2, x3, x4, x5) => maj (x1, x2, maj (x3, x4, x5))" come? Quale dovrebbe essere la risposta se x1 = x2 = F; x3 = x4 = x5 = T; ?
tsh

Aggiungerò una tabella di verità.
Hood

1
Cosa significa un output di 1?
Mhmd

2
Titolo suggerito: Gerrymandering con porte logiche
Robert Fraser

1
@trichoplax No, l'output su tutti i vettori rimanenti può essere qualsiasi cosa. Aggiornerò per renderlo esplicito.
Cappuccio

Risposte:


2

JavaScript (ES6), 260 byte

Accetta input come una matrice di array di valori booleani. Restituisce un albero di porte a maggioranza indicizzata 1 o genera un errore di ricorsione (1) se non esiste una soluzione.

La funzione principale f () tenta ricorsivamente di trovare una soluzione chiamando il solutore F () e incrementando il livello massimo di annidamento m ad ogni iterazione.

(1) dopo a molto tempo e assumendo memoria infinita

f=(a,m)=>(F=(a,d,I=a[i=0].map(_=>++i),g=(a,b)=>b[1]?b.reduce((s,i)=>s+g(a,i),0)>1:a[b-1])=>I.find(i=>a.every(a=>g(a,i)))||d&&(I.reduce((a,x)=>[...a,...a.map(y=>[...y,x])],[[]]).some(b=>r=b.length==3&&F(a.map(a=>[...a,g(a,b)]),d-1,[...I,b]))&&r))(a,m)||f(a,-~m)

dimostrazione

Esempio

Di seguito è riportata una tabella di convalida della soluzione trovata per l'ultimo caso di test della demo.

12345 | [5,[1,2,4],[3,4,[1,2,3]]]
------+-------------------------------------------------------------
TTTFF | [F,[T,T,F],[T,F,[T,T,T]]] --> [F,T,[T,F,T]] -> [F,T,T] --> T
TTFTF | [F,[T,T,T],[F,T,[T,T,F]]] --> [F,T,[F,T,T]] -> [F,T,T] --> T
TTFFT | [T,[T,T,F],[F,F,[T,T,F]]] --> [T,T,[F,F,T]] -> [T,T,F] --> T
TFTTF | [F,[T,F,T],[T,T,[T,F,T]]] --> [F,T,[T,T,T]] -> [F,T,T] --> T
TFTFT | [T,[T,F,F],[T,F,[T,F,T]]] --> [T,F,[T,F,T]] -> [T,F,T] --> T
TFFTT | [T,[T,F,T],[F,T,[T,F,F]]] --> [T,T,[F,T,F]] -> [T,T,F] --> T
FTTTF | [F,[F,T,T],[T,T,[F,T,T]]] --> [F,T,[T,T,T]] -> [F,T,T] --> T
FTTFT | [T,[F,T,F],[T,F,[F,T,T]]] --> [T,F,[T,F,T]] -> [T,F,T] --> T
FTFTT | [T,[F,T,T],[F,T,[F,T,F]]] --> [T,T,[F,T,F]] -> [T,T,F] --> T
FFTTT | [T,[F,F,T],[T,T,[F,F,T]]] --> [T,F,[T,T,F]] -> [T,F,T] --> T

C'è una soluzione efficiente, che si spera che qualcuno troverà. Nel frattempo, immagino che una specie di forza bruta lavori ...
Hood,

2

Mathematica, 121 byte

Una funzione anonima che prende il suo secondo argomento come un elenco degli elenchi di posizioni vere nel vettore dei booleani.

f[n_][s_]:=If[n<3,(Intersection@@s)[[1]],{#/. 2->1,#2/.{2->1,3->2},#3}&@@(1+f[n-1]/@(s-1/.{{0->1},{1->2,0->1},{0->2}}))]

Formattato leggermente più bello:

f[n_][s_] := If[n < 3, (Intersection @@s)[[1]],
   {# /. 2 -> 1, #2 /. {2 -> 1, 3 -> 2}, #3} & @@ 
    (1 + f[n - 1] /@ (s - 1 /. {{0 -> 1}, {1 -> 2, 0 -> 1}, {0 -> 2}}))]

Se ci sono meno di tre variabili, interseca i vettori del vincolo per vedere se esiste un "Vero" comune in tutti i vincoli. Se ce n'è uno, allora la funzione costante (x_1, x_2) -> x_i funziona, altrimenti è impossibile (e genererà un errore cercando di prendere il primo elemento di un elenco vuoto).

Altrimenti, sostituire f1=f(x1,x1,x2,x3,,xn1) , f2=f(x1,x2,x2,x3,,xn1) , ed f3=f(x1,x2,x1,x3,,xn1)) x n , risolvi ricorsivamente ciascuno di questi, quindi impostaf=maj(f1(x1,x3,x4,,xn),f2(x1,x2,x4,,xn),f2(x2,x3,x4,,xn)) .

Spiegazione:

Questo è un algoritmo ricorsivo che riduce il problema di trovare una soluzione di un problema n variabile alla ricerca di tre soluzioni per n1 problemi variabili. L'osservazione chiave che fa funzionare questo è che per f una delle funzioni che stiamo cercando abbiamo: f(x1,,xn)=maj(f(x1,x1,x3,x4,,xn),f(x1,x2,x2,),f(x3,x2,x3,))

x2x1x3x2x1x3 .

f(x1,x1,x3,x4,,xn)f(x1,x2,x2,x4,,xn), and f(x3,x2,x3,x4,,xn)) and take the majority of them.

Why is this true? Well the majority function satisfies two properties:

  1. It is "complementary". That is, if !x is the negation of x, then maj(!x,!y,!z)=!maj(x,y,z). As a consequence, every function we can build out of the majority function is complementary.

  2. It is monotonic. That is, maj(x,y,False)maj(x,y,True). In general, if we say that FalseTrue and say (x1,,xn)(y1,,yn) if xiyi for all i, then I say a function f is monotonic if (x1,xn)(y1,,yn) implies f(x1,xn)f(y1,,yn). The composition of monotonic functions is monotonic so every function we can build out of the majority function is monotonic.

It turns out that complementary monotonic functions are exactly the class of functions that can be built out of majority gates.

Now, we show that for f a complementary monotonic function, our identity holds: f(x1,,xn)=maj(f(x1,x1,x3,x4,,xn),f(x1,x2,x2,x4,,xn),f(x3,x2,x3,x4,,xn))

Let's set f1(x1,x2,x3,,xn)=f(x1,x1,x3,x4,,xn), f2(x1,,xn)=f(x1,x2,x2,x4,,xn) and f3(x1,,xn)=f(x3,x2,x3,x4,,xn). To show that f=maj(f1,f2,f3), we need to show that for any input, at least two of f1, f2, and f3 are equal to f. We divide up into cases based on the values of x1, x2 and x3. If x1=x2=x3 then f1=f2=f3=f.

Suppose not all of x1, x2, and x3 are the same. By permuting the variables of f, we can assume that x1=x2 and x3 is different and because f is complementary, it suffices to deal with the case x1=x2=False and x3=True. In this case, (x1,x1,x3)=(False,False,True)=(x1,x2,x3), (x1,x2,x2)=(False,False,False)(x1,x2,x3) and (x3,x2,x3)=(True,False,True)(x1,x2,x3). By monotonicity we deduce that f2f1=ff3. If f=False then f2False implies f2=False=f and if f=True then f3True implies f3=True. Thus, at least two of f1, f2, and f3 are equal to f in all cases so f=maj(f1,f2,f3).

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.