Formatowanie porządkowe Alice

9

Wprowadzenie

Alice jest dwuwymiarowym językiem Martina Endera, który ma dwa różne tryby wykonania: kardynalny i porządkowy . Kiedy wskaźnik instrukcji przechodzi przez lustro (albo /albo \), przełącza się z jednego trybu do drugiego.

W tym wyzwaniu skupimy się na trybie porządkowym , w którym polecenia działają na ciągach, a wskaźnik instrukcji porusza się po przekątnej, odbijając się od krawędzi kodu.

Proste programy działające tylko w trybie porządkowym można pisać w dość zwartym stylu, jak w poniższym przykładzie:

/fbd/
@aec\

Tu rozpoczyna się w trybie IP kardynalnej z pierwszą komórką idzie na wschód, przepływa przez pierwsze lustro i zaczyna poruszać się po przekątnej i podskakują, wykonywanie poleceń a, boraz c. Następnie spotyka lustro północno-wschodniej, która sprawia, że się na południe w kierunku drugiego lustra, a następnie rozpocząć odbijając z powrotem w kierunku zachodnim, napotykając polecenia d, e, f, i wreszcie @, który kończy program.

Tego rodzaju struktura jest dość zwarta, ale nie jest łatwa do napisania i utrzymania (dodanie jednego polecenia może zmusić nas do zmiany kolejności większości kodu!), Więc chciałbym, abyś pomógł mi w formatowaniu.

Zadanie

Biorąc pod uwagę sekwencję poleceń, gdzie każde polecenie jest pojedynczym drukowalnym znakiem ASCII, zmień ich kolejność w dwóch wierszach, aby pierwszą połowę sekwencji można było odczytać, zaczynając od pierwszego znaku drugiej linii, a następnie przesuwając się zawsze po przekątnej w prawo, podczas gdy drugą połowę można odczytać, biorąc pozostałe postacie od prawej do lewej. Nie martw się o lusterka i symbol zakończenia, dodam je osobiście.

Na przykład biorąc pod uwagę dane wejściowe, abcdefktóre należy wyprowadzić

fbd
aec

W przypadku, gdy dane wejściowe są nieparzystej długości, należy w dowolnym miejscu dodać pojedynczą spację (która jest noop w Alice), o ile sekwencja napotkanych poleceń pozostaje taka sama. Możesz również wybrać wyświetlanie dwóch wierszy różniących się długością o jeden znak, w którym to przypadku uważa się, że krótszy wiersz zawiera jedną spację na końcu.

Zasady

To jest , najkrótsza odpowiedź w bajtach wygrywa!

  • Możesz wprowadzić / wyprowadzić dowolną z domyślnych metod wejścia / wyjścia
  • Dane wejściowe składają się z jednego wiersza drukowalnych znaków ASCII
  • Pojedynczy znak nowej linii jest dozwolony w danych wyjściowych
  • Niektóre dane wyjściowe programu mogą nie mieć całkowicie poprawnego działania, gdy są uruchamiane jako programy Alice (np. Jeśli przestrzeń dopełniania jest wstawiona do literału łańcucha). Nie musisz się martwić tymi sytuacjami
  • Standardowe luki są zabronione

Przypadki testowe

--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)
Lew
źródło

Odpowiedzi:

1

Galaretka , 15 bajtów

œs2U2¦ṚZUJḤ$¦ZY

Wypróbuj online!

Pobiera cytowane dane wejściowe.

Wyjaśnienie:

œ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
Erik the Outgolfer
źródło
12

Alice , 28 bajtów

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

Wypróbuj online!

Jeśli długość wejściowa jest nieparzysta, to umieszcza przestrzeń wypełniania na końcu programu zlinearyzowanego, co kończy się jako pierwszy znak wyniku.

