Гольф усі 16 логічних воріт з 2 входами і 1 вихід!


63

Наприклад, затвор A and B- це логічний затвор з 2 входами та 1 виходом.

Їх рівно 16, адже:

  • кожен логічний затвор приймає два входи, які можуть бути truthy або falsey, даючи нам 4 можливі входи
  • з чотирьох можливих входів, кожен може мати вихід трити та фальси
  • отже, існує 2 ^ 4 можливих логічних воріт, а це 16.

Ваше завдання - написати 16 програм / функцій, які реалізують усі вони окремо.

Ваші функції / програми повинні бути незалежними .

Вони дійсні до тих пір, поки вони виводять значення truthy / falsey, це означає, що ви можете реалізувати A or Bв Python як lambda a,b:a+b, навіть якщо 2вони створені для A=Trueта B=True.

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

Список логічних воріт

  1. 0,0,0,0 ( false)
  2. 0,0,0,1 ( and)
  3. 0,0,1,0 ( A and not B)
  4. 0,0,1,1 ( A)
  5. 0,1,0,0 ( not A and B)
  6. 0,1,0,1 ( B)
  7. 0,1,1,0 ( xor)
  8. 0,1,1,1 ( or)
  9. 1,0,0,0 ( nor)
  10. 1,0,0,1 ( xnor)
  11. 1,0,1,0 ( not B)
  12. 1,0,1,1 ( B implies A)
  13. 1,1,0,0 ( not A)
  14. 1,1,0,1 ( A implies B)
  15. 1,1,1,0 ( nand)
  16. 1,1,1,1 ( true)

Там, де перше число є виходом для A=false, B=false, друге число є виходом для A=false, B=true, третє число є виходом для A=true, B=false, четверте число - вихід для A=true, B=true.

Таблиця лідерів


2
Ваші функції / програми можуть ділитися кодом. Що це значить? Також програми можуть бути різними мовами?
Лінь

2
Мені здається, що пояснення є заплутаним: "з 4 можливих входів кожен може мати вихід та хибність". Це не означає 8 (4 * 2) станів?
DavidC

4
Імена, які ви пропускаєте, - це ворота AND-NOT (A AND NOT B і B AND NOT A).
Mego

14
Так це сталося знову. Є 18 відповідей, в основному простий і правильний, тоді з нізвідки питання не стало "незрозумілим, що ви запитуєте". Мені вам не подобається виклик, продовжуйте, візьміть інше, не закривайте його!
edc65

4
@dorukayhan Дивіться: вакуумна правда
Sp3000

Відповіді:


110

Доміно , 122 000 байт або 72 плитки

Кількість байтів - це розмір збереженого файлу, який є 0.122 MB.

Натхненням були доміно обчислення . Я перевірив усе це на симетрію (і далі!) За допомогою гри з віртуальною реальністю Steam під назвою Настільний симулятор .

Деталі

  • I / O
    • Початок - це включено для ясності (не зараховується до загальної кількості) і є тим, що "викликає" або "виконує" функцію. Потрібно натиснути після введення [Жовтий] .
    • Введення A - Це включено для ясності (не зараховується до загальної кількості) і "натискається", щоб вказати a, 1а не було натиснуто інакше [Зелений] .
    • Введення B - Це включено для ясності (не зараховується до загальної кількості) і "натискається", щоб вказати а, 1а в іншому випадку не було натиснуто [Синій] .
    • Вихід - Це зараховується до загальної суми. Саме доміно оголошує результат логічної брами [Чорний] .
  • Т / ф
    • Падіння виходу доміно представляє результат Trueабо1
    • Постійна доміно доміно являє собою результат Falseабо0
  • Натискання
    • Для того, щоб дати вхід або запустити ланцюг, нереститься металевий мармур
    • Встановіть силу підйому на 100%
    • Підніміть мармур над потрібним доміно
    • Кинь мармур

введіть тут опис зображення

Ворота

  • хибний, 1
    • введіть тут опис зображення
  • і, 6 4
    • введіть тут опис зображення
  • А, а не В, 4 3
    • введіть тут опис зображення
  • А, 1
    • введіть тут опис зображення
  • не A і B, 4 3
    • введіть тут опис зображення
  • Б, 1
    • введіть тут опис зображення
  • xor, 15 11
    • введіть тут опис зображення
  • або, 1
    • введіть тут опис зображення
  • ні, 3 2
    • введіть тут опис зображення
  • xnor, 17 13
    • введіть тут опис зображення
  • не В, 2
    • введіть тут опис зображення
  • B означає A, 7 6
    • введіть тут опис зображення
  • не А, 2
    • введіть тут опис зображення
  • А означає B, 7 6
    • введіть тут опис зображення
  • нанд, 16 15
    • введіть тут опис зображення
    • правда, 1
    • введіть тут опис зображення

TL; DR

Я чекав / бажав виклику, сприятливого для доміно, і коли побачив це, я не міг його передати. Єдина проблема полягала в тому, що, очевидно, більше ніхто не володіє доміно! Тож врешті-решт я поступився і купив Подвійну Дванадцять . У цьому наборі є 91 плитка, що дало мені уявлення про функціонування виклику / запуску доміно замість методу звичайної (тривалої) «затримки в часі». Заслуга за поворот на 90 градусів належить каналу доміноесдубл07 .

Після побудови їх з фізичним доміно, було виключено на мета , що справжні рішення повинні бути цифровими. Тому я відтворив ці ворота в настільному симуляторі . На жаль, TS і реальність не згодні з фізикою доміно. Це вимагало від мене додати 11 доміно, але я також заощадив 8. Загалом, віртуальні доміно є приблизно на x150 більш ефективними щодо побудови та тестування ( Ctrl+ Z).

Оновлення

  • -9 [17-03-13] Скороченоxor xnor nand
  • [17-03-04] Додано посилання на файл семінару
  • +11 [17-03-03] Додано цифровий xnorтаxor
  • -8 [17-03-03] Оцифровував усі ворота (крім xorі xnor). Для блокування на стільниці потрібно лише 1 доміно, а не 2.
  • [16-09-23] Зменшення зображень
  • -11 [16-09-18] Майже розрізати xor навпіл. Дякуємо @DJMcMayhem за xnor та Джо за xor.
  • -31 [16-08-31] Оновлено деякі фотографії та поголив кілька плиток та розрізав Xor навпіл
  • [16-08-28] Додано фотографії

43
+1 Нам потрібно більше гольфінгу в доміно на PPCG
Beta Decay


7
Ого. Це одна з найоригінальніших відповідей, яку я коли-небудь бачив на цьому сайті.
DJMcMayhem

3
Схоже, ти міг би зняти одне доміно, якщо ти збиваєш кнор разом і маєш 4 поперек, а не 5. Потім знову я не перевіряв цього.
DJMcMayhem

2
Дякуємо, що знайшли час, щоб зробити це правильною відповіддю. Однак посилання на вихідний файл трохи важко знайти. Зазвичай посилання в заголовку веде до самої мови. Тож я б пов'язував цю гру з паровою грою, а потім поклав би її на фактичний "вихідний файл" в окремий чітко позначений посилання десь у тілі відповіді.
Мартін Ендер

45

Шестикутник , 89 байт

Завдяки FryAmTheEggman за необхідне натхнення для рішення XOR.

0000 !@
0001 ?.|@!
0010 #?#!)@
0011 ?!@
0100 +?|@!?
0101 ??!@
0110 ?<@!!<_\~(
0111 ?<<@!
1000 )\!#?@{
1001 (~?/@#!
1010 ??|@!)
1011 \#??!1@
1100 ?(~!@
1101 ?.|@!)
1110 ?$@#)!<
1111 1!@

Усі програми використовують 0для false та 1for true.

Спробуйте в Інтернеті! Це не тестовий набір, вам доведеться самостійно копіювати в різні програми та вводи.

Вищезазначене рішення знаходиться в межах 2-байт оптимальності (якщо я не розслабляємо правду / хибну інтерпретацію, я думаю). Я дозволив пошуку грубої сили тривати близько двох днів для всіх програм, які вписуються в сторону 2, тобто до 7 байт (не зовсім всі програми - я зробив кілька припущень щодо того, що потрібно кожній дійсній програмі, а що ні дійсна програма могла мати). Пошук знайшов рішення для 15 з 16 можливих воріт - і часто набагато більше, ніж лише один. Ви можете знайти список усіх альтернативних рішень у цій пастібі, де я також згрупував їх за еквівалентною поведінкою. Те, що я показую вище, я вибрав, тому що вони є найпростішим чи найцікавішим рішенням, і завтра я додам їх пояснення.

Що стосується 16-го ворота: XOR - це єдиний воріт, який, очевидно, не може бути реалізований у 7 байтах. На жаль, пошук коду в більш великих програмах, на жаль, неможливий з кодом, який у мене зараз є. Тож XOR довелося писати від руки. Найкоротшою, яку я знайшов поки що, є вищезгадана 10-байтна програма, яка базується на невдалій (але дуже близькій) спробі FryAmTheEggman. Можливо, що існує 8-байтове або 9-байтове рішення, але крім цього, всі рішення дійсно повинні бути оптимальними.

Пояснення

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

0000: Помилковий

Я не думаю, що нам буде потрібна схема для цього:

 ! @
. . .
 . .

Оскільки вся сітка пам'яті ініціалізована на нулі, !просто надрукує нуль і @припинить програму.

Це також єдине 2-байтове рішення.

0001: І

 ? .
| @ !
 . .

Це в основному реалізує коротке замикання . Сіра діаграма нижче показує початок програми, де зчитується перший вхід, ?а вказівник інструкції (IP) завертається до лівого кута, де |дзеркало відображає його. Тепер кут виступає як умовний, таким є два різних контури виконання залежно від значення першого вводу. Червона діаграма показує потік управління для, A = 0а зелена діаграма для A = 1:

i i i

Як бачите, коли Aє 0, то ми просто надруковуємо його та припиняємо (пам’ятайте, що все .не є). Але коли Aє 1, то IP знову переходить перший рядок, читаючи Bта друкуючи це замість цього.

Всього існує шістнадцять 5-байтових рішень для цього ворота. Чотирнадцять із них по суті є такими ж, як і вище, або використовуючи >замість цього, |або замінюючи .команду, яка фактично не працює, або ставлять ?на друге місце:

?.|@!    .?|@!    ?=|@!    =?|@!    ?_|@!    _?|@!    ?0|@!
?.>@!    .?>@!    ?=>@!    =?>@!    ?_>@!    _?>@!    ?0>@!

А потім є ще два рішення (які рівнозначні один одному). Вони також реалізують ту саму логіку короткого замикання, але шляхи виконання трохи божевільніші (і залишаються читачем як вправа):

?<!@|
?<!@<

0010: А, а не В

 # ?
# ! )
 @ .

