Поменять полярность


12

Цель этой задачи - написать программу, которая удовлетворяет следующим условиям:

  • Программа не является палиндромной или, по сути, палиндромной (это означает, что можно удалить символы, чтобы сделать их палиндромом, не изменяя эффектов программы).

  • Программа не является инволюцией (это означает, что она не производит свой исходный ввод при запуске на своем выходе)

  • Программа обратной полярности является обратной к обычной программе; поэтому, когда обратная программа запускается на выходе обычной программы, она возвращает исходный ввод.

Что означает обратная полярность ? Ну, это отличается между языками.

  • Для большинства не связанных с esolangs это означает изменение порядка подопераций в одной операции, изменение порядка аргументов и изменение содержимого жестко закодированных списков / массивов / кортежей / словарей / стеков / очередей / и т. Д. как изменение порядка блоков кода и отдельных строк (но не строк внутри блоков)

Примеры:

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

Python : 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 месяц с момента начала этого конкурса (я случайно наткнулся на него, не зная, что я действительно вовремя). Поскольку это конкурс популярности, победителем (по оползню ) стал Pietu1998-Befunge . Несмотря на то, что нижние компоненты (реверсор текста и обратный алфавит) являются инволюциями, кодер / декодер - нет, так что здесь нет проблем. Бонусные баллы (на мой взгляд) за умение написать «BEFUNGE» по центру. Мне лично понравилась новинка решения Тезея Згарба , потому что язык выглядит круто (если его ограничить). Спасибо всем за участие, и хотя победитель был выбран, я оставляю этот конкурс полностью открытым и приветствую будущие предложения.


1
Что вы подразумеваете под программой с обратной полярностью, противоположной обычной программе? Отличается ли выход каким-либо образом?
Sp3000

Выполняет обратную операцию; когда обратная программа запускается на выходе обычной программы, она возвращает исходный ввод.
archaephyrryx

Извините за ошибку; Я не слышал об этом раньше, и это показалось мне немного гротескным, поэтому я должен был предположить, что это был Эзоланг; Я изменю это.
archaephyrryx

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

1
В примере с Haskell почему аргумент функции не перемешивается до конца? Выбраны ли реверсы таким образом, чтобы сохранить безопасность типов? Разрешено ли нам выбирать некоторые детали операции смены полярности?
Джон Дворжак

Ответы:


41

Befunge

Вау, это была работа, даже с редактором, которого я сделал для этого испытания. Вот что я получил, хороший блок 11х12:

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
Вот это да! Я должен поддержать это, хотя это означает, что я опустился на третье место.
Уровень реки St

18

Brainfuck, 5

,+.-,

Возможно, впервые в истории Brainfuck дает ответ, конкурентоспособный по длине кода. Позор, это не вопрос игры в гольф.

Вводит байт (символ), увеличивает его и выводит результат. Запятая в конце ожидает другого ввода, который, если дан, будет проигнорирован. В спецификации нет ничего о правильном расторжении: -) *

* (или о выполнении чего-то полезного со всем кодом в обоих направлениях)

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

Вперед: B->C

Реверс: B-> Aили C->B


11

Marbelous

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

--
]]
00
]]
++

Если мы повернем это на 180 ° (без смены скобок) или отразим по оси X, мы получим

++
]]
00
]]
--

который читает байт из STDIN и уменьшает его.

Вы можете проверить это здесь .

Я мог бы взглянуть на некоторые более сложные программы Marbelous, но я уверен, что es1024 превзойдет меня. ;)

объяснение

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

Поэтому два устройства наверху просто игнорируются, потому что поток управления никогда не достигает их.


В качестве альтернативы, вы можете заменить свои три средние строки одним устройством ввода.
overactor

@overactor Или вы имеете в виду }0и использовать его в качестве субборт?
Мартин Эндер,

}0в качестве ввода командной строки, чтобы быть точным.
overactor

5

Marbelous

Эта доска принимает один аргумент ( 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 , для каждого п .

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», если вы сначала применили обратную программу).
user19057

Вы можете использовать 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 ° (но при этом содержимое каждой ячейки остается одинаковым) Изменяет программу так, чтобы она оставляла shift ( 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.