Wyrównaj przekątne siatki tekstu

15

Biorąc pod uwagę prostokątną siatkę tekstu, ustaw w linii przekątne, które przechodzą od lewego górnego rogu do prawego dolnego rogu, do kolumn, tak aby znaki znajdujące się najdalej po prawej stronie wszystkich przekątnych znajdowały się na poziomie. Użyj wcięć do wcięcia.

Na przykład, jeśli siatka wprowadzania tekstu to

abcd
1234
WXYZ

wtedy by wyrównać przekątnych W, 1X, a2Y, b3z, c4, i dw kolumnach podając ten wyjściowe:

  ab
 123c
WXYZ4d

Zwróć uwagę, że znaki znajdujące się najdalej po prawej stronie wszystkich przekątnych WXYZ4d, są na tym samym poziomie.

Detale

  • Siatka wprowadzania tekstu będzie miała rozmiar co najmniej 1 × 1, a wszystkie linie będą tej samej długości.

  • Możesz wziąć siatkę wejściową jako ciąg wielowierszowy lub jako listę ciągów jednowierszowych.

  • Siatka wejściowa będzie zawierać tylko drukowalne znaki ASCII (zawiera spację).

  • Dane wyjściowe mogą opcjonalnie mieć jedną końcową linię nowego wiersza, ale nie powinno być innych pustych linii.

  • Linie wyniku mogą opcjonalnie zawierać końcowe spacje, ale nie powinny mieć niepotrzebnych spacji wiodących.

Inne przykłady

Puste linie oddzielają przykłady. Po każdym wejściu następuje bezpośrednio jego wynik.

123
456
789

  1
 452
78963

123.?!
456??!
789!!!

  123.
 456???
789!!!!!

**@
@  

 **
@  @


/\/\
\/ /
/ /\
\/\/

   /
  \/\
 / / /
\/\/\/\

12
34
56
78
90

 7531
908642

Code

Code

G
O
L
F

FLOG

~

~

Punktacja

Najkrótszy kod w bajtach wygrywa.

Hobby Calvina
źródło
Czy wejściem może być tablica znaków 2D (macierz znaków)?
Luis Mendo,
Czy pierwsza kolumna danych wejściowych może zawierać spacje?
Kritixi Lithos
@LuisMendo To brzmi dobrze.
Calvin's Hobbies
@KritixiLithos Tak, może.
Calvin's Hobbies

Odpowiedzi:

4

J , 12 bajtów

|./.&.|:&.|.

Definiuje anonimowy czasownik. Wypróbuj online!

Wyjaśnienie

|./.&.|:&.|.
|.            Reversed
  /.          anti-diagonals
    &.        under
      |:      transpose
        &.    under
          |.  reversal

W J u &. v(czytaj: uponiżej v) oznacza „v, następnie u, a następnie odwrotność v”. Odwrócenie i transpozycja są samoinwersjami, więc program naprawdę oznacza „odwróć, transponuj, wyciągnij odwrócone anty-przekątne, transponuj, odwróć”.

Z przykładowym wejściem:

abcd
1234
WXYZ

Rewers:

WXYZ
1234
abcd

Transponować:

W1a
X2b
Y3c
Z4d

Wyodrębnij odwrócone przekątne (i podkładkę ze spacjami):

W  
X1 
Y2a
Z3b
4c 
d  

Transponować:

WXYZ4d
 123c 
  ab  

Rewers:

  ab  
 123c 
WXYZ4d
Zgarb
źródło
2
Doskonała demonstracja mocy przysłówków
mile
2
Obudziłem się i przypomniałem sobie, że to właściwie koniunkcje.
mile
2

Galaretka , 11 lub 10 bajtów

ZŒDṙLUz⁶ṚUY

Wypróbuj online!

Dość inny algorytm od mojego innego rozwiązania; ten używa wbudowanego, aby dostać się na przekątnych, zamiast robić rzeczy ręcznie.

Wyjaśnienie:

ZŒDṙLUz⁶ṚUY
Z           transpose
 ŒD         diagonals, main diagonal first
    L       number of lines in the original array
   ṙ        rotate list (i.e. placing the short diagonal first)
     U      reverse inside lines
      z⁶    transpose, padding with spaces
        ṚU  rotate matrix 180 degrees
          Y (possibly unnecessary) join on newlines

Przekątne wychodzą w możliwie najgorszej możliwej orientacji (wymagającej powtarzających się transpozycji, cofnięć i obrotów) oraz w niewłaściwej kolejności (Jelly wysyła główną przekątną jako pierwszą, więc musimy przesunąć niektóre przekątne od końca do początku, aby je zdobyć w celu). Jednak nadal wychodzi to krócej niż moje inne rozwiązanie Jelly.


źródło
2

CJam , 29 bajtów

qN/{)\z}h]2/{~W%+}%eeSf.*W%N*

Wypróbuj online!

Wyjaśnienie

Zamiast wyciągać przekątne, odrywamy warstwy od końca, naprzemiennie na lewo i na prawo. Rozważ następujące dane wejściowe:

GFDB
EEDB
CCCB
AAAA