Це також реалізує форму короткого замикання, але завдяки використанню #керуючого потоку набагато складніше. #- це умовний IP-комутатор. Hexagony фактично поставляється з шістьма IP - адрес , помічених 0до 5, які починаються в шести кутах сітки, вказуючи уздовж їх по годинниковою стрілкою краю (і програма завжди починається з IP 0). Коли #зустрічається a, приймається поточне значення за модулем 6, а контрольний потік продовжується відповідним IP. Я не впевнений, який привід божевілля змусив мене додати цю функцію, але це, безумовно, дозволяє отримати деякі дивовижні програми (як ця).

Ми виділимо три випадки. Коли A = 0програма досить проста, так як значення завжди , 0коли #зустрічається таке , що немає IP-комутації не відбувається:

i

#нічого не робить, ?читає A(тобто також нічого не робить), #все ще нічого не робить, !друкує 0, )збільшує його (це важливо, інакше IP не перейде на третій рядок), @припиняє програму. Досить просто. Тепер розглянемо випадок (A, B) = (1, 0):

i

Червоний шлях все ще відповідає IP 0, і я додав зелений шлях для IP 1. Ми бачимо, що після ?читання A( 1цього разу) #перемикається на IP, що починається у верхньому правому куті. Це означає, що ?можна прочитати B( 0). Тепер )збільшуємо це до 1такого, що #у верхньому лівому куті нічого не робить, і ми залишаємося з IP 1. У !друкує 1і IP обтікає ліву діагональ. #все ще нічого не робить і @припиняє програму.

Нарешті, справді дивний випадок, коли обидва входи 1:

i

Цього разу також є другий вхід 1і )збільшує його 2. Це означає, що #у верхньому лівому куті викликає інший IP-перемикач на IP 2, позначають синім кольором. На цьому шляху ми спочатку збільшуємо його далі 3(хоча це не має значення), а потім проходимо ?втретє. Оскільки ми зараз натиснули EOF (тобто вхід вичерпано), ?повертає 0, !друкує це та @припиняє програму.

Зокрема, це єдине 6-байтове рішення для цього ворота.

0011: A

 ? !
@ . .
 . .

Це досить просто, що діаграма нам не знадобиться: ?читає A, !друкує її, @закінчує.

Це єдине 3-байтове рішення для цих воріт. (В принципі, це також можна було б зробити ,;@, але пошук не включав ;, тому що я не думаю, що він може колись зберегти байти !для цього завдання.)

0100: B, а не A

 + ?
| @ !
 ? .

Цей набагато простіше, ніж його "брат" 0010. Контрольний потік насправді такий самий, як ми бачили вище для 0001(І). Якщо A = 0, то IP переходить нижній рядок, читаючи Bта друкуючи, що перед завершенням. Якщо A = 1тоді IP знову переходить перший рядок, також читаючи B, але +додає два невикористані краї пам’яті, тому все, що він робить, скидає поточне значення 0, щоб !завжди друкувати 0.

Є 6-байтних альтернатив цьому (досить 42). По-перше, є тонна розчинів, еквівалентних вище. Ми знову можемо вільно вибирати між |і >, і +може бути замінений на будь-який інший командою , яка дає нам порожній край:

"?|@!?    &?|@!?    '?|@!?    *?|@!?    +?|@!?    -?|@!?    ^?|@!?    {?|@!?    }?|@!?
"?>@!?    &?>@!?    '?>@!?    *?>@!?    +?>@!?    -?>@!?    ^?>@!?    {?>@!?    }?>@!?

Крім того, ми можемо використовувати і ]замість ?. ]переходить до наступного IP (тобто вибирає IP 1), так що ця гілка замість цього повторно використовує ?у верхньому правому куті. Це дає ще 18 рішень:

"?|@!]    &?|@!]    '?|@!]    *?|@!]    +?|@!]    -?|@!]    ^?|@!]    {?|@!]    }?|@!]
"?>@!]    &?>@!]    '?>@!]    *?>@!]    +?>@!]    -?>@!]    ^?>@!]    {?>@!]    }?>@!]

А потім є шість інших рішень, які працюють по-різному з різним рівнем божевілля:

/[<@!?    ?(#!@]    ?(#>@!    ?/@#/!    [<<@!?    [@$\!?

0101: Б

 ? ?
! @ .
 . .

Woohoo, ще один простий: читати A, читати B, друкувати B, припиняти. Але насправді є альтернативи цьому. Оскільки Aце лише один символ, ми можемо також прочитати його ,:

,?!@

Також є можливість використання одинарного ?дзеркала та використання дзеркала для його перегляду двічі:

?|@!    ?>@!

0110: Xor

  ? < @
 ! ! < _
\ ~ ( . .
 . . . .
  . . .

Як я вже говорив вище, це був єдиний хвірт, який не впишеться в бічну довжину 2, тому це власноручне рішення FryAmTheEggman і я, і є хороший шанс, що це не оптимально. Можна виділити два випадки. Якщо A = 0потік управління досить простий (тому що в такому випадку нам потрібно тільки друкувати B):

i

Починаємо на червоній стежці. ?читає A, <- це гілка, яка відхиляє лівий нуль. ІР накручується донизу, потім _- інше дзеркало, і коли IP потрапляє в кут, він завертається до верхнього лівого кута і продовжує синій шлях. ?читає B, !друкує. Тепер (декрементує це. Це важливо, оскільки воно гарантує, що значення не є позитивним (воно є 0чи -1зараз). Це робить обтікання IP-праворуч праворуч, де @програма завершує роботу.

Коли A = 1все стає дещо складніше. У такому випадку ми хочемо надрукувати not B, що саме по собі не надто складно, але шлях виконання трохи тропічний.

i

Цього разу <відхиляє IP-праворуч, а далі - <просто дзеркало. Таким чином, IP проходить той самий шлях у зворотному напрямку, читаючи, Bколи він ?знову зустрічається . IP обертається до правого кута і продовжує зелений шлях. Вона наступні зустрічі , (~які є «декремент, помножити на -1», які свопи 0і 1тому розраховує not B. \є просто дзеркалом і !друкує бажаний результат. Потім ?намагається повернути інше число, але повертає нуль. Зараз IP продовжується в нижньому лівому куті на блакитному шляху. (декременти, <роздуми,(декременти знову, так що поточне значення негативне, коли IP потрапляє в кут. Він рухається по нижній правій діагоналі, а потім, нарешті, натискає, @щоб припинити програму.

0111: Або

 ? <
< @ !
 . .

Більш коротке замикання.

i i

A = 0Випадок (червоний контур) трохи заплутаним тут. IP-адреса відхиляється ліворуч, завертається до лівого нижнього кута, негайно відображається <та повертається ?до прочитаного B. Потім він загортає до rigt кутку, друкує Bз !і закінчується.

A = 1Випадок (зелений шлях) трохи простіше. <Філія відхиляє IP право, тому ми просто надрукувати !, завернути назад в лівому верхньому кутку, і закінчуються в @.

Є лише одне інше 5-байтове рішення:

\>?@!

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

1000: Ні

 ) \
! # ?
 @ {

Це може бути моя улюблена програма, знайдена в цьому пошуку. Найкрутіше, що ця реалізація norнасправді працює до 5 входів. Мені доведеться трохи розібратися в деталях моделі пам'яті, щоб пояснити цю. Отже, як швидке оновлення, модель пам’яті Hexagony - це окрема шестикутна сітка, де кожен край містить ціле значення (спочатку всі нульові). Існує вказівник пам’яті (MP), який вказує край і напрямок уздовж цього краю (такий, що перед поточним краєм і за ним є два сусідні краї із значущими лівими та правими сусідами). Ось діаграма ребер, які ми будемо використовувати, з MP, що починається, як показано червоним кольором:

i

Спершу розглянемо випадок, коли обидва входи 0:

i

Ми починаємо з сірого шляху, який просто збільшує край А до 1так, щоб #перейти на IP, 1який є синім шляхом, починаючи з правого верхнього кута. \нічого там не робить і ?читає вхід. Ми загортаємо до верхнього лівого кута, де )збільшується цей вхід. Тепер, поки вхід дорівнює нулю, це призведе до а 1, тож #нічого не буде робити. Потім {переміщує MP вліво, тобто на першій ітерації від до B . Оскільки цей край все ще має початковий нуль, IP повертається назад у верхній правий кут та на новий край пам'яті. Отже ця петля триватиме до тих пір, поки зчитує нулі, переміщаючи MP навколо шестикутника від B?до C до D тощо. Не має значення, ?повертає нуль, тому що це був вхід чи тому, що це EOF.

Після шести ітерацій через цю петлю, {повертається до . Цього разу край вже містить значення з першої ітерації, тому IP переходить у лівий кут і продовжує замість цього зеленого шляху. просто роздруковує це і припиняє програму.1!1@

А що робити, якщо якийсь із входів є 1?

i

Потім ?читає, що 1в якийсь момент і )збільшує його 2. Це означає #, що тепер знову переключимо IP-адреси, і ми продовжимо в правому куті червоною стежкою. ?читає інший вхід (якщо такий є), який насправді не має значення і {рухається одним краєм далі. Це повинно бути невикористаним краєм, отже, це працює до 5 входів. IP-адреса перегортається вгорі праворуч, де вона негайно відображається, і переходить у лівий кут. !друкує 0на невикористаному краю та #переходить на IP-адресу 0. Цей IP все ще чекав на #південному заході (сірий шлях), тому він негайно потрапляє на програму @та припиняє її.

Всього існує сім 7-байтових рішень для цього ворота. 5 з них працюють так само, як це і просто використовують інші команди для переміщення до невикористаного краю (і можуть ходити по іншому шестикутнику або в іншому напрямку):

)\!#?@"    )\!#?@'    )\!#?@^    )\!#?@{    )\!#?@}

І є ще один клас рішень, який працює лише з двома входами, але шляхи виконання яких насправді є ще більш складними:

?]!|<)@    ?]!|<1@

1001: Рівність

 ( ~
? / @
 # !

Це також робить дуже розумним використання умовного вибору IP. Нам потрібно ще раз розрізняти A = 0і A = 1. У першому випадку ми хочемо друкувати not B, у другому ми хочемо надрукувати B. Бо A = 0ми також виділяємо два випадки для B. Почнемо з A = B = 0:

i

Починаємо сірою стежкою. (~можна ігнорувати, IP переходить у лівий кут (все ще на сірій стежці) та читає Aз ?. (декременти, які, таким чином, ми отримуємо -1і перегортаємо IP до лівого нижнього кута. Тепер, як я вже говорив раніше, #приймає значення модуля, 6перш ніж вибирати його IP, тому значення -1фактично виходить IP 5, яке починається в лівому куті на червоному шляху. ?читає B, (декрементує це так, щоб ми залишалися в IP, 5коли ми #знову натискаємо . ~заперечує -1так, що IP перегортається до правого нижнього кута, друкує 1та закінчується.

i

Тепер , якщо Bце 1замість того, щоб , поточне значення буде , 0коли ми потрапили #вдруге, тому ми переходимо назад в IP 0( в даний час на зеленому шляху). Що потрапляє ?втретє, поступаючись 0, !друкує його та @припиняє.

i

Нарешті, випадок де A = 1. Цього разу значення струму вже дорівнює нулю, коли ми потрапляємо #вперше, тому це ніколи не переходить на IP 5в першу чергу. Ми просто продовжуємо негайно зелену стежку. ?тепер не просто дає нуль, але повертає Bнатомість. !друкує його і @знову припиняється.

Всього є три 7-байтові рішення для цього ворота. Інші два працюють дуже по-різному (навіть один від одного) і ще більш дивно використовують #. Зокрема, вони читають одне або більше значень за допомогою ,(зчитування символьного коду замість цілого числа), а потім використовують це значення за модулем 6 для вибору IP. Це досить гайки.

),)#?@!

?~#,~!@

1010: Не Б

 ? ?
| @ !
 ) .

Цей досить простий. Шлях виконання - це горизонтальна гілка, про яку ми вже знаємо andраніше. ??читає, Aа потім негайно B. Після відображення на |та розгалуження B = 0ми будемо виконувати нижню гілку, де )збільшується значення, на 1яке потім друкується !. На верхній гілці (якщо B = 1) ?просто скиньте край, до 0якого також надрукується !.

Для цього ворота існує вісім 6-байтних програм. Чотири з них майже однакові, використовуючи або >замість, |або 1замість )(або обох):

??>@!)    ??>@!1    ??|@!)    ??|@!1

