Давши таблицю правдивості, виведіть програму Stackylogic, яка її задовольняє


17

Stackylogic - мова програмування, яку я склав у попередньому виклику: Run Stackylogic . Прочитайте цю публікацію для отримання детальної інформації та прикладів, але ось як це перефразовано працює:

Stackylogic приймає 0's і 1' для введення та виведення єдиного 0 або 1після завершення.

Програма складається з рядків, які містять лише символи 01?, а також точно одного <в кінці одного з рядків. Лінії не можуть бути порожніми і лінія з <повинна мати принаймні один 0, 1або ?перед ним.

Ось зразок програми, яка обчислює NAND з двох біт:

1
?<
11
?
0

Кожен рядок програми вважається стеком , нижній зліва та верхній праворуч. Безпосередньо перед першим рядком програми та після останнього рядка є порожній стек (тобто порожній рядок).

<, Названий курсором, зазначає стек , щоб почати при запуску програми. Виконання триває наступним чином:

  1. Спустіть верхній символ із стека, на який вказує курсор.

    • Якщо символ є ?, запропонуйте користувачеві a 0або a 1і діяти так, як ніби це був символ.
    • Якщо символ є 0, перемістіть курсор на один стек вгору (до рядка над поточним рядком).
    • Якщо символ є 1, перемістіть курсор на одну стек вниз (до рядка нижче поточного рядка).
  2. Якщо стек, на який рухається курсор, порожній, виведіть останнє значення, яке вискочило з стека (завжди a 0або 1), і закінчіть програму.

  3. В іншому випадку, якщо стек, на який рухається курсор, не порожній, поверніться до кроку 1 і повторіть процес.

Ключове, що потрібно усвідомити для цього виклику - це те, що всі програми Stackylogic прирівнюються до таблиці істинності . Деякі заздалегідь задані кількості булевих значень вводяться, і рівно один булевий показник детерміновано виводиться.

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

Базова справа

Ці дві таблиці 0-вхід істина таблиці , які завжди виводяться 0або 1. Стаклогічні еквіваленти цих таблиць є 0<і 1< відповідно.

Індуктивний крок

Припустимо, що Stackylogic може імітувати будь-яку таблицю істинності N-вводу. Нехай M = N + 1.

Таблиця M-введення, T, може бути виражена у вигляді двох N-вхідних таблиць, T 0 і T 1 , плюс додатковий вхідний біт B. Коли B дорівнює 0, використовується результат T 0 . Коли B дорівнює 1, використовується результат T 1 .

Наприклад, 3-вхідна таблиця правдивості, що відповідає псевдокоду

if B:
    result = x OR y
else:
    result = x NAND y

є

B x y | result
0 0 0 | 1
0 0 1 | 1
0 1 0 | 1
0 1 1 | 0
1 0 0 | 0
1 0 1 | 1
1 1 0 | 1
1 1 1 | 1

що насправді дві таблиці істинності 2-вхідних даних для NAND та АБО, складених на вершині один одного за допомогою муксирующего біта B.

Нехай S 0 і S 1 - програми Стаккілогіки, які задовольняють T 0 і T 1 відповідно (ми знаємо, що вони існують на основі першого припущення). Програма S, яка задовольняє T, може бути побудована як:

[lines of S0 excluding the cursor, with 0 appended to all lines below the cursor]
?<
[lines of S1 excluding the cursor, with 1 appended to all lines above the cursor]

Це розташування ефективно змінюється між S 0 і S 1 на основі першого вхідного біта (з рядка ?<). Якщо це так 0, курсор поверне додане 0до початкового положення курсору S 0 , яке потім буде межене порожніми стеками та знизу, і таким чином виконати точно ідентично вихідному S 0 . Так само, якщо 1вводиться, курсор буде їздити 1вниз до положення курсора S 1 і продовжує виконувати його так, як ніби він був один.

Наприклад, програми Stackylogic для АБО та NAND є

?
?<

і

1
?<
11
?
0

Їх можна комбінувати для імітації

if B:
    result = x OR y
else:
    result = x NAND y

так:

1
?
110
?0
00
0
?<
?1
?

Таким чином, будь-яка таблиця істинності може бути змодельована програмою Stackylogic.

Виклик

Напишіть програму або функцію, яка приймає таблицю істинності N вхідних даних (N> 0) у вигляді списку 2 N булевих значень, які представляють результати таблиці в бінарному порядку.

Будь-який розумний формат введення в порядку. наприклад для таблиці АБО ІСТИНИ

x y | OR
0 0 | 0
0 1 | 1
1 0 | 1
1 1 | 1

будь-який із цих стилів введення буде добре:

0111

0, 1, 1, 1

0
1
1
1

[False, True, True, True]

Роздрукуйте або поверніть програму Stackylogic, яка задовольняє таблицю істинності, тобто має точно той же вихід, що заданий тим самим входом. Будь-яка кінцева програма, яка задовольняє цій таблиці, є дійсним результатом. Не потрібно дотримуватися методу побудови індуктивного доказу. Програми Stackylogic не повинні бути оптимально короткими.

