Зворотну полярність


12

Мета цього завдання - написати програму, яка задовольняє наступним умовам:

  • Програма не є паліндромною, або по суті паліндромною (це означає, що можна видалити символи, щоб зробити її паліндром без зміни ефектів програми).

  • Програма не є інволюцією (це означає, що вона не виробляє свого початкового вводу при запуску на своєму виході)

  • Програма зворотної полярності - обернена нормальна програма; тому коли повернена програма запускається на виході звичайної програми, вона повертає початковий вхід.

Що означає зворотна полярність ? Ну, це відрізняється між мовами.

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

Приклади:

Haskell : x`mod`y-> y`mod`x; zipWith ((*3).(+)) [1,2,3] [4,5,6]->zipWith ((+).(*3)) [6,5,4] [3,2,1]

Пітон : 2**3-> 3**2; for x,y in [(1,2),(3,4),(5,6)]->for y,x in [(6,5),(4,3),(2,1)]

  • Для мов, які мають 1-символьні функції (наприклад, Pyth, APL), просто переверніть рядок інструкцій

  • Для одновимірних езолангів, таких як BF, перевірте інструкції або поміняйте полярність; полярність свопи []-> {}, +-> -, --> +, >-> <, <-> >, .-> ,і ,-> .(але не обидва)

  • Для двовимірних езолангів, таких як Befunge, ви можете або виконати віддзеркалення по осях x або y, або по діагоналі, повернути на 180 градусів або зробити комбінацію відбиття та обертання

Допускаються коммутаційні операції, але паліндромні - не: 2*xдобре, але x+xпогано. Визначення зворотності полярності є досить розкутим, але використовуйте судження щодо того, що має сенс; об'єкт не в пошуку найрозумнішої лазівки, а в пошуку найрозумнішого рішення.

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

ОНОВЛЕННЯ

Минуло рівно 1 місяць з початку цього конкурсу (я випадково випадково перевірив його, не знаючи, що я насправді вчасно). Оскільки це змагання за популярність, переможцем (зсувом) став Pietu1998-Befunge . Незважаючи на те, що нижні компоненти (текстовий реверс та алфавіт назад) є обома інволюціями, кодер / декодер - це не так, що тут немає жодної проблеми. Бонусні бали (на мій погляд) за те, що вдалося написати "ПОВЕРНЕННЯ" в середині. Мені особисто сподобалась новизна рішення Тезея Згарба , адже мова виглядає круто (якщо обмежено). Дякую всім за участь, і, хоча переможця було визначено, я залишаю цей конкурс повністю відкритим і вітаю майбутні подання.


1
Що ви маєте на увазі під програмою зворотної полярності - обернена нормальна програма? Чи відрізняється вихід певним чином?
Sp3000

Він виконує зворотну операцію; коли повернена програма запущена на виході звичайної програми, вона повертає вихідний вхід.
архефірикс

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

1
Просто щось, що, мабуть, слід вказати - ()паліндромний? Технічно навпаки )(.
Sp3000

1
У прикладі Haskell чому аргумент функції не переміщується до кінця? Чи обрані реверси таким чином, щоб зберегти безпеку типу? Чи дозволяється нам вибирати деякі деталі операції зміни полярності?
Джон Дворак

Відповіді:


41

Befunge

Ого, це була робота, навіть з редактором, який я зробив для цього виклику. Ось що я отримав, хороший блок розміром 11x12:

v$,g6<6g,$v
v,$ _^_ $,v
1W>v\B\v>L1
~T+:1E1:-O~
+F00-F-02L+
>:|6gUg6|:>
{a@>^N^>@z`
>1+|@G$| +>
:^9< E<  ^1
~>7^@_,#:>:
 xD>65 ^=P~
v,-\+**<  v

Це робить пару речей, на жаль лише для малих літер.

Що це робить

Коли працює нормально, він виконує шифр Цезаря на вході.

abcxyz      -> bcdyza
exampletext -> fybnqmfufyu

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

bcdyza      -> abcxyz
fybnqmfufyu -> exampletext

Коли повертається вертикально , він шифрує введення зворотним алфавітом. Це можна вважати протилежним підходом до шифру Цезаря.

abcxyz      -> zyxcba
exampletext -> vcznkovgvcg

Нарешті, повернувшись на 180 градусів, вона повертає вхід. У мене таке відчуття, що це має бути реверсом чогось (натяк: введення).

abcxyz      -> zyxcba
exampletext -> txetelpmaxe

Як це працює

В основному блок складається з чотирьох алгоритмів напівперекриття.

Шифровий кодер Цезаря

v$,g6<
v,$ _^
1 >v\
~ +:1
+ 00-
>:|6g
{a@>^

Шифровий декодер Цезара (повернутий горизонтально)

v$,g6<
v,$ _^
1 >v\
~ -:1
+ 20-
>:|6g
`z@>^

Шифр зворотного алфавіту (повернутий вертикально)

v,-\+**<
   >65 ^
~>7^
:^9<
>1+|@
   >^

Текстовий реверс (повернутий на 180 градусів)

v  <
~      
:>:#,_@
1^  <
>+ |$
   >^

2
Я припускаю, що Befunge має невелику перевагу тут, тому що ви завжди можете просто використовувати верхній лівий квадрант і повністю ігнорувати те, що в решті коду. Хороша робота, хоча!
Мартін Ендер

1
Оце Так! Я ХОЧУ підняти це, хоча це означає, що я опускаюся на третє місце.
Річка Рівня Св.

18

Brainfuck, 5

,+.-,

Можливо, вперше Brainfuck виробляє відповідь, яка є конкурентоспроможною за довжиною коду. Сором, це не кодове питання про гольф.

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

* (або про те, щоб зробити щось корисне з усім кодом в обох напрямках)

Типові результати (другий символ, якщо вказано, ігнорується).

Вперед: B->C

Реверс: B-> Aабо C->B


11

Марбельний

Ось простий, щоб почати нас. Він читає один символ із STDIN, збільшує та друкує його.

--
]]
00
]]
++

