Порядок форматування Аліси


9

Вступ

Аліса - це дводенна мова Мартіна Ендера, яка має два різні режими виконання, кардинальний та порядковий . Коли вказівник інструкції проходить через дзеркало (або /або \), він переходить з одного режиму в інший.

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

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

/fbd/
@aec\

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

Така структура є досить компактною, але писати та підтримувати її непросто (додавання однієї команди може змусити нас змінити порядок більшості коду!), Тому я хотів би, щоб ви допомогли мені з форматуванням.

Завдання

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

Так, наприклад, для даного вводу abcdefслід вивести

fbd
aec

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

Правила

Це є , найкоротша відповідь, в байтах, виграє!

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

Тестові справи

--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, щоб зрозуміти алгоритм, який ви використовували ... Чи можете ви додати пояснення?
Лев

@Leo Я не впевнений, скільки ще можу пояснити. Як відомо, команди слідують за зигзаговим рядком зліва направо і знову назад ліворуч. 1&~iДосягає вертикальні зигзагоподібний, в той час як i+i>l?l-i:iдосягає півдорозі дзеркала. Після того, як всі команди були введені в потрібні позиції виконання, масив потім збирається разом для отримання бажаного результату.
Ніл
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.