Двоє використовують сингл, ?який використовується двічі завдяки дзеркалу. Тоді заперечення відбувається так, як ми робили xorз будь-яким (~або ~).

?>!)~@    ?>!~(@

І, нарешті, два рішення використовують умовний IP-перемикач, бо навіщо використовувати простий спосіб, якщо і згорнуте:

??#)!@    ??#1!@

1011: B означає A

 \ #
? ? !
 1 @

Для цього використовується деяка досить складна комутація IP. Почну з A = 1справи цього разу, тому що це простіше:

введіть тут опис зображення

Ми починаємо на сірому шляху, який зчитує Aз ?і потім потрапляє в #. Так як Aце 1це переходить на IP 1(зелений шлях). !Відразу друкує того, IP - обгортання в лівому верхньому кутку, читає B(надмірно) і завершує роботу .

Коли A = 0справи стають трохи цікавішими. Спочатку розглянемо A = B = 0:

введіть тут опис зображення

Цього разу #нічого не робить, і ми залишаємось на IP 0(червоний шлях з цієї точки вперед). ?читає Bі 1перетворює його на а 1. Загорнувшись у верхній лівий кут, ми #знову натискаємо , тож врешті-решт ми опиняємось зеленою доріжкою та друкуємо, 1як і раніше, перед тим, як закінчувати.

Нарешті, ось (A, B) = (0, 1)хибний випадок:

введіть тут опис зображення

Зауважте, що для ясності я видалив початковий сірий шлях, але програма починається так само, і ми опиняємося на червоному шляху, як і раніше. Тож цього разу ?повертається другий 1. Зараз ми стикаємося з 1. У цей момент важливо зрозуміти, що цифри насправді роблять у Гексагоні (поки що ми використовували їх лише на нулях): коли зустрічається цифра, поточне значення множиться на 10, а потім додається цифра. Зазвичай це використовується для запису десяткових чисел дословно у вихідний код, але це означає, що B = 1насправді відображено у значення 11. Таким чином, коли ми потрапили #, це береться за модулем, 6щоб дати, 5і, отже, ми переходимо до IP 5(замість того, 1як раніше) і продовжуємо синій шлях. Удар?в третій раз повертає нуль, тому !друкує, що після двох ?інших IP-адреса перегортається праворуч внизу, де програма закінчується.

Для цього є чотири 7-байтові рішення, і всі вони працюють по-різному:

#)/!?@$    <!?_@#1    \#??!1@    |/)#?@!

1100: Не A

 ? (
~ ! @
 . .

Просто простий лінійний: читати Aз ?, заперечувати (~, друкувати !, закінчувати @.

Є одне альтернативне рішення, і це ~)замість цього:

?~)!@

1101: A означає B

 ? .
| @ !
 ) .

Це набагато простіше, ніж протилежне значення, про яке ми тільки що говорили. Це знову одна з тих горизонтальних галузевих програм, як та для and. Якщо Aце так 0, він просто збільшується до 1нижньої гілки та друкується. В іншому випадку верхня гілка виконується знову, де ?читається, Bа потім !надруковує це.

Там в тонну альтернатив тут (66 рішень в цілому), в основному за рахунок вільного вибору ефективних немає-OPS. Для початку ми можемо варіювати вищезазначене рішення всіма тими ж способами, які ми могли б зробити, andі ми також можемо вибирати між )та 1:

?.|@!)    .?|@!)    ?=|@!)    =?|@!)    ?_|@!)    _?|@!)    ?0|@!)
?.|@!1    .?|@!1    ?=|@!1    =?|@!1    ?_|@!1    _?|@!1    ?0|@!1
?.>@!)    .?>@!)    ?=>@!)    =?>@!)    ?_>@!)    _?>@!)    ?0>@!)
?.>@!1    .?>@!1    ?=>@!1    =?>@!1    ?_>@!1    _?>@!1    ?0>@!1

А потім є інша версія з використанням умовного вибору IP, де першу команду можна вибрати майже довільно, а також є вибір між )і 1для деяких із цих варіантів:

"?#1!@    &?#1!@    '?#1!@    )?#1!@    *?#1!@    +?#1!@    -?#1!@    .?#1!@    
0?#1!@    1?#1!@    2?#1!@    3?#1!@    4?#1!@    5?#1!@    6?#1!@    7?#1!@    
8?#1!@    9?#1!@    =?#1!@    ^?#1!@    _?#1!@    {?#1!@    }?#1!@

"?#)!@    &?#)!@    '?#)!@              *?#)!@    +?#)!@    -?#)!@    
0?#)!@              2?#)!@              4?#)!@              6?#)!@    
8?#)!@                        ^?#)!@    _?#)!@    {?#)!@    }?#)!@

1110: Нанд

 ? $
@ # )
 ! <

Останній складний. Якщо ви все ще читаєте, ви майже зробили це. :) Давайте розглянемо A = 0спочатку:

введіть тут опис зображення

?читає, Aа потім ми вдаряємо $. Це команда стрибків (як Befunge #), яка пропускає наступну інструкцію, щоб ми не закінчувались на @. Натомість IP продовжується на #. Однак оскільки Aє 0, це нічого не робить. )збільшує його 1так, щоб IP продовжувався на нижньому шляху, де 1друкується. У <відхиляє IP - вправо , де він загортає до лівого кута , і програма завершується.

Далі, коли є вхід, (A, B) = (1, 0)ми отримуємо цю ситуацію:

введіть тут опис зображення

Це по суті те ж саме , як і раніше , за винятком , що на #ми переходимо до IP 1(зелений шлях), але так як Bце 0ми повернутися до IP , 0коли ми потрапили #вдруге (тепер синій шлях), де він друкує , 1як і раніше.

Нарешті, A = B = 1випадок:

введіть тут опис зображення

Цього разу, коли ми #вдруге, поточне значення все ще залишається 1таким, що ми знову не змінюємо IP-адресу. <Відображає це і в третій раз ми потрапили , ?ми отримуємо нуль. Звідси IP-обгортання ліворуч знизу, де !друкується нуль, і програма закінчується.

Всього для цього існує дев'ять 7-байтних рішень. Перша альтернатива просто використовує 1замість ):

?$@#1!<

Тоді є два рішення, які допоможуть вам змінити кількість IP-комутацій:

)?#_[!@    1?#_[!@

Це насправді підірвало мою думку: цікава частина полягає в тому, що перемикання IP може використовуватися як відкладене умовне. Правила перемикання IP-адреси мови такі, що поточний IP робить ще один крок до того, як відбудеться комутація. Якщо цей крок відбудеться через кут, то поточне значення визначає, до якої гілки буде продовжуватися IP, якщо ми коли-небудь повернемось до нього. Саме це відбувається, коли вхід є A = B = 1. Хоча це все відповідає тому, як я спроектував мову, я ніколи не знав про це значення специфікації, тому приємно, коли моя мова навчає мене новим хитрощам: D.

Тоді є третє рішення, кількість IP-комутації ще гірше (хоча він не використовує цей відкладений умовний ефект):

>?1]#!@

А тут ще один:

?$@#)!<

І ось ось ці чотири рівнозначні рішення, які використовують певну умовну комутацію IP і замість цього реалізують всю логіку через гілки та кути:

]<?<@!)    ]<?<@!1    ]|?<@!)    ]|?<@!1

1111: Правда

 1 !
@ . .
 . .

Ви заробили собі щось просте для кінця: встановіть край 1, друкуйте !, закінчуйте @. :)

Звичайно, є одна альтернатива:

)!@

Як завжди, всі діаграми управління потоками, створені за допомогою HexagonyColorer Тімві, і діаграма пам'яті з його EsotericIDE .


9
Aaaaaand the tl; dr. Нагорода дістається ... (жартує, очевидно, чудова відповідь і дуже добре виписано, +1)
Bassdrop Cumberwubwwwwub

4
Це причина, що ви більше не активні в чаті ??
Оптимізатор

Начебто запізнення, але ви могли б додати посилання на свій грубий код сили?
nedla2004

@ nedla2004 Я зазвичай не тримаю їх, але це завжди модифікована версія цього сценарію .
Мартін Ендер

40

APL, 22 20 18 байт

Справжні та помилкові записи - це повні програми, а інші 14 - функції. (Спасибі Адаму.)

0000 false              0 (complete program)
0001 p and q            ∧
0010 p and not q        >
0011 p                  ⊣
0100 not p and q        <
0101 q                  ⊢
0110 xor                ≠
0111 p or q             ∨
1000 not p and not q    ⍱
1001 eq                 =
1010 not q              ~⊢
1011 p or not q         ≥
1100 not p              ~⊣
1101 not p or q         ≤
1110 not p or not q     ⍲
1111 true               1 (complete program)

Спробуйте тут.


1
+1 Приємне використання атопів! Ви можете зберегти два байти, зробивши 0000 і 1111 в trad-fns 0і 1.
Адам

Існує консенсус, щоб дозволити tfns, але не рахувати перший рядок. Це відповідає нерахуванню імені файлу на мовах, які використовують файли як контейнери програми з назвою програми = ім'я файлу.
Адам