Якщо повернути це на 180 ° (не змінюючи дужки) або віддзеркалити його по осі x, ми отримаємо

++
]]
00
]]
--

який читає байт зі STDIN і зменшує його.

Ви можете протестувати його тут .

Я можу розглянути кілька складніших програм Marbelous, але я впевнений, що es1024 обіграє мене. ;)

Пояснення

Це 00мармур зі значенням 0 (що є довільним). Ці ]]пристрої зчитують байти з STDIN - тобто, якщо мармур падає через них, вартість у Мармурової було змінено в читанні байт. ++І --пристрій просто збільшувати або зменшувати значення мармурового ( в мод 256) , і нехай вона провалиться. Коли мармур падає з дошки, байт пишеться в STDOUT.

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


Ви також можете замінити три середні ряди одним пристроєм введення.
суперактор

@overactor Або ти маєш на увазі }0і використовуєш його як дошку?
Мартін Ендер

}0як введення командного рядка, щоб бути точним.
суперактор

5

Марбельний

Ця рада бере один аргумент ( x) і повертається (101 * x) mod 256.

.. @5 .. }0 }0 @1 .. @0 .. @2 .. 
.. /\ Dp << \\ .. &0 >0 &1 .. .. 
!! @3 .. << }0 .. \/ -- \/ .. }0 
@4 .. .. &0 @1 /\ &0 65 &1 /\ @2 
/\ Dp .. @4 .. .. @3 @0 @5 !! \\

Дзеркальне відображення комірок уздовж осі y призведе до отримання дошки, яка бере один аргумент ( y) і повертається (101 * y + 8 * y) mod 256, що є зворотною стороною першої дошки.

.. @2 .. @0 .. @1 }0 }0 .. @5 ..
.. .. &1 >0 &0 .. \\ << Dp /\ ..
}0 .. \/ -- \/ .. }0 << .. @3 !!
@2 /\ &1 65 &0 /\ @1 &0 .. .. @4
\\ !! @5 @0 @3 .. .. @4 .. Dp /\

Перевірте це тут . Циліндричні дошки та бібліотеки, що включають, повинні бути перевірені.

Приклад введення / виводу :

Original Board:      Mirrored Board:
Input   Output       Input    Output
025     221          221      025
042     146          146      042
226     042          042      226

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

101було обрано з двох причин: це основний (і кожен можливий вхід до цієї програми призводить до унікального виходу), і обернена операція 109, що займається , що є зручною відстані в 8 від 101.

Коротке пояснення

Стовпець, що містить комірки (зверху вниз), @0 >0 -- 65 @0працює однаково на обох дошках і циклічно 101повторюється перед тим, як направлятися праворуч. По обидва боки >0відгалуження - різний синхронізатор; яку вибрати - залежить від того, чи є дзеркальна плата чи ні.

З кожної сторони, синхронізуючись із центральною петлею, вхід повторно підсумовується, отримуючи таким чином 101*x mod 256. На оберненій дошці дві копії входу також двічі зміщуються вліво ( input * 4), потім підсумовуються та залишаються в синхронізаторі.

Після завершення центральної петлі підсумований мармур відправляється для друку, який знаходиться збоку дошки (зліва для оригінальної дошки, правою для дзеркального відображення). Після друку !!досягається комірка, що закінчує дошку. Зауважте, що цикл, який надав, 101 * xпродовжує працювати сам, доки плата не припиняється.

Dp просто виводить результат у вигляді десяткового числа.


5

Тесей

Це може розглядатися як лазівка, але мені подобається мова, тому тут йдеться. Ця програма визначає функцію fна натуральних числах, яка відображає від 3n до 3n + 1 , 3n + 1 до 3n + 2 і 3n + 2 до 3n для кожного n .

data Num = Zero | Succ Num

iso f :: Num <-> Num
  | n                          <-> iter $ Zero, n
  | iter $ m, Succ Succ Succ n <-> iter $ Succ m, n
  | iter $ m, Succ Succ Zero   <-> back $ m, Zero
  | iter $ m, Succ Zero        <-> back $ m, Succ Succ Zero
  | iter $ m, Zero             <-> back $ m, Succ Zero
  | back $ Succ m, n           <-> back $ m, Succ Succ Succ n
  | back $ Zero, n             <-> n
  where iter :: Num * Num
        back :: Num * Num

