Выровняйте диагонали сетки текста

15

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

Например, если сетка ввода текста

abcd
1234
WXYZ

то вы бы выстраиваться диагоналей W, 1X, a2Y, b3z, c4, и dв колонках , давая этот выход:

  ab
 123c
WXYZ4d

Обратите внимание, что самые нижние правые символы всех диагоналей WXYZ4dнаходятся на одном уровне.

Детали

  • Размер входной сетки текста будет не менее 1 × 1, а длина всех строк будет одинаковой.

  • Вы можете принять входную сетку как многострочную строку или как список однострочных строк.

  • Сетка ввода будет содержать только печатные символы ASCII (включая пробел).

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

  • Строки вывода могут иметь пробелы, но не должны иметь лишних начальных пробелов.

Другие примеры

Пустые строки отдельные примеры. За каждым входом непосредственно следует выход.

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

~

~

счет

Самый короткий код в байтах побеждает.

Кальвин Хобби
источник
Может ли ввод быть двумерным массивом символов (матрицей символов)?
Луис Мендо
Может ли первый столбец ввода содержать пробелы?
Kritixi Lithos
@ LuisMendo Это звучит нормально.
Увлечения Кельвина,
@KritixiLithos Да, возможно.
Увлечения Кельвина,

Ответы:

4

J , 12 байт

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

Определяет анонимный глагол. Попробуйте онлайн!

объяснение

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

В J u &. v(читай: uпод v) означает «v, затем u, затем обратное к v». Реверс и транспонирование являются самообращениями, поэтому программа действительно означает «реверсировать, транспонировать, извлекать обратные антидиагональные, транспонировать, реверсировать».

С примером ввода:

abcd
1234
WXYZ

Задний ход:

WXYZ
1234
abcd

Транспонирование:

W1a
X2b
Y3c
Z4d

Извлечение обратной анти-диагонали (и прокладка с пробелами):

W  
X1 
Y2a
Z3b
4c 
d  

Транспонирование:

WXYZ4d
 123c 
  ab  

Задний ход:

  ab  
 123c 
WXYZ4d
Zgarb
источник
2
Отличная демонстрация силы наречий
мили
2
Я проснулся и вспомнил, что это были на самом деле союзы.
миль
2

Желе , 11 или 10 байт

ZŒDṙLUz⁶ṚUY

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

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

Объяснение:

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

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


источник
2

CJam , 29 байт

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

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

объяснение

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

GFDB
EEDB
CCCB
AAAA

Если мы выпишем диагонали в соответствии с требованиями задачи, мы получим:

   G
  EEF
 CCCDD
AAAABBB

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

{      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.
Мартин Эндер
источник
Осторожно, это ]обернет весь стек! Я думаю, что функции должны работать независимо от содержимого стека под вводом, и вы, кажется, согласны ^^
Линн
@ Линн, блин, забыл, что я использовал, ]когда я изменил его на функцию.
Мартин Эндер
Я думаю, что вы могли бы сделать [{)\z}h]и сохранить его функцию, для 27 байтов.
Линн
2

JavaScript, 116 101 байт

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>

