Порядковый формат Алисы

9

Введение

Алиса - это двумерный язык Мартина Эндера, который имеет два разных режима исполнения: кардинальный и порядковый . Когда указатель инструкций проходит через зеркало (либо, /либо \), он переключается из одного режима в другой.

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

Простые программы, работающие только в обычном режиме, могут быть написаны в довольно компактном стиле, как в следующем примере:

/fbd/
@aec\

При этом IP - запускается в режиме кардинального от первой ячейки на востоке, проходит через первое зеркало и начинает двигаться по диагонали , и отражаясь, выполнение команд a, bи c. Затем он встречает на северо-востоке зеркала , которое делает его идти на юг по направлению к другому зеркалу , а затем начать прыгающую спину к западу, встречая команды d, e, f, и , наконец @, которая завершает программу.

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

Задание

Учитывая последовательность команд, где каждая команда представляет собой один печатный символ ASCII, переупорядочьте их в две строки, чтобы можно было прочитать первую половину последовательности, начиная с первого символа второй строки, а затем перемещаться всегда по диагонали вправо, в то время как вторую половину можно прочитать, взяв оставшиеся символы справа налево. Не беспокойтесь о зеркалах и символе завершения, я добавлю их сам.

Так, например, при заданном входе abcdefвы должны вывести

fbd
aec

В случае, если ввод имеет нечетную длину, вы должны добавить один пробел (который является алисом в Алисе) в любом месте, при условии, что последовательность встречаемых команд остается неизменной. Вы также можете выбрать вывод двух строк, различающихся по длине на один символ, и в этом случае более короткая считается имеющей один пробел в конце.

правила

Это , самый короткий ответ, в байтах, выигрывает!

  • Вы можете вводить / выводить с помощью любого из методов ввода / вывода по умолчанию
  • Ввод состоит из одной строки печатных символов ASCII
  • В выводе допускается один завершающий символ новой строки
  • Некоторые выходные данные вашей программы могут работать не совсем корректно при запуске в качестве программ Алисы (например, если пробел вставляется в строковый литерал). Вам не нужно беспокоиться о таких ситуациях
  • Стандартные лазейки запрещены

Контрольные примеры

--Input
abcdef
--Output
fbd
aec

--Input
123
--Output
 2
13
OR
31
 2
OR
3
12
OR
32
1

--Input
O
--Output
O

OR

O

--Input
"Hello, World!"o
--Output
oH!lloo 
""edlr,W

--Input
i.szR.szno
--Output
o.zz.
inssR