10
Желе: 19 байт. Це: 18 байт. Це не означає, що ви перемогли Денніса ? +1 для цього.
NoOneIsHere

29

Шахи / посередні шахісти в ендграх, 70 штук

Натхнений відповіддю доміно, я вирішив, що ще одна гра повинна мати цю честь.

Зауважте, що я взяв кілька правил щодо того, як рухаються шматки. Оскільки я не відчуваю, як вивчати оптимальні рухи для кожної ситуації, правила для білих білих є простими: тримайтеся поза контролем, захоплюйте найвищий рейтинг, який він може перевернути, втрачаючи якомога менше матеріалу, і зупиняйте пішака від сприяння в такому порядку пріоритетності. Якщо є два простори, до яких він може переміститися, з однаковою прихильністю, він може перейти до будь-якого (отже, у цих, якщо він може переміститися на більш ніж один квадрат, вони одного кольору). Зауважте, що білий колір захопить чимось, навіть якщо він потрапить у полон, якщо шматок, на який він атакує, має більшу цінність, ніж втрачений. Цінності тут:pawn<knight=bishop<rook<queen

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

Вихід - колір квадратного білого короля, який закінчується на: Білий = 1, чорний = 0

Перед зображеннями я хочу вибачитися за погані зображення. Я не дуже добре тримаю камеру.

Неправдиво, 4:

помилковий

І, 4:

введіть тут опис зображення

А, а не В, 5 (я думаю, я можу це знизити до трьох, але зараз немає дошки):

введіть тут опис зображення

A, 4:

введіть тут опис зображення

Не A, а B, 5 (я думаю, я можу це знизити до трьох, але зараз немає дошки):

введіть тут опис зображення

B, 4:

введіть тут опис зображення

Xor, 5 (я знаю спосіб зробити це 4, але у мене немає дошки зараз):

введіть тут опис зображення

Або 4:

введіть тут опис зображення

Ні, 4:

введіть тут опис зображення

Xnor, 5 (я знаю спосіб зробити це 4, але у мене немає дошки зараз):

введіть тут опис зображення

Не B, 4:

введіть тут опис зображення

B означає A, 5 (я думаю, я можу скоротити це до трьох, але зараз немає дошки):

введіть тут опис зображення

Не A, 4:

введіть тут опис зображення

A означає B, 5 (я думаю, я можу це звести до трьох, але зараз немає дошки):

введіть тут опис зображення

Nand, 4:

введіть тут опис зображення

Правда, 4:

введіть тут опис зображення


1
Нічого собі, я поняття не мав, що програмування в шахах можливе ... Не могли б ви розмістити відео / симуляцію декількох із них в дії?
Бета-розпад

2
хммм, у мене зараз немає доступу до шахової дошки. Я, напевно, можу сказати, що A означає, що B / B означає, що / і т. Д. Важче зрозуміти через вплив пішаків на рух королів. Мені, мабуть, слід додати кращих пояснень для цих двох
руйнівний лимон

Радий надихнутись: D Якщо я правильно розумію, місце розташування дошки та шматка еквівалентно програмі. Граки є входом, тож я можу розмістити їх на будь-якій площі, якщо це правильний колір?
нелінійний

Ні, вхід граків полягає в тому, чи вони присутні чи відсутні на дошці. Вони позначаються a і b, коли вони не є симетричними воротами (коли це має значення різні a і b). Також я зрозумів, як я міг би відіграти 2 штуки, але у мене зараз немає дошки. Кисть потрібно використовувати :)
Знищується лимон

Що стосується вашого "І" випадку, якщо ви вилучите правий грак, що заважає королю рухатися вниз (до білого)?
Натан Меррілл

27

Желе , 19 байт

0 0 0 0 ¤  1 byte  Empty niladic chain. Returns default argument 0.
0 0 0 1 &  1 byte  Bitwise AND.
0 0 1 0 >  1 byte  Greater than.
0 0 1 1    0 bytes Empty link. Returns left argument.
0 1 0 0 <  1 byte  Less than.
0 1 0 1 ị  1 byte  At-index (x,y -> [y][x]). Returns right argument.
0 1 1 0 ^  1 byte  Bitwise XOR.
0 1 1 1 |  1 byte  Bitwise OR.
1 0 0 0 |¬ 2 byte  Logical NOT of bitwise OR.
1 0 0 1 =  1 byte  Equals.
1 0 1 0 ¬} 2 bytes Logical NOT of right argument.
1 0 1 1 *  1 byte  Exponentiation.
1 1 0 0 ¬  1 byte  Logical NOT of left argument.
1 1 0 1 >¬ 2 bytes Logical NOT of greater than.
1 1 1 0 &¬ 2 bytes Logical NOT of bitwise AND.
1 1 1 1 !  1 byte  Factorial.

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


13
Я люблю використання Factorial для перетворення 0 або 1 на 1.
Ніл

Це Jelly UTF-8? Якщо так , то ¤і ¬2 байта, а НЕ 1.
Vi.

1
@Vi. Jelly підтримує UTF-8, але він також підтримує користувацьку кодову сторінку, що кодує кожен з 256 символів, які він розуміє як один байт кожен. Посилання байтів у заголовку вказує на нього.
Денніс

0 0 1 0 > 1 byte Greater than.Не вдалося б це зробити, якщо другий вхід був негативним?
MD XF

@MFXF Ми можемо вибрати, яку правду та яке хибне значення ми підтримуємо.
Денніс

24

Логічні ворота NAND - 31 хвіртка

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

введіть тут опис зображення

У кожній з цих діаграм верхній вхід - A, а нижній - B.


5
@xnor може поласувати тим, що знає, що його логічна брама - це та, для якої потрібні найбільші ворота NAND, щоб зробити D:
Джо Z.

Чи можете ви хоча б використовувати Logisim для форматування коду?
mbomb007

1
@ mbomb007 Я відредагую це пізніше. Я не так досвідчений з Логісімом, тому це може зайняти деякий час.
Джо З.

3
Але мені більше подобається почерк.
Leaky Nun

1
Крім того, ви можете переключитися на "ні ворота" і відформатувати його за допомогою redstone ...
jimmy23013,

22

Побітовий циклічний тег , 118 біт = 14,75 байт

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

  • 0: видаліть перший біт із стрічки даних.
  • 1x: якщо перший біт стрічки даних дорівнює 1, додайте біт xдо стрічки даних.

Ми ініціалізуємо стрічку даних з 1, а потім двома вхідними бітами (1 необхідний, тому що немає способу створити 1, якщо стрічка даних складається повністю з 0s), і ми використовуємо остаточний видалений біт даних як вихідний затвор .

  • 0,0,0,0 ( false):001
  • 0,0,0,1 ( and):1001001
  • 0,0,1,0 ( A and not B):0110100
  • 0,0,1,1 ( A):1001
  • 0,1,0,0 ( not A and B):0100
  • 0,1,0,1 ( B):0
  • 0,1,1,0 ( xor):0110110010
  • 0,1,1,1 ( or):0110
  • 1,0,0,0 ( nor):1101001000
  • 1,0,0,1 ( xnor):110101001100
  • 1,0,1,0 ( not B):1100100
  • 1,0,1,1 ( B implies A):110101101000
  • 1,1,0,0 ( not A):11010000
  • 1,1,0,1 ( A implies B):11010011001
  • 1,1,1,0 ( nand):10110100100010
  • 1,1,1,1 ( true):1100

Вітаємо!
Leaky Nun

Є тягнеться 1по falseнеобхідності?
CalculatorFeline

@CalculatorFeline Так, нам потрібно додати a 0до стрічки, щоб її можна було остаточно видалити.
Anders Kaseorg

Ага. Забув про це + обгортання. Розумний!
CalculatorFeline

20

Пітон 2, 137 байт

[].sort
min
int.__rshift__
round
range
{}.get
cmp
max
lambda a,b:a<1>b
lambda a,b:a==b
lambda a,b:b<1
pow
{0:1,1:0}.get
{0:1}.get
lambda a,b:a+b<2
slice

Приймає входи типу min(True,False)(або як min(1,0)). Користується великою перевагою результатів, лише потребуючи правильного значення Truthy-Falsey. Коли це можливо, використовуйте вбудований, щоб уникнути затрат lambda. Я використовував код для пошуку вбудованих модулів, які працюють.

Моя улюблена - {0:1}.getце я думав від руки. Словник {0:1}відображає ключ 0до значення 1. Його getметод приймає ключ і за замовчуванням, виводить значення, що відповідає ключу, або за замовчуванням, якщо такого ключа немає. Таким чином, єдиний спосіб для виведення 0як {0:1}.get(1,0)з недостатньому ключем 1і значенням по замовчуванням 0. Можна отримати й інші варіанти з різними словниками, але лише цей був найкоротшим.

built_in_names = list(__builtins__) 

object_names = ["int","(0)","(1)"] + \
["True","False","0L","1L","0j","1j"] + \
["str", "''", "'0'","'1'","'a'"] + \
["list", "[]", "[0]", "[1]","['']","[[]]","[{}]"] + \
["set","set()","{0}","{1}","{''}"] + \
["dict","{}","{0:0}","{0:1}","{1:0}","{1:1}","{0:0,1:0}", "{0:0,1:1}","{0:1,1:0}","{0:1,1:1}"] + \
["id"]

object_method_names = [object_name+"."+method_name 
for object_name in object_names 
for method_name in dir(eval(object_name))]

additional_func_names = [
"lambda a,b:0",
"lambda a,b:1",
"lambda a,b:a",
"lambda a,b:b",
"lambda a,b:b<1",
"lambda a,b:a<1",
"lambda a,b:a+b",
"lambda a,b:a*b",
"lambda a,b:a==b",
"lambda a,b:a-b",
"lambda a,b:a<=b",
"lambda a,b:a>=b", 
"lambda a,b:a>b", 
"lambda a,b:a<b", 
"lambda a,b:a<1>b", 
"lambda a,b:a+b<2"]

func_names = built_in_names + object_method_names + additional_func_names

t=True
f=False

cases = [(f,f),(f,t),(t,f),(t,t)]

def signature(func):
    table = [bool(func(x,y)) for x,y in cases]
    table_string = ''.join([str(int(val)) for val in table])
    return table_string

d={}

for func_name in func_names:
    try:
        func = eval(func_name) 
        result = signature(func)
        if result not in d or len(func_name)<len(d[result]):
            d[result]=func_name
    except:
        pass

total_length = sum(len(func) for sig,func in d.items())

print total_length
print

for sig in sorted(d):
    print d[sig]

Хіба ви не можете використовувати методи вбудованих функцій , таких як INT в __lt__або __eq__? Це ще більше зменшить кількість байтів: int.__gt__замість lambda a,b:b<1, int.__eq__а не lambda a,b:a==bтак
Gábor Fekete