Наприклад, якби вхід був 11100111, був би один дійсний вихід

1
?
110
?0
00
0
?<
?1
?

але є багато інших.

Виграє найкоротший код у байтах.

Дивіться оригінальний виклик Stackylogic, якщо вам потрібен перекладач.


Чи можемо ми прийняти N як другий вхід?
Leaky Nun

@LeakyNun Так (або 2 ^ N), якщо потрібно.
Захоплення Кальвіна

Відповіді:


8

Pyth, 53 байти

L?tb,lehJyMc2bsX0.e.e+W>_Wk-Yhb0ZkebJ\?,0]`hbjXF+yQ\<

Спробуйте в Інтернеті

Це точна реалізація системи, описаної в виклику щодо того, як реалізувати довільні таблиці істинності в Stackylogic. Ми просто розрізаємо таблицю істини навпіл, реалізуємо її рекурсивно, а потім додаємо 0 і 1, як потрібно.

Це визначає рекурсивну функцію, значення якої повертається [1, ['0', '?', '1']], де перше число - це місце вказівника, а решта - стакілогічна програма.

L?tb,lehJyMc2bsX0.e.e+W>_Wk-Yhb0ZkebJ\?,0]`hbjXF+yQ\<
                                                         Q = eval(input())
L?tb,lehJyMc2bsX0.e.e+W>_Wk-Yhb0ZkebJ\?,0]`hb
L                                                 def y(b): return
 ?tb                                              if b[1:] (base case on false)
                                      ,0]`hb      else: [0, str([0])]
                                                  then:
           c2b                                    Cut the input in half
         yM                                       Map y over the halves
        J                                         Store that in J
    ,leh                                          The cursor position is the length 
                                                  of the body of the first function
                 .e                 J             enum-map, where k is the index
                                                  and b is the value, over J
                   .e             eb              enum-map, Y is the index and
                                                  Z is the value, over body of b
                     +W         Zk                Add to Z (line) k (the overall 
                                                  index, 0 or 1) conditional on
                          -Yhb                    Y (line index) - cursor
                       _Wk                        Negated if k
                      >       0                   > 0
               X0                    \?           Add '?' to the first element
              s                                   Concatenate, giving the body

jXF+yQ\<
    yQ      Call the above on the input
   +  \<    Append a '<'
 XF         Splat the 3 element list into the 'append-at' function,
            adding the curson in the right place
j           Join on newlines and print.

Ну ... я просто повернувся додому, щоб виправити своє рішення ...
Лина монашка

3

Python 3, 352 208 205 байт

Це все ще дуже необачне, і я спробую додати пояснення пізніше. Після деяких модифікацій мені вдалося видалити 144 147 байт.

f=lambda x,l=len,r=range:'\n'.join(*x)if l(x)<2 else f([[x[i][j]+['0',''][j<=l(x[i])//2]for j in r(l(x[i]))]+[['?','?<'][l(x)<3]]+[x[i+1][j]+['1',''][j>=l(x[i])//2]for j in r(l(x[i]))]for i in r(0,l(x),2)])

Функція, fяка приймає введення значень таблиці істинності як список булевих форм ['1','1','1','0','0','1'...], де '1'truthy та '0'falsey, і повертає програму Stackylogic.

Спробуйте це на Ideone

Якщо ви хочете протестувати отриману програму, ви можете використовувати GamrCorps інтерпретатор Convex «и тут .

Як це працює

Це рекурсивна функція і використовує індуктивний метод, описаний у питанні.

На рівні нульової індексованої рекурсії aфункція створює n/2 a+1-вхідні програми Stackylogic з -вхідних n aпрограм у списку. Це робиться шляхом об’єднання всіх сусідніх пар двох програм у списку з ?; оскільки курсор завжди знаходиться в середньому елементі кожної складової програми, необхідне додавання 0або 1може бути виконане ітерацією над кожним рядком приєднаних програм та додаванням, якщо індекс поточного рядка менший або дорівнює / більший ніж або дорівнює середньому індексу у відповідних випадках. Якщо список містить лише дві програми, наступний рекурсивний виклик дасть остаточну програму; оскільки для цього потрібен курсор, приєднання замість цього відбувається на ?<.

Коли список має довжину 1, у списку повинен бути лише один елемент, що містить повну програму. Отже, всі рядки програми з'єднуються на новому рядку та повертаються.

Приклад допомагає проілюструвати це:

Take the input ['1', '1', '1', '0', '0', '1', '1', '1'].

Level  Return value

0  [['1', '?', '1'], ['1', '?', '0'], ['0', '?', '1'], ['1', '?', '1']]
1  [['1', '?', '10', '?', '11', '?', '0'], ['0', '?', '10', '?', '11', '?', '1']]
2  [['1', '?', '10', '?', '110', '?0', '00', '?<', '01', '?1', '101', '?', '11', '?', '1']]
3  '1\n?\n10\n?\n110\n?0\n00\n?<\n01\n?1\n101\n?\n11\n?\n1'

which when printed gives:

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