Jeśli wypiszemy przekątne zgodnie z wymaganiami wyzwania, otrzymamy:

   G
  EEF
 CCCDD
AAAABBB

Zauważ, że jest to po prostu (od dołu do góry), najniższy wiersz, połączony z kolumną z prawej strony. Ta definicja działa również, jeśli wejście jest prostokątne.

{      e# Run this loop while there are still lines left in the input.
  )    e#   Pull off the bottom-most row.
  \    e#   Swap with the remaining rows.
  z    e#   Transpose the grid so that the next iteration pulls off the last
       e#   column instead. However, it should be noted that transposing
       e#   effectively reverses the column, so the second half of each output
       e#   line will be the wrong way around. We'll fix that later.
}h     e# When the loop is done, we'll have all the individual layers on the
       e# stack from bottom to top, alternating between horizontal and vertical
       e# layers. There will be an empty string on top.
]      e# Wrap all those strings in a list.
2/     e# Split into pairs. There may or may not be a trailing single-element
       e# list with the empty string.
{      e# Map this block over each pair...
  ~    e#   Dump the pair on the stack.
  W%   e#   Reverse the second element.
  +    e#   Append to first element.
       e#   If there was a trailing single-element list, this will simply
       e#   add the empty string to the previous pair, which just removes
       e#   the empty string.
}%
ee     e# Enumerate the list, which pairs each string (now containing both halves)
       e# of an output line from bottom to top) with its index.
Sf.*   e# Turn those indices X into strings of X spaces, to get the correct
       e# indentation.
W%     e# Reverse the list of strings so the longest line ends up on the bottom.
Martin Ender
źródło
Ostrożnie, to ]owinie cały stos! Myślę, że funkcje powinny działać niezależnie od zawartości stosu poniżej danych wejściowych i wydaje się, że zgadzasz się ^^
Lynn
@ Lynn ups, zapomniałem, że używałem, ]kiedy zmieniłem go na funkcję.
Martin Ender
Myślę, że możesz to zrobić [{)\z}h]i zachować funkcję dla 27 bajtów.
Lynn
2

JavaScript, 116 101 bajtów

f=(s,r='$&',l='',z=s.replace(/.$|\n?(?!.*\n)..+/gm,x=>(l=x+l,'')))=>l?f(z,r+' ')+l.replace(/\n?/,r):l


G.onclick=()=>O.textContent=f(I.value);
<textarea id=I style=height:100px>/\/\
\/ /
/ /\
\/\/</textarea><button id=G>Go</button><pre id=O></pre>