@ GáborFekete Вони не існують в Python 2, тому що ints завантажують порівняння cmp. Я не пробував цього для Python 3.
xnor

Ой зараз я бачу!
Габор Фекете

Збережіть 4 байти за допомогою функції notдля 0001, False- ideone
Джонатан Аллан

1
@JonathanAllan Це розумно, але я думаю, що notце не відповідає вимогам функції, оскільки ти не можеш цього робити f=not;f(3,4). Рядок notпрацює, тому що передбачувані аргументи функції виглядають як кортеж, так само, як 3+і як 3+(4)навіть 3+не функція, яка може приймати 4вхід.
xnor

20

Ідіть (гра), 33 камені, 73 перехрестя

Якщо доміно та шахи прийнятні, то це. Це не може бути надто гофрованим на повній дошці 19x19 Go. Тому я використовував невеликі прямокутні дошки. Вхідні дані, чи є камені, позначені 1 і 2. Вихід - чи перемагає чорний. Він використовує оцінку площі, 0,5 комі, ситуаційне суперко, не самогубство. Всі чорні грати. Деякі отримують багаторазові рішення.

Перемоги білих (2, 1x5):

➊━━━➋

1 і 2 (3, 2x3):

➊◯➋
┗┷┛

1, а не 2 (2, 1x5):

╺➊━➁╸

1 (2, 1x5):

╺➊➁━╸ 
╺➊━━➁
➀━➁━╸

Не 1 і 2 (2, 1x5):

╺➋━➀╸

2 (2, 1x5):

╺➋➀━╸

1 xor 2 (2, 2x3):

➀┯➁
┗┷┛

1 або 2 (2, 1x5):

╺➊━➋╸
➀━━━➁

1, ні 2 (2, 1x4):

➊━━➋
╺➀➁╸

1 = 2 (2, 1x7):

╺━➀━➁━╸

Не 2 (2, 1x3):

➀➁╸

1 чи ні 2 (2, 1x4):

➀➁━╸
➀━➁╸
╺➊➁╸
➋➊━╸
➋━➊╸

Не 1 (2, 1х3)

➁➀╸

Не 1 або 2 (2, 1x4):

➁➀━╸

1 н. 2 (2, 1x3):

➊━➋

Виграє чорний (2, 1x3):

➊➋╸
➀━➁
➊━➁

Ця сторінка мені трохи допомогла: http://www.mathpuzzle.com/go.html

Можливо, хтось міг би знайти рішення 2 каменю для 1 та 2 на дошці 1x9 ...


1
Які ваші правила самогубства? Заборонено? А що станеться, коли одна сторона заповнить всю дошку? Це вважається самогубством?
Мартін Ендер

@MartinEnder заборонено. І так, це вважається самогубством.
jimmy23013

Рішення 1x7 здавалося неправильним. Я намагаюся це виправити ...
jimmy23013

15

Javascript ES6, 124 байти

a=>0
Math.min
parseInt
a=>a
a=>b=>a<b
a=>b=>b
a=>b=>a^b
Math.max
a=>b=>~a&~b
a=>b=>a==b
a=>b=>~b
Math.pow
a=>~a
a=>b=>a<=b
a=>b=>~a|~b
a=>1

Я зараз серйозно ненавиджу лямбдів.


1
Якщо мені дозволено писати деякі програми і деякі функції ... Я думаю , що ви могли б змінити , a=>b=>0щоб a=>0і сказати , що граматика називати це є (a=>0)(a,b)тільки для тих 4 результатів.
jimmy23013

О так, дякую!
Mama Fun Roll

2
Math.minзамість a=>b=>a&b. Math.maxзамість a=>b=>a|b. Math.powзамість a=>b=>a>=b.
Conor O'Brien

1
Крім того, оскільки NaN - фальси, ви можете робити parseIntзамість a=>b=>a>b.
Conor O'Brien

1
@algmyr !NaN=> true, !!NaN=>false
Mama Fun Roll

14

Сітківка , 62 39 байт

23 байти завдяки @MartinEnder !

0000 false              1 byte : 2
0001 p and q            2 bytes: 11
0010 p and not q        2 bytes: 10
0011 p                  2 bytes: ^1
0100 not p and q        2 bytes: 01
0101 q                  2 bytes: 1$
0110 xor                5 bytes: 01|10
0111 p or q             1 byte : 1
1000 not p and not q    2 bytes: 00
1001 xnor               5 bytes: (.)\1
1010 not q              2 bytes: 0$
1011 p or not q         5 bytes: ^1|0$
1100 not p              2 bytes: ^0
1101 not p or q         5 bytes: ^0|1$
1110 not p or not q     1 byte : 0
1111 true               0 bytes: 

Вводиться як " PQ.

Висновок цілого числа від 0до 3. 0- це фальси, інші - тритумний.

Пояснення

Усі вони - просто регекси .

Наприклад, 01|10просто сірники 01або 10.

В 0000, 2ніколи не буде на вході, тому він ніколи не збігається.

В 1111, він відповідає порожній рядку, який там є 4.


^1|0$має відповідати лише 1 символьному рядку. Що тут відбувається?
CalculatorFeline

@CalculatorFeline Він відповідає [ 1на початку введення] АБО [ 0в кінці введення]. Взяв мені хвилинку, щоб отримати це теж ...
ETHproductions

Прецедент, хлопці ....
Leaky Nun

Я здогадуюсь ^1|0$читати важче, ніж 1.|.0. Здається, читання у всіх важче
l4m2

10

Стек котів , 67 + 64 = 131 байт

Зауважте, що +64 - це від застосування -nmпрапорів до кожної програми. -nвказує на числовий введення / вивід і -mвідображає вихідний код по останньому символу - не всі подання потребують цих прапорів технічно, але для послідовності та простоти я забиваю їх усі однаково.

-2 -2 -3 -3     !I                0 0 0 0     <I!+
-4 -4 -4  1     |!T*I             0 0 0 1     [>I=I_
-4 -4  3 -2     *I*_              0 0 1 0     :I*=I:
-2 -2  3  3     T*I               0 0 1 1     [<!>X
-2  1 -2 -2     _*T*I             0 1 0 0     *|!TI:
-2  1 -3  1     !-|_I             0 1 0 1     <!I!>X
-2  3  3 -2     ^T*I              0 1 1 0     ^:]<_I
-2  3  3  3     -_T*I             0 1 1 1     *I<-I!
 2 -3 -3 -3     -*|_I             1 0 0 0     ^{!:}I_
 2 -3 -3  2     _|*I              1 0 0 1     _|[<I!:
 1 -2  1 -2     :]I*:             1 0 1 0     _!:|]X
 1 -2  1  1     *I\<X             1 0 1 1     *>I>!I
 2  2 -3 -3     -*I               1 1 0 0     I^:!
 2  2 -3  2     _*I_              1 1 0 1     |I|^:!
 1  2  2 -1     |!:^I             1 1 1 0     -I*<*I
 1  1  1  1     *<X               1 1 1 1     +I+

()у Stack Cats перевіряє, чи є елемент позитивним чи непозитивним (тобто 0 чи негативним), тому ми використовуємо його відповідно для truthy / falesy. Другий стовпець - це лише інтерес і містить найкращі ворота з 0/ 1с як результати (загальний бал 90).

Вхід є розділеними роздільниками бітами через STDIN. Спробуйте в Інтернеті!


Stack Cats - це оборотна езотерична мова, де програми мають рефлексивну симетрію. Давши фрагмент f(наприклад >[[(!-)/), дзеркальне зображення (наприклад \(-!)]]<) обчислює обернену f^-1. Як такі, навіть програми довжини нічого не роблять (або застрягають у нескінченному циклі), і єдині нетривіальні програми мають непарну довжину, обчислюючи, f g f^-1де gцентральний оператор.

Оскільки половина вихідного коду завжди є зайвою, його можна залишити, а запуск коду з -mпрапором означає, що вихідний код повинен бути відображений над останнім символом, щоб отримати фактичний вихідний код. Наприклад, програма *<Xнасправді *<X>*є симетричною.

Гольфінг у Стек Котів є дуже неінтуїтивним, тому вищезазначені програми доводилося шукати грубою силою. Більшість з них напрочуд складні, але я поясню декілька і додаю до цієї відповіді, коли встигну. На даний момент деякі пояснення та альтернативні рішення для 0/ 1версій можна знайти у сховищі Github тут .


1
Note that the +64 is from applying the -nm flags to each program.3 * 16 = 48 або 2 * 16 = 32, так чи інакше 64 - шлях хай
кіт

@cat Праги коштують 4 за програму, оскільки вам доведеться порахувати простір.
FryAmTheEggman

@cat відповідна мета-повідомлення: meta.codegolf.stackexchange.com/questions/273/…
Мартін Ендер

Минуло більше року. У вас ще є час?
CalculatorFeline

8

Haskell, 78 76 75 байт

  1. _#_=2<1
  2. &&
  3. >
  4. pure
  5. <
  6. _#b=b
  7. /=
  8. ||
  9. (not.).max
  10. ==
  11. _#b=not b
  12. >=
  13. a#_=not a
  14. <=
  15. (not.).min
  16. _#_=1<2

Редагувати: -1 байт завдяки @cole.


Я збирався просто прокоментувати "чувак, _#_це не стандартний оператор!" І тоді я зрозумів ... Молодці.
Математична

4 могло бутиpure
cole

@cole: Дякую Нічого собі, він pureбув представлений Preludeще в 2015 році, тому він був доступний під час цього виклику.
німі

6

Брахілог , 36 34 байт

0000 false              \     Backtrack (always false)
0001 p and q            1.    Unify input and output with 1
0010 p and not q        >.    Input > Output
0011 p                  1     Unify input with 1
0100 not p and q        <.    Input < Output
0101 q                  ,1.   Unify output with 1
0110 xor                '.    Input and output cannot unify
0111 p or q             1;1.  Unify input with 1 or unify output with 1
1000 not p and not q    0.    Unify input and output with 0
1001 eq                 .     Unify input with output
1010 not q              ,0.   Unify output with 0
1011 p or not q         >=.   Input >= Output
1100 not p              0     Unify input with 0
1101 not p or q         <=.   Input <= Output
1110 not p or not q     0;0.  Unify input with 0 or unify output with 0
1111 true                     Empty program (always true)

Це розраховує 0як на хибну цінність, так і 1на неправдиву цінність. Повертається trueабо false. p є Inputі q є Output.


Як ви вводите вихід?
Leaky Nun

1
@LeakyNun Як і вхід. Основний предикат, який ви запитуєте, має два аргументи, викликані Inputта Outputумовно, але ви можете встановлювати значення обом або повертати значення з обох.
Фаталізувати

1
Це правильний інструмент для роботи: P
Conor O'Brien

6

Пролог, 147 145 байт

Набрав 2 байти завдяки @SQB