Я просто хотел использовать эту /.$|\n?(?!.*\n)..+/gmидею регулярных выражений . ( https://regex101.com/r/mjMz9i/2 )

Вкус регулярных выражений в JavaScript разочаровывает, мне пришлось использовать, (?!.*\n)потому что он не \Zреализован, и почему-то я не смог его использовать \0.

  • 15 байтов от спасибо @Neil.
Вашингтон Гуэдес
источник
Мне просто нравится этот подход, но вы можете использовать .вместо, [^]так как вам нужно всего лишь пропустить символы без новой строки, чтобы найти новую строку, которая экономит 2 байта.
Нил
Я не думаю, что ^это необходимо в последнем регулярном выражении, потому что any в любом случае \nуже находится в начале строки, так что это сохраняет еще один байт.
Нил
Я нашел способ играть в гольф '$&'+' '.repeat(n). По сути, это выражение просто, $&но с пробелом, добавляемым к каждому вызову, что тривиально реализовать рекурсивно - заменить n=0на r='$&'и f(z,n+1)с, f(z,r+' ')а затем r- желаемая строка замены. Если я посчитал правильно, это экономит 12 байтов.
Нил
@Neil. Это круто !!, спасибо
Вашингтон
1

Желе , 15 или 14 байт

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

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

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

Вот как работает алгоритм. Давайте начнем с этого ввода:

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

Мы начинаем с L’⁶x;\. L’дает нам длину ввода минус 1 (в данном случае 2). Затем ⁶xдает нам строку пространств этой длины ( " "в данном случае); и ;\дает нам совокупные результаты при конкатенации (треугольник пространств). Затем мы переворачиваем треугольник и соединяем его с левой стороной оригинала ( ;"объединяем соответствующие элементы списков, µпринудительно приводим к разрыву при разборе и, таким образом, используем исходный ввод как второй список по умолчанию), давая нам следующее:

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

Это почти то решение, которое нам нужно, но нам нужно переместить элементы вниз, чтобы они были на одном уровне с последней строкой. Это вопрос транспонирования ( Z), обращения внутри каждой строки ( U), транспонирования снова ( Z) и обращения строк ( ):

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

транспонирования

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

перевернуть в строках

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

транспонирования

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

поменять местами

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

Наконец, Yприсоединяется к новым строкам. Для меня неясно, требуется ли это для соответствия спецификации (которая допускает ввод в виде списка строк, но не говорит то же самое о выводе), поэтому точное число байтов зависит от того, включен он или нет.


источник
1

Pyth, 16 байт

j_.t_M.Tm+*;l=tQ

Большой Пит :

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

Поскольку люди говорят, что языки игры в гольф трудно читать, я разработал Big Pyth, который легко читается и легко переносится на Pyth. Связанный файл переводит входной поток Big Pyth в Pyth. Каждый токен Big Pyth, разделенный пробелами, соответствует токену Pyth, либо персонажу, либо. сопровождаемому символом. Исключением являются implicitтокены, которые неявно присутствуют в коде Pyth.

Я хочу посмотреть, насколько хорош объяснительный формат Big Pyth, поэтому я не буду давать никаких других объяснений. Спросите меня, если вы хотите что-то объяснить, однако.

isaacg
источник
0

JavaScript (ES6), 140 байт

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``)

Принимает ввод и вывод как массивы строк. Также принимает ввод двумерного массива символов и сохраняет 7 байтов, если вывод двумерного массива символов допустим. Объяснение: Высота результата m- это минимум высоты hи ширины wисходного массива, а ширина просто на единицу меньше суммы высоты и ширины исходного массива. Исходная строка для символов в основной части результата поступает непосредственно из соответствующей строки исходного массива, считая снизу вверх, тогда как в дополнительной части результата исходная строка перемещается вверх на одну строку для каждого дополнительного столбца. Исходный столбец для обеих половин результата оказывается равным целевому столбцу, перемещенному на один столбец влево для каждой исходной строки над основанием.

Нил
источник
0

Октава, 57 байт

@(A){B=spdiags(A),C=B>0,D='  '(C+1),D(sort(C))=B(C),D}{5}
Райнер П.
источник
0

Python 3, 247 байт

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')`
Кормак
источник
Бесполезные пробелы в join(i) for.
Yytsi
0

Python 2, 150 байт

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])

Принимает ввод как список строк.

Arfie
источник
0

Clojure, 194 байта

Реализовал сложный путь, группируя символы, Gа затем генерируя строки.

#(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"]))))

Принимает входной сигнал в виде vecиз vecS , как [[\a \b \c \d] [\1 \2 \3 \4] [\W \X \Y \Z]]. Пример:

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

  ab
 c123
d4WXYZ
NikoNyrh
источник