Геррімандерінг з логічними воротами


16

Функція більшості - булева функція, яка займає три булеві входи і повертає найпоширеніші. Наприклад, якщо maj(x,y,z)функція більшості і Tпозначає істинну, а Fтоді позначає помилкову:

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

Це питання стосується написання булевих функцій як композицій більшості функцій. Прикладом 5-арного складу більшості функцій є (x1,x2,x3,x4,x5) => maj(x1,x2,maj(x3,x4,x5)). Ця функція повертає наступний вихід на цих вхідних векторах вибірки:

(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

Завдання

Напишіть програму, яка вводить додатне ціле число n та список довжини n векторів булевих знаків та виводить дерево воріт більшості, яке, якщо можливо, повертає істинні значення для всіх заданих векторів. Функція може повертати істинну або хибну для векторів, які не є у списку обмежень.

  • Список векторів може бути введений у будь-якому форматі, який вам подобається. Якщо ви хочете, замість введення вектора, ви можете ввести список справжніх позицій у векторі. Так, наприклад, [TTF,TFT,FTT]або[[T,T,F],[T,F,T],[F,T,T]] або [[1,2],[1,3],[2,3]](список справжніх позицій) все добре.

  • Вихідним може бути будь-який дійсний формат дерева. Наприклад, maj(maj(x1,x2,x3),x4,x5)працює. Ви, ймовірно, захочете використовувати одиничні числа як очікування змінних, як у[[1,2,3],4,5] . 123m45mНаприклад, зворотний лак також нормальний.

  • Якщо функція не працює, ваша програма повинна генерувати помилку або виводити значення фальси.

  • Якщо працює кілька функцій, програма може повернути будь-яку з них. Функцію не потрібно спрощувати. Наприклад, maj(x1,x1,x2)або x1еквівалентні.

Оцінка балів

Це код гольфу: найкоротше рішення в байтах.

Тестові приклади:

Зауважте, що існує багато можливих результатів для кожного з цих випадків, тому слід написати контрольний скрипт, який перетворює ваш вихід у функцію та перевіряє, чи функція повертає справжнє на кожному із зазначених вхідних векторів.

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

"5-арний склад більшості функцій (x1, x2, x3, x4, x5) => maj (x1, x2, maj (x3, x4, x5))" "як? Якою має бути відповідь, якщо x1 = x2 = F; x3 = x4 = x5 = T; ?
тш

Я додам таблицю правдивості.
Гуд

1
Що означає вихід 1?
Mhmd

2
Запропонована назва: Геррімандерінг з логічними воротами
Роберт Фрейзер

1
@trichoplax Ні, вихід на всі решта векторів може бути будь-яким. Я оновлю, щоб зробити це явним.
Гуд

Відповіді:


2

JavaScript (ES6), 260 байт

Приймає введення як масив масивів булевих. Повертає дерево з 1-проіндексованими воротами більшості або видає помилку рекурсії (1), якщо рішення не існує.

Основна функція f () рекурсивно намагається знайти рішення шляхом виклику розв'язувача F () та збільшення максимального рівня гніздування m при кожній ітерації.

(1) через тривалий час і припускаючи нескінченну пам'ять

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)

Демо

Приклад

Нижче наводиться таблиця перевірки рішення, знайденого для останнього тестового випадку демонстрації.

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

Є ефективне рішення, яке, сподіваємось, хтось знайде. Тим часом, я здогадуюсь, груба сила працює ...
Гуд

2

Математика, 121 байт

Анонімна функція, яка приймає другий аргумент як перелік списків справжніх позицій у векторі булевих.

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

Відформатований трохи приємніше:

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

Якщо є менше трьох змінних, перехрестіть вектори обмежень, щоб побачити, чи є загальне "Істинне" у всіх обмеженнях. Якщо така є, то функція постійної (x_1, x_2) -> x_i працює, інакше це неможливо (і викине помилку, намагаючись взяти перший елемент порожнього списку).

В іншому випадку, підставляємо 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)).

Пояснення:

Це рекурсивний алгоритм, який зменшує задачу пошуку рішення n змінної задачі до пошуку трьох рішень для n1 змінних задач. Основне зауваження, що робить цю роботу, полягає в тому, що для f однієї з функцій, яку ми шукаємо, ми маємо: f(x1,,xn)=maj(f(x1,x1,x3,x4,,xn),f(x1,x2,x2,),f(x3,x2,x3,))

У першому положенні ми замінили x2 на x1 , у другому - x3 на x2 а в третьому - x1 на x3 .

Як тільки ви дізнаєтесь цю ідентичність, алгоритм стає зрозумілим: коли є дві або менше змінних, проблема є тривіальною. В іншому випадку рекурсивно вирішуйте три задачі представлення f(x1,x1,x3,x4,,xn) , f(x1,x2,x2,x4,,xn) та f(x3,x2,x3,x4,,xn)) і візьміть більшість із них.

Чому це правда? Ну функція більшості задовольняє дві властивості:

  1. Це "взаємодоповнюючий характер". Тобто, якщо !x є запереченням x , то maj(!x,!y,!z)=!maj(x,y,z) . Як наслідок, кожна функція, яку ми можемо побудувати з функції більшості, є взаємодоповнювальною.

  2. Це монотонно. Тобто maj(x,y,False)maj(x,y,True) . Загалом, якщо сказати, що FalseTrue і скажемо (x1,,xn)(y1,,yn) якщоxiyi для всіхi , то я кажу, що функціяf є монотонною, якщо(x1,xn)(y1,,yn) означаєf(x1,xn)f(y1,,yn). Склад монотонних функцій є монотонним, тому кожна функція, яку ми можемо побудувати з функції більшості, є монотонною.

Виявляється, що комплементарні монотонні функції - це саме той клас функцій, який можна побудувати з воріт більшості.

Тепер ми покажемо, що для f комплементарної монотонної функції наша тотожність справедлива: f(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)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).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.