a(a,a).       % 0000 false
b(1,1).       % 0001 P and Q
c(1,0).       % 0010 P and not Q
d(1,_).       % 0011 P
e(0,1).       % 0100 not P and Q
f(_,1).       % 0101 Q
g(P,Q):-P\=Q. % 0110 P xor Q
h(1,_).       % 0111 P or Q
h(0,1).
i(0,0).       % 1000 not P and not Q
j(P,P).       % 1001 P == Q                 
k(_,0).       % 1010 not Q
m(P,Q):-P>=Q. % 1011 P or not Q
n(0,_).       % 1100 not P              
r(P,Q):-P=<Q. % 1101 not P or Q         
s(0,_).       % 1110 not P or not Q
s(1,0).
t(_,_).       % 1111 true

Запит x(P,Q).з xє відповідним листом і Pі Qвстановити на 0 або 1.
Повертає trueабо false.

Приклад SWISH, включаючи тести - введіть runTest.для запуску.


Чи підтримує це a(2,2).помилкове?
jimmy23013

@ jimmy23013 Я думаю, це могло б, якщо я припускаю, що 2 - хибний. Не впевнений, що це прийнятно.
Фаталізувати

@ jimmy23013 Насправді, a(a,a).(або будь-який інший лист) теж працює і aне є прийнятним вкладом для правдивості, тому це добре. Дякую за пропозицію.
Фаталізувати

6

NTFJ, 86 байт

0000 false              ~
0001 p and q            |:|
0010 p and not q        :||:|
0011 p                  $
0100 not p and q        #{:||:|
0101 q                  #{$
0110 xor                :#{:#{:||#}:|||
0111 p or q             :|#{:||
1000 not p and not q    :|#{:||:|
1001 eq                 :#{:#{:||#}:|||:|
1010 not q              #{$:|
1011 p or not q         #{:||
1100 not p              $:|
1101 not p or q         :||
1110 not p or not q     |
1111 true               #

Спробуйте тут! Але читайте спочатку нижче.

