Задание №2 — Построение таблицы истинности
Миша заполнял таблицу истинности функции но успел заполнить лишь фрагмент из трёх различных её строк, даже не указав, какому столбцу таблицы соответствует каждая из переменных w, x, y, z.
| 1 | 1 | 1 | ||
| 0 | 1 | 0 | 1 | |
| 1 | 1 | 0 | 1 |
Определите, какому столбцу таблицы соответствует каждая из переменных w, x, y, z. В ответе напишите буквы w, x, y, z в том порядке, в котором идут соответствующие им столбцы (сначала буква, соответствующая первому столбцу; затем буква, соответствующая второму столбцу, и т.д.). Буквы в ответе пишите подряд, никаких разделителей между буквами ставить не нужно.
Пример. Функция задана выражением зависящим от двух переменных, а фрагмент таблицы имеет следующий вид.
| 0 | 1 | 0 |
В этом случае первому столбцу соответствует переменная y, а второму столбцу – переменная x. В ответе следует написать yx.
Правильный ответ
zyxw
Пояснение
Решение:
Функция зависит от четырёх переменных, поэтому её полная таблица истинности содержит строк, а расставить переменные w, x, y, z по четырём столбцам можно способами.
Найдём все наборы, на которых . Таких наборов всего три (значения записаны в «алфавитном» порядке ):
| w | x | y | z | F |
|---|---|---|---|---|
| 0 | 0 | 1 | 0 | 1 |
| 0 | 1 | 0 | 1 | 1 |
| 0 | 1 | 1 | 0 | 1 |
Значит, каждая строка фрагмента — это одна из этих трёх строк, только с переставленными столбцами. Но в каком порядке идут сами строки фрагмента, неизвестно, поэтому соответствие «столбец → переменная» надёжнее всего установить перебором всех 24 расстановок.
Отдельно обратим внимание на условие: строки фрагмента различны. Это не украшение: если его не учитывать, подходящих расстановок получается 2. Поэтому проверка расстановки такая: для каждой строки фрагмента находим все её дополнения, дающие нужное значение , и убеждаемся, что из этих дополнений можно выбрать попарно различные строки.
Всё это удобно поручить программе. В Python эквиваленция — это a == b.
from itertools import product, permutations
def F(w, x, y, z):
return int(((x or y) and (not (y == z))) and (not w))
# фрагмент таблицы: '.' — незаполненная клетка, второе число — значение F
frag = [('1.1.', 1),
('01.0', 1),
('.110', 1)]
def fits(mask, vals):
return all(m == '.' or int(m) == v for m, v in zip(mask, vals))
for p in permutations('wxyz'):
# для каждой строки фрагмента — все её допустимые дополнения
variants = []
for mask, f in frag:
variants.append([vals for vals in product((0, 1), repeat=4)
if fits(mask, vals) and F(**dict(zip(p, vals))) == f])
# строки фрагмента должны быть попарно различны
for lines in product(*variants):
if len(set(lines)) == len(lines):
print(''.join(p))
break
Программа печатает единственную расстановку — zyxw.
Проверим её вручную. Столбцы идут в порядке ; восстановим пустые клетки (восстановленные значения выделены курсивом):
| z | y | x | w | F |
|---|---|---|---|---|
| 1 | 0 | 1 | 0 | 1 |
| 0 | 1 | 0 | 0 | 1 |
| 0 | 1 | 1 | 0 | 1 |
Все строки различны, известные клетки совпадают с фрагментом, и функция на них принимает требуемые значения — расстановка найдена верно.
Ответ: zyxw