Chciałem tylko użyć tego wzoru wzorca wyrażenia regularnego /.$|\n?(?!.*\n)..+/gm. ( https://regex101.com/r/mjMz9i/2 )

JavaScript wyrażenia regularnego jest rozczarowujący, musiałem go użyć, (?!.*\n)ponieważ nie został \Zzaimplementowany i jakoś nie mogłem go użyć \0.

  • 15 bajtów off dzięki @Neil.
Washington Guedes
źródło
Uwielbiam to podejście, ale możesz użyć .zamiast tego, [^]ponieważ musisz tylko pominąć znaki inne niż nowa linia, aby znaleźć nową linię, która oszczędza 2 bajty.
Neil
Nie sądzę, żeby ^to było konieczne w końcowym wyrażeniu regularnym, ponieważ i tak \njest już na początku łańcucha, więc zapisuje inny bajt.
Neil
Znalazłem sposób na grę w golfa '$&'+' '.repeat(n). Zasadniczo, że wyrażenie jest po prostu $&ale z przestrzenią dodawane każdego połączenia, które jest trywialny do wdrożenia rekurencyjnie - wymień n=0się r='$&'i f(z,n+1)z f(z,r+' ')czym rjest pożądany ciąg wymiana. Jeśli poprawnie policzyłem, to oszczędza 12 bajtów.
Neil
@Neil. To niesamowite !!, dziękuję
Washington Guedes
1

Galaretka , 15 lub 14 bajtów

L’⁶x;\Ṛ;"µZUZṚY

Wypróbuj online!

Jest to algorytm, który nie wykorzystuje wbudowanego Jelly do przekątnych. Może to skrócić czas; Mógłbym spróbować później.

Oto jak działa algorytm. Zacznijmy od tego wejścia:

["abc",
 "def",
 "ghi"]

Zaczynamy od L’⁶x;\.L’daje nam długość wejścia minus 1 (w tym przypadku 2). Następnie ⁶xdaje nam ciąg spacji o tej długości ( " "w tym przypadku); i ;\daje nam skumulowane wyniki podczas konkatenacji (trójkąt spacji). Następnie odwracamy trójkąt i konkatenujemy go do lewej strony oryginału ( ;"konkatenuje odpowiednie elementy list, µsiłą powoduje przerwanie parsowania, a tym samym domyślnie wykorzystuje oryginalne dane wejściowe jako drugą listę), dając nam to:

["  abc",
 " def",
 "ghi"]

Jest to prawie rozwiązanie, którego chcemy, ale musimy przesunąć elementy w dół, aby zrównać się z ostatnim łańcuchem. Jest to kwestia transpozycji ( Z), odwrócenia wewnątrz każdej linii ( U), transpozycji ponownie ( Z) i odwrócenia linii ( ):

["  abc",
 " def",
 "ghi"]

transponować

["  g",
 " dh",
 "aei",
 "bf",
 "c"]

odwróć w rzędach

["g  ",
 "hd ",
 "iea",
 "fb",
 "c"]

transponować

["ghifc",
 " deb",
 "  a"]

odwrócić rzędy

["  a",
 " deb",
 "ghifc"]

Wreszcie Ydołącza do nowych linii. Nie jest dla mnie jasne, czy jest to wymagane, aby zachować zgodność ze specyfikacją (która pozwala na wprowadzanie danych jako listę ciągów, ale nie mówi tego samego o danych wyjściowych), więc dokładna liczba bajtów zależy od tego, czy jest uwzględniona, czy pominięta.


źródło
1

Pyth, 16 bajtów

j_.t_M.Tm+*;l=tQ

Big Pyth :

join-on-newline
reverse transpose-and-fill-with-spaces reverse func-map transpose-justified
map
  plus
    times innermost-var
      length assign tail input
    implicit-innermost-var
  implicit-input

Ponieważ ludzie mówią, że języki gry w golfa są trudne do odczytania, zaprojektowałem Big Pyth, który jest zarówno czytelny, jak i łatwy do przetłumaczenia na Pyth. Połączony plik tłumaczy strumień wejściowy Big Pyth na Pyth. Każdy oddzielony spacjami token Big Pyth odpowiada tokenowi Pyth, znakowi lub znakowi, .po którym następuje znak. Wyjątkiem są implicittokeny, które są niejawne w kodzie Pyth.

Chcę zobaczyć, jak dobry jest format objaśniający Big Pyth, więc nie dam żadnych innych wyjaśnień. Zapytaj mnie jednak, czy chcesz coś wyjaśnić.

isaacg
źródło
0

JavaScript (ES6), 140 bajtów

a=>[...Array(m=(h=a.length)<(w=a[0].length)?h:w)].map((_,i)=>[...Array(h+w-1)].map((_,j)=>(a[x=i+h-m-(++j>w&&j-w)]||``)[x+j-h]||` `).join``)

Pobiera dane wejściowe i wyjściowe jako tablice ciągów. Akceptuje również dwuwymiarowe tablice znaków i oszczędza 7 bajtów, jeśli dwuwymiarowe tablice znaków jest dopuszczalne. Objaśnienie: Wysokość wyniku mjest minimalną wysokością hi szerokością woryginalnej tablicy, podczas gdy szerokość jest po prostu o jeden mniejsza niż suma wysokości i szerokości oryginalnej tablicy. Wiersz źródłowy dla znaków w głównej części wyniku pochodzi bezpośrednio z odpowiedniego wiersza oryginalnej tablicy, licząc w górę od dołu, natomiast w dodatkowej części wyniku wiersz źródłowy przesuwa się o jeden wiersz w górę dla każdej dodatkowej kolumny. Kolumna źródłowa dla obu połówek wyniku okazuje się być równa kolumnie docelowej przesuniętej o jedną kolumnę w lewo dla każdego wiersza źródłowego nad dnem.

Neil
źródło
0

Oktawa, 57 bajtów

@(A){B=spdiags(A),C=B>0,D='  '(C+1),D(sort(C))=B(C),D}{5}
Rainer P.
źródło
0

Python 3, 247 bajtów

def a(s):
 s=s.split('\n')
 for i,l in enumerate(s):r=len(s)-i-1;s[i]=' '*r+l+' '*(len(s)-r-1)
 print(*[''.join(i) for i in list(zip(*[''.join(a).rstrip([::-1].ljust(min(len(s),len(s[0])))for a in zip(*[list(i)for i in s])]))[::-1]],sep='\n')`
Cormac
źródło
Bezużyteczne białe znaki na join(i) for.
Yytsi
0

Python 2, 150 bajtów

def f(l):w=len(l[0]);h=len(l);J=''.join;R=range;print'\n'.join(map(J,zip(*['%%-%ds'%h%J(l[h+~i][j-i]for i in R(h)if-w<i-j<1)for j in R(h-~w)]))[::-1])

Pobiera dane wejściowe jako listę ciągów.

Arfie
źródło
0

Clojure, 194 bajty

Zaimplementowano trudną drogę, grupując znaki, Ga następnie generując linie.

#(let[n(count %)m(count(% 0))G(group-by first(for[i(range n)j(range m)][(min(- n i)(- m j))((% i)j)]))](apply str(flatten(for[k(reverse(sort(keys G)))][(repeat(dec k)" ")(map last(G k))"\n"]))))

Staje się jako wejście vecz vecLike [[\a \b \c \d] [\1 \2 \3 \4] [\W \X \Y \Z]]. Przykład:

(def f #( ... ))
(print (str "\n" (f (mapv vec(re-seq #".+" "abcd\n1234\nWXYZ")))))

  ab
 c123
d4WXYZ
NikoNyrh
źródło