Введення неявне в стеці. Результат випускається на стек. Додайте 16 байт (по одному *в кінці кожного), якщо ви хочете 0x00або 0x01виведіть 0 і 1. Додайте додаткові 160 байт, якщо ви хочете друкувати 0або 1. (Поставте ~~##~~~#{@перед кожним *.)

Єдиний бінарний оператор NTFJ - це NAND, тому кожен із них записується у формі NAND.

Давайте переглянемо кожну з них.

0: хибно

~

~представляє помилковий біт. Досить просто. Оскільки введення неявне в нижній частині стека, це залишається вгорі.

1: р і q

|:|

NTFJ працює на стеці. :є командою для дубліката. Зауважте, що p and qnot (p nand q)і це not q = q nand q.

Command | Stack
        | p q
   |    | (p nand q)
   :    | (p nand q) (p nand q)
   |    | (p nand q) nand (p nand q)
        | => not (p nand q)
        | => p and q

(Тоді зауважте, :|можна сказати, що це заперечення і |:|може бути сполученням )

2: р і не q

:||:|

Зауважте, що це просто заперечення :|і сполучник |:|.

Command | Stack
        | p q
  :|    | p (not q)
  |:|   | p and (not q)

3: с

$

$вискакує предмет із стека. Отже ... так.

4: не р і q

#{:||:|

Це те саме, що і 2, за винятком #{на початку. #натискає 1 (справжній біт) і {один раз обертає стек, що залишився. Досить просто.

5: q

#{$

Поверніть один раз ліворуч, опустіть.

6: xor

:#{:#{:||#}:|||

Дотримуйтесь:

p xor q = (p and (not q)) or ((not p) and q)                ; by experimentation (trust me)
        = (not ((not p) nand q)) or (not (p nand (not q)))  ; by definition of nand
        = not (((not p) nand q) and (p nand (not q)))       ; by De Morgan's laws
        = ((not p) nand q) nand (p nand (not q))            ; by definition of nand

Однак немає можливості повністю дублювати стек. Таким чином, ми будемо мати , щоб привести кожного з p, qу верхній і дублювати його.

Command | Stack
        | p q
   :    | p q q
  #{    | q q p
   :    | q q p p
  #{    | q p p q
  :|    | q p p (not q)
   |    | q p (p nand (not q))
  #}    | (p nand (not q)) q p
  :|    | (p nand (not q)) q (not p)
   |    | (p nand (not q)) (q nand (not p))
   |    | (p nand (not q)) nand (q nand (not p))

Таким чином, ми маємо свій ксьор.

7: p або q

:|#{:||

Негативні вершини, піднесіть донизу вгору, заперечте це і з'єднайте їх. В основному p or q = (not p) nand (not q).

8: не р і не q

:|#{:||:|

Це просто заперечення 7. Легко.

9: екв

:#{:#{:||#}:|||:|

Це просто xnor , чи не xor. Знову просто.

10: не q

#{$:|

Заперечення 5.

11: p чи ні q

#{:||

Negate p, nand. (not p) nand q = not ((not p) and q) = p or (not q) (by De Morgan's laws).

12: не с

$:|

Кидайте, зупиняйте та заперечуйте.

13: не p чи q

:||

Закони Де Моргана, щоб врятувати день! Такий самий процес, що і 11, лише заперечення qзамість p.

14: не p чи ні q

|

Це просто мімічний нанд.

15: правда

#

# - справжній біт.


тільки чому ...> _>
Rɪᴋᴇʀ

idk саме як це працює, але здається досить крутим +1
Downgoat

Чому 5 не просто порожня програма, а 10 просто :|?
Йофан

6

Minecraft, 89 блоків

На всіх наступних фотографіях сині блоки призначені для вводу A, а помаранчеві - для вводу B

16. ІСТИНА ворота - 1 блок

введіть тут опис зображення

15. NAND ворота - 1x2x3 = 6 блоків

введіть тут опис зображення

14. A => B - 1x2x3 = 6 блоківвведіть тут опис зображення

13. НЕ А - 2 блоки введіть тут опис зображення

12. В => А - 1х2х3 = 6 блоківвведіть тут опис зображення

11. НЕ Б - 2 блоки введіть тут опис зображення

10. XNOR - 1x3x4 = 12 блоків введіть тут опис зображення

9. NOR - 1x2x3 = 6 блоківвведіть тут опис зображення

8. АБО - 1 блок введіть тут опис зображення

7. XOR - 1x3x4 = 12 блоків введіть тут опис зображення

6. Б - 1 блок введіть тут опис зображення

5.! A&B - 1x2x5 = 10 блоків введіть тут опис зображення

4. А - 1 блок введіть тут опис зображення

3. A &! B - 1x2x5 = 10 блоків введіть тут опис зображення

2. І - 2x2x3 = 12 блоків введіть тут опис зображення

1. FALSE-1 блоки введіть тут опис зображення


2
У другому до останнього зображення (І) ви могли зберегти 6 блоків, поставивши факели зверху на задню частину блоків, тобто навпроти важелів. Поміняйте пальник посередині на шматочок пилу і видаліть пил вгорі, збивши його до 1x2x3 = 6 блоків.
Лука H

5

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

0>1&
And
#&&!#2&
#&
!#&&#2&
#2&
Xor
Or
Nor
Xnor
!#2&
#||!#2&
!#&
!#||#2&
Nand
1>0&

Кожен з них оцінює функцію, тож ви можете їх використовувати як би

#&&!#2&[True, False]
Xor[True, False]

Ах, якби в Mathematica були лише цілі числа, що були тритужними / хибними, ці чотири довші можна було б значно скоротити.


Якщо цілі числа не є truthy / falsey, що відбувається, якщо ви помістите їх у оператор if?
Conor O'Brien

3
@ CᴏɴᴏʀO'Bʀɪᴇɴ вона залишається неоціненою.
Мартін Ендер

5

MATL, 34 23 байти

Я сподіваюся, що я отримав замовлення в порядку! Нуль - це фальси, ненульовий - правда. Кожна функція приймає два неявні входи (хоча деякі входи можуть ігнорувати). Перший вхід - A, а другий - B. Ви можете ввести 0/ 1для істинного / помилкового, або T/ F.

Ось приклад TryItOnline для тестового випадку 3.

Збережено 4 байта, використовуючи *для and, і ще 4 за допомогою >/ <замість ~wY&/ w~Y&після того, як я побачив відповідь Дениса!

1.  0,0,0,0 0 (ignores input, just returns a zero)
2.  0,0,0,1 * (and)
3.  0,0,1,0 < (not-A and B)
4.  0,0,1,1 D (A)
5.  0,1,0,0 > (not-B and A)
6.  0,1,0,1 xD (discard A, display B)
7.  0,1,1,0 Y~ (xor)
8.  0,1,1,1 + (or)
9.  1,0,0,0 +~ (not-or)
10. 1,0,0,1 = (A=B)
11. 1,0,1,0 x~ (not-B)
12. 1,0,1,1 <~ (not-B or A)
13. 1,1,0,0 ~ (not-A)
14. 1,1,0,1 ~+ (not-A or B)
15. 1,1,1,0 *~ (not(A and B))
16. 1,1,1,1 1 (just returns 1)

10
Номер шість вважає це смішним.
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ Число 6 найкраще, мені теж подобається число 12! xD!
Девід

У вас немає функції "нерівності"?
Лина монашка

Ні (принаймні я так не думаю)
Девід

2
@David Я думаю, що номер 7 можна замінити на-
Луїс Мендо

5

постійного струму, 37 байт

dc("настільний калькулятор") - це стандартна команда unix, калькулятор постфіксу на основі стека. У ньому бракує бітових операцій, і оператори порівняння можуть використовуватися лише для виконання макросів (що не варто байтів). Розділ цілого числа складає деяке з цього.

Ці сценарії очікують 0і 1значення на стеку, а результат залишають у стеку.

0,0,0,0 (false)              0
0,0,0,1 (and)                *         a*b
0,0,1,0                      -1+2/     (a-b+1)/2
0,0,1,1 (A)                  r         reverse a, b: a now on top
0,1,0,0                      -1-2/     (a-b-1)/2
0,1,0,1 (B)                            (0 bytes) do nothing: b on top
0,1,1,0 (xor)                -         a-b
0,1,1,1 (or)                 +         a+b                  
1,0,0,0 (nor)                +v1-      sqrt(a+b) -1
1,0,0,1 (xnor)               +1-       a+b-1
1,0,1,0 (not B)              1-        b-1
1,0,1,1 (if B then A)        -1+       a-b+1
1,1,0,0 (not A)              r1-       a-1
1,1,0,1 (if A then B)        -1-       a-b-1            
1,1,1,0 (nand)               *1-       a*b - 1
1,1,1,1 (true)               1

5

Лабіринт , 85 байт

Завдяки Sp3000 за збереження 2 байт.

!@
??&!@
??~&!@
?!@
?~?&!@
??!@
??$!@
??|!@
??|#$!@
??$#$!@
?#?$!@
?#?$|!@
?#$!@
?#$?|!@
??&#$!@
1!@

Все це - повні програми, зчитування двох цілих чисел 0або 1з STDIN (використовуючи будь-який нерозрядний роздільник) та друк результату як 0або 1до STDOUT.

Спробуйте в Інтернеті! (Не тестовий набір, тому вам доведеться спробувати різні програми та введення вручну.)

Що стосується пояснень, то всі вони досить прості. Усі програми лінійні, а використовувані команди виконують наступне:

?   Read integer from STDIN and push.
!   Pop integer and write to STDOUT.
@   Terminate program.
&   Bitwise AND of top two stack items.
|   Bitwise OR of top two stack items.
$   Bitwise XOR of top two stack items.
~   Bitwise NOT of top stack item.
#   Push stack depth (which is always 1 when I use it in the above programs).
1   On an empty stack, this pushes 1.

Зауважте, що я використовую #завжди використовується для комбінування $, тобто для обчислення XOR 1, або іншими словами для логічного заперечення. Лише в кількох випадках я міг використати ~натомість, оскільки наступні &викидає всі небажані біти від отриманого -1або -2.


5

Машинний код IA-32, 63 байти

Hexdump коду, з розбиранням:

0000  33 c0     xor eax, eax;
      c3        ret;

0001  91        xchg eax, ecx;
      23 c2     and eax, edx;
      c3        ret;

0010  3b d1     cmp edx, ecx;
      d6        _emit 0xd6;
      c3        ret;

0011  91        xchg eax, ecx;
      c3        ret;

0100  3b ca     cmp ecx, edx;
      d6        _emit 0xd6;
      c3        ret;

0101  92        xchg eax, edx;
      c3        ret;

0110  91        xchg eax, ecx;
      33 c2     xor eax, edx;
      c3        ret;

0111  8d 04 11  lea eax, [ecx + edx];
      c3        ret;

1000  91        xchg eax, ecx; // code provided by l4m2
      09 d0     or eax, edx;
      48        dec eax;
      c3        ret;

1001  3b ca     cmp ecx, edx;
      0f 94 c0  sete al;
      c3        ret;

1010  92        xchg eax, edx;
      48        dec eax;
      c3        ret;

1011  39 d1     cmp ecx, edx; // code provided by l4m2
      d6        _emit 0xd6;
      40        inc aex;
      c3        ret;

1100  91        xchg eax, ecx;
      48        dec eax;
      c3        ret;

1101  3b d1     cmp edx, ecx; // code inspired by l4m2
      d6        _emit 0xd6;
      40        inc aex;
      c3        ret;

1110  8d 44 11 fe   lea eax, [ecx+edx-2] // code provided by l4m2
      c3        ret;

1111  91        xchg eax, ecx;
      40        inc eax;
      c3        ret;

Код більше , ніж це може бути, тому що воно використовує стандартну угоду кодування: введення в ecxі edx, і вихід в al. Це може бути виражено в C як

unsigned char __fastcall func(int, int);

Здається, що MS Visual Studio не розуміє незадокументованого SALCкоду, тому мені довелося використовувати його код, а не ім'я.

Дякуємо l4m2 за покращення деяких зразків коду!


1
1110 8D4411FE LEA EAX, [ECX+EDX-2]
l4m2

5

C 34 байт

#define g(n,a,b)((n-1)>>3-b-2*a)&1

Де n - номер функції, який слід використовувати, але я думаю, що його буде відмовлено, тому я пропоную цей інший:

C 244 байти (використовуючи пам'ять)

typedef int z[2][2];
z a={0,0,0,0};
z b={0,0,0,1};
z c={0,0,1,0};
z d={0,0,1,1};
z e={0,1,0,0};
z f={0,1,0,1};
z g={0,1,1,0};
z h={0,1,1,1};
z i={1,0,0,0};
z j={1,0,0,1};
z k={1,0,1,0};
z l={1,0,1,1};
z m={1,1,0,0};
z n={1,1,0,1};
z o={1,1,1,0};
z p={1,1,1,1};

він використовує подвійний індексований масив. n[0][1]є(A implies B)(0,1)

Четвертий 138 байт

Я тільки що дізнався Forth. Я вважаю, що це Ansi Forth сумісний, оскільки він працює також на gforth.

: z create dup , 1+ does> @ -rot 3 swap - swap 2* - rshift 1 and ; 
0 
z a z b z c z d z e z f z g z h z i z j z k z l z m z n z o z p 
drop

Функція z створить нову функцію із вказаним іменем, після чого покладіть номер логічного ворота зверху стека до нової адреси функції. Він залишає наступну (n + 1) логічну функцію ворота в стеку для наступного оголошення.

ви можете перевірити:
І AB

0 0 b . cr 
0 1 b . cr
1 0 b . cr 
1 1 b . cr   

("." вершина друку стека "cr" - повернення каретки)


Вам потрібно лише надати фрагменти коду для кожної функції.
CalculatorFeline

4

C, 268 байт

#define c(a,b)0      // 0000 
#define d(a,b)a&b    // 0001 
#define e(a,b)a>b    // 0010 
#define f(a,b)a      // 0011 
#define g(a,b)a<b    // 0100 
#define h(a,b)b      // 0101 
#define i(a,b)a^b    // 0110 
#define j(a,b)a|b    // 0111 
#define k(a,b)!b>a   // 1000 
#define l(a,b)a==b   // 1001 
#define m(a,b)!b     // 1010 
#define n(a,b)!b|a   // 1011 
#define o(a,b)!a     // 1100 
#define p(a,b)!a|b   // 1101 
#define q(a,b)!b|!a  // 1110 
#define r(a,b)1      // 1111 

Макроси здаються коротшими, ніж функції.


4

Брайан і Чак , 183 байти

Завдяки Sp3000 за збереження 4 байтів.

Деякі програми містять недрукований символ. Зокрема, кожного \x01слід замінити <SOH>контрольним символом (0x01):

0000
?
#>.
0001
,-?,-?>?\x01
#}>.
0010
,-?,?>?\x01
#}>.
0011
,?\x01+?
#>.
0100
,?,-?>?\x01
#}>.
0101
,,?\x01+?
#>.
0110
,?>},?>?_\x01
#}+{>?_}>.
0111
,\x01?,?>?
#{>.
1000
,?,?>?\x01
#}>.
1001
,-?>},?>?_\x01
#}+{>>?_}>.
1010
,,-?\x01+?
#>.
1011
,\x01?,-?>?
#{>.
1100
,-?\x01+?
#>.
1101
,\x01-?,?>?
#{>.
1110
,\x01-?,-?>?
#{>.
1111
?
#>+.

Вхідні та вихідні значення використовують байтові значення , тому вхід має бути двома 0x00 або 0x01 байтами (без роздільника), а вихід буде одним таким байтом. Це насправді також найбільш розумне визначення truthy / falesy для B&C, оскільки єдина команда управління потоком ?вважає нулі фальшивими, а все інше - правдою.

Пояснення

Спочатку швидкий ґрунтовник для B & C:

  • Кожна програма складається з двох екземплярів, подібних Brainfuck, кожен написаний у власному рядку. Ми називаємо першого Брайана, а другого Чаком . Розстріл починається на Брайана.
  • Стрічка кожної програми є вихідним кодом іншої програми, а вказівник інструкції кожної програми - головою стрічки іншої програми.
  • Тільки Брайан може використовувати команду ,(вхідний байт), і тільки Чак може використовувати команду .(вихідний байт).
  • []Петлі Brainfuck не існує. Натомість єдиний у вас керуючий потік - ?це перемикання управління на інший екземпляр, якщо поточне значення під головкою стрічки є ненульовим.
  • У доповненні до >і <, є {і }які по суті еквівалентні фрагменти Brainfuck [<]і [>], тобто, вони рухають голову стрічки до наступної нульовій позиції в цьому напрямку. Основна відмінність полягає в тому, що {її можна зупинити і на лівому кінці стрічки, незалежно від того, яке значення вона має.
  • Для зручності будь-які _s у вихідному коді замінюються нульовими байтами (оскільки вони дуже корисні в нетривіальних програмах для того, щоб ловити {і }).

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

Існує п’ять класів програм, про які я детально поясню пізніше. На даний момент я перелічу їх тут, щоб збільшити складність.

0000, 1111: Постійні функції

?
#>.
?
#>+.

Це дуже просто. Ми переходимо на Чак беззастережно. Чак переміщує головку стрічки до невикористаної комірки праворуч і друкує її безпосередньо, або збільшує спочатку для друку 1.

0011, 0101, 1010, 1100: Функції в залежності від тільки один вхід

,?\x01+?
#>.
,,?\x01+?
#>.
,,-?\x01+?
#>.
,-?\x01+?
#>.

Залежно від того, ми починаємо з ,чи ,,працюємо ми з Aабо B. Давайте розглянемо перший приклад 0011(тобто A). Прочитавши значення, ми використовуємо ?як умовне це значення. Якщо A = 1, тоді це перемикається на Чак, який переміщує головку стрічки вправо і друкує буквально вбудований 1-байт. В іншому випадку контроль залишається на Брайана. Тут 1-байт - неоперативний. Тоді ми збільшуємо вхід добре, +щоб переконатися, що він не дорівнює нулю, а потім переходимо на Чак з ?. Цього разу >переходить до невикористаної комірки праворуч, яка потім друкується як 0.

Для того, щоб заперечувати одне із значень, ми просто декрементуємо його -. Це перетворюється 1в 0і 0в -1, який не дорівнює нулю і , отже , truthy, наскільки ?стурбований.

0001, 0010, 0100, 1000: Бінарні функції з одним truthy результат

,-?,-?>?\x01
#}>.
,-?,?>?\x01
#}>.
,?,-?>?\x01
#}>.
,?,?>?\x01
#}>.

Це розширення попередньої ідеї для роботи з двома входами. Давайте розглянемо приклад 1000(NOR). Ми (потенційно) читаємо обидва входи за допомогою ,?. Якщо будь-яке з них є 1, ?перемикає на Чак. Він переміщує головку стрічки до кінця }(на порожню комірку після коду Брайана), переміщує іншу комірку з >(все ще нуль) і друкує її ..

Однак якщо обидва входи дорівнюють нулю, то керування все ще здійснюється за допомогою Брайана. >потім переміщує головку стрічки на }таку, що ця команда не виконується, коли ми переходимо на Чак ?. Тепер усе, що робить Чак, - >.це лише те, що рухається на 1-клітинку і це друкує.

Ми можемо легко отримати інші три функції, відкинувши один або обидва входи у міру необхідності.

0111, 1011, 1101, 1110: Бінарні функції з трьома truthy результатами