Kilka dni temu Leo napisał w Alice formater Ordinal . Po dodaniu obsługi danych wejściowych o nieparzystej długości, a następnie usunięciu rzeczy, które nie były konieczne do tego wyzwania, otrzymaliśmy 28 bajtów . Chciałem wypróbować nieco inne podejście, które brzmi następująco. Niestety, właśnie skończyło się wiązanie 28 bajtów, ale przynajmniej w ten sposób mogę opublikować własne rozwiązanie i pozwolić Leo opublikować swój oryginalny algorytm.

To wykorzystuje naprawdę sprytny pomysł Leo, aby podzielić strunę na pół ..Y;m;.!z?~.

Wyjaśnienie

Załóżmy, że wejście ma parzystą długość (ponieważ po prostu wstawimy spację, jeśli nie ma). Wzorzec jest nieco łatwiejszy, jeśli użyjemy go 0123456789jako kodu. Wymagany wynik to:

91735
08264

Więc pierwszy wiersz zawiera wszystkie nieparzyste pozycje danych wejściowych, a drugi wiersz wszystkie parzyste dane wejściowe. Ponadto, jeśli odwrócimy nieparzyste pozycje, wówczas same linie są przeplatane zarówno przez pierwszą połowę (być może dłuższą) z odwrotnością drugiej połowy.

Podstawową ideą jest:

  • Rozdziel dane wejściowe na nieparzyste i parzyste pozycje.
  • W razie potrzeby wypełnij nieparzyste pozycje spacją.
  • Odwróć nieparzyste pozycje.
  • Następnie dwa razy: zmniejsz o połowę bieżącą strunę, odwróć drugą połowę, przeplataj obie połówki, drukuj z końcowym podawaniem linii.

Jeśli chodzi o kod, wygląda to trochę jak układ, który tworzymy w tym wyzwaniu, ale jest nieco inny: kiedy adres IP trafi /na koniec kodu, zostanie odbity na wschód , a nie na południe. Następnie, w trybie kardynalnym, IP zawinie się do pierwszej kolumny. \Tam ponownie przechodzi w tryb porządkowych, tak, że druga połowa kodu nie wychodzi od prawej do lewej strony tutaj, ale od lewej do prawej, jak również. Jest to korzystne podczas pracy ze stosem adresów zwrotnych, ponieważ nie przechowuje informacji o kierunku adresu IP. Pozwala nam to zaoszczędzić kilka bajtów, ponieważ IP będzie się poruszać w tym samym (poziomym) kierunku zarówno na, jak wi na k.

Kod zlinearyzowany jest następujący:

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

Przejdźmy przez to:

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.
Martin Ender
źródło
1
Będę musiał opublikować kolejne wyzwanie dla tego nowego układu, który wymyśliłeś! : D Bardzo fajnie, myślę, że zacznę go używać, nawet gdy nie używam stosu zwrotnego, łatwiej jest odczytać obie połówki kodu od lewej do prawej
Leo
4

Galaretka , 23 22 bajtów

-1 bajt dzięki Leo (lewy dolny może być dopełnienie)

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

Pełny program wypisujący wynik (monadyczny link zwraca listę list list znaków).

Wypróbuj online! lub zobacz pakiet testowy .

W jaki sposób?

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)
Jonathan Allan
źródło
1

JavaScript (ES6), 104 bajty

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>

Działa poprzez emulowanie ścieżki wykonania i wypełnianie poleceń w miarę jej działania.

Neil
źródło
Wygląda na fajny pomysł, ale nie wiem wystarczająco dużo o javascript, aby zrozumieć użyty algorytm ... Czy mógłbyś dodać jakieś wyjaśnienie?
Leo
@Leo Nie jestem pewien, o ile więcej mogę wyjaśnić. Jak wiecie, polecenia podążają za zygzakowatą linią od lewej do prawej iz powrotem w lewo. 1&~iOsiąga pionową zygzakowata, podczas gdy i+i>l?l-i:iosiąga lustro połowy. Po wprowadzeniu wszystkich poleceń w pożądane pozycje wykonania tablica jest następnie gromadzona razem, aby uzyskać pożądany wynik.
Neil