Тесей - це оборотна мова з синтаксисом, що нагадує Haskell, де кожна функція є зворотною (дисконтування проблем із припиненням). Він високо експериментальний і розроблений для наукових цілей. Вищевказаний код визначає тип даних для натуральних чисел та функцію f. Враховуючи номер введення, ви узгоджуєте його по лівій частині (він завжди відповідає n). Потім ви дивитеся на візерунок праворуч. Якщо на цьому шаблоні є ярлик (тутiter), ви переходите до узгодження шаблону з лівого боку та знову приймаєте відповідне значення праворуч. Це повторюється, поки у вас не буде маркованого значення праворуч, і це ваш вихід. Шаблони зліва та справа повинні бути вичерпними та не перекриватись (окремо для кожної мітки). Тепер, щоб "змінити полярність" f, я роблю наступне.

  • Замініть два значення кожної мітки. Це не змінює семантику f.
  • Замініть правою та лівою сторонами в тілі функції. Це визначає зворотну функцію f конструкції .

Результат:

iso f :: Num <-> Num
  | iter $ n, Zero             <-> n
  | iter $ n, Succ m           <-> iter $ Succ Succ Succ n, m
  | back $ Zero, m             <-> iter $ Succ Succ Zero, m
  | back $ Succ Succ Zero, m   <-> iter $ Succ Zero, m
  | back $ Succ Zero, m        <-> iter $ Zero, m
  | back $ Succ Succ Succ n, m <-> back $ n, Succ m
  | n                          <-> back $ n, Zero
  where iter :: Num * Num
        back :: Num * Num

3

тр

a b

Приклад:

$ echo "apple" | tr a b
bpple
$ echo "bpple" | tr b a
apple

Тільки справжня зворотна область доменних рядків, яка не включає в себе і 'a', і 'b'.


Насправді потрібно трохи обмежити домен. Наприклад, якщо ви починаєте з "bog", вашій програмі та її зворотному напрямку дається "bog" -> "bog" -> "aog". Отже, будь-яка рядок, що містить "b", є проблемою (або містить "a", якщо спочатку застосувати зворотну програму).
користувач19057

Можна використовувати tr abc bcaз версією із зворотною полярністю tr acb cba.
Крістіан Сіверс

2

Ще одна марбелівська відповідь

Початкове право зміщує введення командного рядка (значення 8 біт), додаючи провідне, якщо 1 втрачається при зміщенні. ( 0000 0001 -> 1000 0000)

{0 ..
~~ ..
>> {0
-2 =0
.. ^0
\/ }0
}0 Sb
<< ..
\\ ..
:Sb
// ..
Sb >>
}0 ..
^7 }0
{0 \/

Обертання цієї дошки на 180 ° (але залишаючи вміст кожної комірки однаковим) Змінює програму так, щоб вона залишала зрушення ( 1000 0000 -> 0000 0001)

\/ {0
}0 ^7
.. }0
>> Sb
.. //
:Sb
.. \\
.. <<
Sb }0
}0 \/
^0 ..
=0 -2
{0 >>
.. ~~
.. {0

Ви можете протестувати його тут . (вам потрібно ввімкнути "Відображати вихід у вигляді десяткових чисел")

Пояснення

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

original:      flipped:
   }0          }0
}0 Sb          .. }0
<< ..          >> Sb
\\ ..          .. //

Це досить прості дошки, обидва беруть дві копії вхідних даних (які займають місце }0комірок. Оригінальний подає одну версію в лівий пристрій зсуву <<. Перевернута версія поміщає її в пристрій правого зсуву. >>Вони виконують перехід на біт, але, на жаль, відкидають будь-яку втрачені біти. Там, куди Sbпотрапляють дошки, вони перевіряють, чи зміна значення, яке вони подають, призведе до втрати трохи і поверне значення, яке додається до результату, щоб протидіяти втраченому біту.

Ось відповідна частина оригінальної Sbдошки для оригінальної програми:

}0
^7
{0

Це неймовірно просто, "^ 7" перевіряє значення найзначнішого біта. Якщо цей 1, виконання зсуву вліво призведе до втрати цього біта. Таким чином, ця плата виводить значення цього біта як 8-бітове значення, яке потрібно додати до результату біт-зміщення.

Для перевернутої версії, Sbслід переглянути щонайменше суттєвий біт і повернути 128або 0, це трохи складніше:

}0
^0 ..
=0 -2
{0 >>
.. ~~
.. {0

Якщо найменше значущий біт (як перевірено ^0) дорівнює 0, він просто повертає 0. Якщо він один, ^0виведеться 1. Це не вдасться перевірити рівність 0 =0і, таким чином, буде натиснути праворуч. Потім віднімаємо 2, -2щоб отримати 255, ліву зміну >>отримуємо 127 і виконуємо двійковий код, ~~щоб не отримати 128 (ми також могли просто додати один, ++щоб отримати 128, але де в цьому весело?)

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