,\x01?,?>?
#{>.
,\x01?,-?>?
#{>.
,\x01-?,?>?
#{>.
,\x01-?,-?>?
#{>.

Невелика модифікація попередньої ідеї з метою заперечення результату (тобто надрукування, 0коли ми пройшли всю Брайан та 1інше). Давайте розглянемо 0111(АБО) як приклад. Зауважте, що вбудований 1-байт - це не-оп, тому це все ще починається з ,?,?. Якщо будь-який вхід, 1ми переходимо до Чука, який переміщує головку стрічки назад до початку {. >.переміщує головку стрічки на цей 1-байт і друкує її.

Якщо обидва входи дорівнюють нулю, ми залишаємося з Брайаном, перемістіть стрічку на стрічку, {щоб пропустити її, а потім переключитесь на Чак. Коли він виконує >.цей час, він рухається до порожньої комірки після коду Брайана і друкує 0.

Знову ж таки, ми легко отримуємо інші функції, відкидаючи один або обидва входи.

0110, 1001: Бінарні функції з двома результатами

,?>},?>?_\x01
#}+{>?_}>.
,-?>},?>?_\x01
#}+{>>?_}>.

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

Основна ідея полягає в тому, щоб використовувати перший вхід , щоб вирішити , буде чи другий вхід вибрати 0і 1чи між 1і 0. Візьмемо 0110для прикладу (XOR):

Розглянемо A = 0. У цьому випадку ми хочемо вивести так, Bяк є. ,читає A, ?нічого не робить. >рухається до наступної (ненульової) комірки, так що }приводить нас до _Чака. Тут ми читаємо Bз ,і використовувати ?знову. Якщо так Bбуло 0, ми все ще на Брайані. >пропускає }Чак і ?перемикається так, щоб >.друкувати 0вбудований у вихідний код Брайана. Якщо це Bбуло 1з іншого боку, Чак виконує те, }що переміщується в _код Брайана, тож натомість >.друкує 1-байт.

Якщо A = 1тоді ми переходимо на Чак відразу, хто виконає }+{>?. Для цього потрібно перейти до _вихідного коду Брайана, перетворити його на 1а +, потім повернутись до початку {та пропустити Брайана, ?перемістивши одну клітинку праворуч, >перш ніж повернути йому керування. Цього разу, після того, як Брайан прочитає B, якщо B = 0, а Чак використовує >.клітинку поруч із Брайаном, ?буде 1замість 0. Крім того, коли B = 1Чак }пропускає прямо над тим, що раніше був проміжок, і переміщується до кінця стрічки, щоб >.натомість надрукувати нуль. Таким чином ми друкуємо not B.

Щоб реалізувати еквівалентність, ми просто заперечували Aперед тим, як використовувати її як умову. Зауважте, що завдяки цьому нам також потрібно додати ще одного >до Чака, щоб пропустити це -, а також під час повернення до початку.


4

ClojureScript, 88 84 76 74 байт

nilі falseє хибними, усі інші цінності - неправдиві. Булеви примушують до 0/1 для арифметики та нерівностей. Функції можуть приймати неправильну кількість аргументів.

0000   nil?            ; previously: (fn[]nil)
0001   and
0010   <
0011   true?           ; previously: (fn[x]x)
0100   >
0101   (fn[x y]y)
0110   not=
0111   or
1000   #(= 0(+ % %2))
1001   =
1010   #(not %2)
1011   <=
1100   not
1101   >=
1110   #(= 0(* % %2))
1111   /               ; previously: (fn[]4), inc

Хіба не 0фальшивий?
Leaky Nun

2
Не в ClojureScript.
MattPutnam

@LeakyNun Не в більшості LISP або функціональних мов програмування, що Clojure безумовно є
кіт

@cat Так у більшості функціональних мов програмування! Python, наприклад, оцінює , not not(0)щоб False, який є falsey значення.
Ерік Аутгольфер

3
@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Er ... Python не є ні чисто функціональним, ні типом функціональної мови, про який я говорю. Python є головним чином імперативним і має деякі менші (погано виконані) функціональні аспекти. Erlang, Haskell (я думаю), Common LISP, Clojure, ракетка, схема, фактор, Standard ML, Objective CAML і т.д. 0 це просто інше значення , і в результаті truthy, і символ помилковою ( #f, f, falseі т.д.) є помилковий. Усі інші значення в більшості функціональних мов є правдивими.
кіт

4

Brainfuck , 184 178 174 байт

Для введення / виводу використовується U + 0000 та U + 0001.

0000 .
0001 ,[,[->+<]]>.
0010 ,[,-[+>+<]]>.
0011 ,.
0100 ,-[,[->+<]]>.
0101 ,,.
0110 ,>,[-<->]<[>>+<]>.
0111 ,-[,-[+>-<]]>+.
1000 ,-[,-[+>+<]]>.
1001 ,>,[-<->]<[>>-<]>+.
1010 ,,-[+>+<]>.
1011 ,-[,[->-<]]>+.
1100 ,-[+>+<]>.
1101 ,[,-[+>-<]]>+.
1110 ,[,[->-<]]>+.
1111 +.

Читання умовного другого входу виглядає дорого. Напр., Чи 0001не могли ви просто зробити ,[,>]<.(дано перекладача, який дозволяє перейти ліворуч від вихідної комірки)?
Мартін Ендер

@MartinEnder Я подумав, що я не просто копіюватиму відповідь Деніса сюди.
Leaky Nun

4

Мозг-Флак , 418 , 316 байт

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

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

неправдиво, 4 байти (люб’язно з Лікі монахині )

(<>)

і, 36 байт

(({}{}[(())()])){{}{}(((<{}>)))}{}{}

А, а не В, 40 байт

((({}){}{}[(())()])){{}{}(((<{}>)))}{}{}

А, 6 байт

({}<>)

не A і B, 38 байт

((({}){}{}[(())])){{}{}(((<{}>)))}{}{}

Б, 2 байти

{}

xor, 34 байти

(({}{}[(())])){{}{}(((<{}>)))}{}{}

або, 6 байт

({}{})

ні, 34 байти

(({}{}<(())>)){{}{}(((<{}>)))}{}{}

xnor, 10 байт

({}{}[()])

не В, 34 байти

{}(({}<(())>)){{}{}(((<{}>)))}{}{}

B означає A, 14 байт

(({}){}{}[()])

не A, 34 байти

(({}<{}(())>)){{}{}(((<{}>)))}{}{}

A означає B, 16 байт

(({}){}{}[()()])

нанд, 12 байт

({}{}[()()])

правда, 6 байт

<>(())

Пояснення

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

По-перше, це ворота, які повертають три однакові значення (тобто 2, 3, 5, 8, 9, 12, 14 і 15). Усі вони дотримуються тієї ж схеми. Спочатку ви перетворюєте вхід у дворозрядне число з а, як двозначне місце, і В як одне. Це робиться за допомогою цього фрагмента (({}){}{}). Потім ви віднімаєте значення двох бітових входів, які ви хочете ізолювати ({}[value]). (У фактичному коді віднімання та перетворення виконуються в один крок для збереження байтів). Це може поєднуватися з не в разі потреби: (({}<(())>)){{}{}(((<{}>)))}{}{}.

Далі вгору: і, ні, або, xor і xnor. Вони працюють аналогічно вищезгаданим. Насправді деякі з них включені вище, проте цей метод коротший. Я використав тут хитрість, що вони відповідають сумі A B. Наприклад, xor оцінюється як true, якщо A + B = 1, а в іншому - false. Спочатку ви додаєте AB і віднімаєте відповідну суму. Виражено як ({}{}[0,1,2 or 3]). Тоді при необхідності проводять ні

Далі: A, B, не A і не B. Вони, як правило, пояснюють себе. Ми починаємо з видалення зайвого значення, а потім або заперечуємо, або закінчуємо.

Нарешті, це два простого: істинний і хибний. Для цього ми висуваємо правильне значення на вимкнений стек. У <>nilad повертає нуль , тому ми можемо зберегти два байта за допомогою перемикача в якості нульового значення.

Не найефективніше рішення там (можливо, найефективніше в Brain-Flak), але мені було дуже цікаво писати це, і я закликаю вас спробувати скоротити їх.


(<>)достатньо для false; також, (<{}{}>)8 байт
Leaky Nun

Ух, у мене було набагато суворіше визначення виклику. Дякую. Я скорочу це значно
Пшеничний майстер

Що ви маєте на увазі?
Leaky Nun

Я подумав, що мені доведеться видалити наявні входи і розмістити результат на його місці. (<>)залишить входи та поставить нуль на інший стек.
Пшеничний майстер

1
Чи не <>досить falseз - за приховані нулі? Також я думаю, що це aможе бути порожня програма. trueможе бути <>[][](не зберігає байти, але виглядає круто: P).
CalculatorFeline

4

ProgFk , 18,5 17,5 байт

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

3
E1
DE 2D
<empty>
DE 1
1
E3
E2
E2 D
E3 D
1D
DE 2
D
DE 1D
E1 D
4

Пояснення

ProgFk - це стрічковий езоланг (схожий на Brainfuck), де кожна клітинка є трохи, а інструкції надаються у вигляді гризків (4 байти). Інструкції діють на клітинку, на яку вказує вказівник. Вхідні дан в першій і другій клітин (з Aі Bбути першою і другою клітини відповідно), а покажчик команд починається з першого осередку. Вихідні дані зберігаються в першій комірці.

Кожна використана інструкція пояснюється нижче.

1   Increment the instruction pointer.
2   Decrement the instruction pointer.
3   Set the current bit to 0.
4   Set the current bit to 1.
D   Perform a NOT on the current bit.
E   The next instruction is an extended instruction.

Extended instructions:
1   Set the current bit to the current bit AND the next bit.
2   Set the current bit to the current bit OR the next bit.
3   Set the current bit to the current bit XOR the next bit.
6   Swap the current bit and the next bit.

Збережено байт завдяки @LeakyNun!


4

Власне, 24 байти

Ці програми приймають дані як A\nB(із \nподанням нового рядка), який залишає B вгорі стека, а A - внизу. Falseпредставлений 0і Trueпредставлений будь-яким натуральним числом.

é0  (false: clear stack, push 0)
*   (and: multiply)
<   (A and not B: less-than)
X   (A: discard B)
>   (B and not A: greater-than)
@X  (B: discard A)
^   (A xor B: xor)
|   (A or B: or)
|Y  (A nor B: or, boolean negate)
=   (A xnor B: equals)
@XY (not B: discard A, boolean negate B)
≤   (if B then A: less-than-or-equal)
XY  (not A: discard B, boolean negate)
≥   (if A then B: greater-than-or-equal)
*Y  (A nand B: multiply, boolean negate)
é1  (true: clear stack, push 1)

Завдяки Leaky Nun за 3 байти

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