Gerrymandering com Logic Gates


16

A função majoritária é uma função booleana que recebe três entradas booleanas e retorna a mais comum. Por exemplo, se maj(x,y,z)é a função majoritária e Tdenota verdadeiro e Fdenota falso, então:

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

Esta questão diz respeito à escrita de funções booleanas como composições das funções majoritárias. Um exemplo de uma composição de 5 árias de funções majoritárias é (x1,x2,x3,x4,x5) => maj(x1,x2,maj(x3,x4,x5)). Esta função retorna a seguinte saída nesses vetores de entrada de amostra:

(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

Tarefa

Escreva um programa que insira um número inteiro positivo n e uma lista de vetores de comprimento n de booleanos e produza uma árvore de portas majoritárias que retorne true em todos os vetores fornecidos, se possível. A função pode retornar verdadeiro ou falso em vetores que não estão na lista de restrições.

  • A lista de vetores pode ser inserida em qualquer formato que você desejar. Se preferir, em vez de inserir o vetor, você pode inserir a lista de posições verdadeiras no vetor. Por exemplo, [TTF,TFT,FTT]ou [[T,T,F],[T,F,T],[F,T,T]]ou [[1,2],[1,3],[2,3]](lista de posições verdadeiras) estão bem.

  • A saída pode ser qualquer formato de árvore válido. Por exemplo, maj(maj(x1,x2,x3),x4,x5)funciona. Você provavelmente desejará usar números únicos como substitutos para variáveis, como em [[1,2,3],4,5]. O polimento reverso 123m45mtambém é bom, por exemplo.

  • Se não houver nenhuma função que funcione, seu programa deve gerar um erro ou gerar um valor falsey.

  • Se houver várias funções que funcionem, seu programa poderá retornar qualquer uma delas. A função não precisa ser simplificada. Por exemplo, maj(x1,x1,x2)ou x1são equivalentes.

Pontuação

Este é o código golf: A solução mais curta em bytes vence.

Casos de teste:

Observe que existem muitas saídas possíveis para cada um desses casos, portanto, você deve escrever um script verificador que converta sua saída em uma função e verifique se sua função retorna verdadeira em cada um dos vetores de entrada especificados.

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]]]]]

"A composição em 5 árias das funções majoritárias é (x1, x2, x3, x4, x5) => maj (x1, x2, maj (x3, x4, x5))" como? Qual deve ser a resposta se x1 = x2 = F; x3 = x4 = x5 = T; ?
tsh

Vou adicionar uma tabela de verdade.
Hood

1
O que significa uma saída 1?
Mhmd

2
Título sugerido: Gerrymandering com portas lógicas
Robert Fraser

1
@trichoplax Não, a saída em todos os vetores restantes pode ser qualquer coisa. Vou atualizar para tornar isso explícito.
Hood

Respostas:


2

JavaScript (ES6), 260 bytes

Recebe entrada como uma matriz de matrizes de booleanos. Retorna uma árvore de portas majoritárias 1 indexadas ou gera um erro de recursão (1) se não houver solução.

A função principal f () tenta recursivamente encontrar uma solução chamando o solucionador F () e aumentando o nível máximo de aninhamento m a cada iteração.

(1) depois de muito tempo, e assumindo memória 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)

Demo

Exemplo

Abaixo está uma tabela de validação da solução encontrada para o último caso de teste da demonstração.

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

Existe uma solução eficiente, que espero que alguém encontre. Enquanto isso, acho que a força bruta funciona ...
Hood

1

Mathematica, 121 bytes

Uma função anônima que usa seu segundo argumento como uma lista das listas de posições verdadeiras no vetor de booleanos.

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}}))]

Formatado um pouco melhor:

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 houver menos de três variáveis, intercepte os vetores de restrição para ver se há um "True" comum em todas as restrições. Se houver uma, a função constante (x_1, x_2) -> x_i funciona, caso contrário, é impossível (e gerará um erro ao tentar obter o primeiro elemento de uma lista vazia).

f1=f(x1,x1,x2,x3,,xn1)f2=f(x1,x2,x2,x3,,xn1)f3=f(x1,x2,x1,x3,,xn1))f=maj(f1(x1,x3,x4,,xn),f2(x1,x2,x4,,xn),f2(x2,x3,x4,,xn)) .

Explicação:

nn1ff(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)f(x3,x2,x3,x4,,xn))

Por que isso é verdade? Bem, a função majoritária satisfaz duas propriedades:

  1. !xxmaj(!x,!y,!z)=!maj(x,y,z)

  2. maj(x,y,False)maj(x,y,True)FalseTrue(x1,,xn)(y1,,yn)xiyiif(x1,xn)(y1,,yn)f(x1,xn)f(y1,,yn). A composição das funções monotônicas é monotônica; portanto, toda função que podemos construir a partir da função majoritária é monotônica.

Acontece que funções monotônicas complementares são exatamente a classe de funções que podem ser construídas a partir dos portões majoritários.

ff(x1,,xn)=maj(f(x1,x1,x3,x4,,xn),f(x1,x2,x2,x4,,xn),f(x3,x2,x3,x4,,xn))

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).

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.