--Input
"  ^^} .~[}.~~[}{~~{}[^^^^.""!}"r.h~;a*y'~i.*So
--Output
o *^i}'.*[;.h~r}}~"{.[^
"S .^~ y~a}~~.["{!~"}^^^
(Odd length, your solution may be different)
Лео
источник

Ответы:

1

Желе , 15 байт

œs2U2¦ṚZUJḤ$¦ZY

Попробуйте онлайн!

Принимает цитируемые данные.

Объяснение:

œs2U2¦ṚZUJḤ$¦ZY Main link, monadic
œs2             Split into 2 chunks of similar lengths, last might be shorter
   U2¦          Reverse the 2nd chunk
      Ṛ         Swap the chunks
       Z        Transpose into chunks of length 2
        UJḤ$¦   Reverse the chunks at even indices (1-indexed)
             Z  Transpose into 2 chunks again
              Y Join by a newline
Эрик Аутгольфер
источник
12

Алиса , 28 байт

/mY. zm~wZ.k;
\I;'!*?RR.OY@/

Попробуйте онлайн!

Если длина ввода нечетная, это помещает пробел в конец линеаризованной программы, которая в итоге становится первым символом вывода.

Лео написал «Алису» в Алисе несколько дней назад. После добавления поддержки входных данных нечетной длины и удаления некоторых вещей, которые не были необходимы для этой задачи, мы получили 28 байтов . Я хотел попробовать немного другой подход - вот ответ. К сожалению, это просто закончилось связыванием 28 байтов, но по крайней мере таким образом я могу опубликовать свое собственное решение и позволить Лео опубликовать свой оригинальный алгоритм.

Это действительно использует умную идею Лео, чтобы разделить строку пополам ..Y;m;.!z?~.

объяснение

Давайте предположим, что вход имеет четную длину (потому что мы просто добавим его пробелом, если он этого не сделает). Шаблон немного легче увидеть, если мы используем 0123456789в качестве кода. Требуемый результат будет:

91735
08264

Таким образом, первая строка содержит все нечетные позиции входных данных, а вторая строка - все четные входные данные. Кроме того, если мы изменим нечетные позиции, то сами линии будут первой чередованием (возможно, более длинной) с чередованием обратной половины.

Итак, основная идея такова:

  • Раздельный ввод в нечетные и четные позиции.
  • Заполните нечетные позиции пробелом, если это необходимо.
  • Поменяйте местами нечетные позиции.
  • Затем дважды: разделите пополам текущую строку, переверните вторую половину, чередуйте обе половины, печатайте с завершающим переводом строки.

Что касается кода, это очень похоже на вид компоновки, который мы создаем в этой задаче, но он немного отличается: когда IP попадает /в конец кода, он отражается на восток , а не на юг. Затем, находясь в режиме кардинала, IP-адрес будет переходить к первому столбцу. \Там вновь входит Порядковый режим, так что вторая половина кода не идет справа налево здесь, но слева направо , а также. Это полезно при работе со стеком обратных адресов, потому что он не хранит информацию о направлении IP. Это позволяет нам сохранить несколько байтов, потому что IP будет перемещаться в одном и том же (горизонтальном) направлении как на, так wи на k.

Линеаризованный код выглядит так:

IY' *mRw..Y;m;.!z?~RZOk@

Давайте пройдем через это:

I       Read one line of input.
Y       Unzip. Separates the string into even and odd positions.
' *     Append a space to the odd half.
m       Truncate: discards characters from the longer of the two
        strings until they're the same length. So if the input
        length was even, appending a space will make the odd half
        longer and this discards the space again. Otherwise, the
        space just padded the odd half to the same length as the
        even half and this does nothing.
R       Reverse the odd half.
w       Push the current IP address to the return address stack.
        The purpose of this is to run the following section
        exactly twice.

          This first part splits the current line in half, based
          on an idea of Leo's:
  ..        Make two copies of the current half.
  Y         Unzip one of the copies. The actual strings are irrelevant
            but the important part is that the first string's length
            will be exactly half the original string's length (rounded up).
  ;         Discard the potentially shorter half.
  m         Truncate on the original string and its even half. This shortens
            the original string to the first half of its characters.
  ;         Discard the even half, because we only needed its length.
  .!        Store a copy of the first half on the tape.
  z         Drop. Use the first half to discard it from the original string.
            This gives us the the second (potentially shorter half).
  ?         Retrieve the first half from the tape.
  ~         Swap it so that the second half is on top.
          The string has now been split in half.
  R       Reverse the second half.
  Z       Zip. Interleave the two halves.
  O       Print the result with a trailing linefeed.

k       Pop an address from the return address stack and jump back there.
        The second time we reach this, the return address stack is empty,
        and this does nothing.
@       Terminate the program.
Мартин Эндер
источник
1
Мне придется опубликовать еще один вызов для этого нового макета, который вы придумали! : D Очень хорошо, я думаю, что я начну использовать его, даже когда я не использую стек возвратов, легче читать обе части кода слева направо
Лев
4

Желе , 23 22 байта

-1 байт благодаря Льву (нижний левый может быть дополнением)

LḂ⁶ẋ;µṚ,µm2œs2U0¦ż/µ€Y

Полная программа печати результата (монадическая ссылка возвращает список списков списков символов).

Попробуйте онлайн! или посмотрите набор тестов .

Как?

LḂ⁶ẋ;µṚ,µm2œs2U0¦ż/µ€Y - Main link: list of characters
L                      - length
 Ḃ                     - modulo 2
  ⁶                    - literal space character
   ẋ                   - repeat
    ;@                 - concatenate (swap @rguments) (appends a space if the input's length is odd)
      µ                - monadic chain separation, call that s
       Ṛ               - reverse s
        ,              - pair with s
         µ         µ€  - for €ach:
          m2           -   modulo 2 slice (take every other character)
            œs2        -   split into two "equal" chunks (first half longer if odd)
               U0¦     -   upend index 0 (reverse the second chunk)
                   /   -   reduce by:
                  ż    -     zip
                     Y - join with newlines (well just the one in this case)
                       - implicit print (mushes the sublists together)
Джонатан Аллан
источник
1

JavaScript (ES6), 104 байта

f=
s=>s.replace(/./g,(c,i)=>a[1&~i][i+i>l?l-i:i]=c,a=[[` `],[]],l=s.length-1|1)&&a.map(a=>a.join``).join`
`
<input oninput=o.textContent=f(this.value)><pre id=o>

Работает, эмулируя путь выполнения и заполняя команды по мере поступления.

Нил
источник
Похоже, хорошая идея, но я не знаю достаточно о javascript, чтобы понять алгоритм, который вы использовали ... Не могли бы вы добавить некоторые объяснения?
Лев
@ Лео, я не уверен, сколько еще могу объяснить. Как вы знаете, команды следуют по зигзагообразной линии слева направо и обратно влево снова. 1&~iДостигает вертикальные зигзагообразный, в то время как i+i>l?l-i:iдостигает полпути зеркала. Как только все команды введены в желаемые позиции выполнения, массив затем собирается вместе для получения желаемого результата.
Нил