Alinhar as diagonais de uma grade de texto

15

Dada uma grade retangular de texto, alinhe as diagonais que vão da parte superior esquerda para a parte inferior direita em colunas, de modo que os caracteres mais baixos à direita de todas as diagonais estejam no mesmo nível. Use espaços para recuo.

Por exemplo, se a grade de entrada de texto for

abcd
1234
WXYZ

então você alinhar as diagonais W, 1X, a2Y, b3z, c4, e dem colunas dando essa saída:

  ab
 123c
WXYZ4d

Observe que os caracteres mais baixos à direita de todas as diagonais WXYZ4d, estão no mesmo nível.

Detalhes

  • A grade de entrada do texto terá tamanho mínimo de 1 × 1 e todas as linhas terão o mesmo comprimento.

  • Você pode considerar a grade de entrada como uma cadeia de linhas múltiplas ou como uma lista de cadeias de linhas únicas.

  • A grade de entrada contém apenas caracteres ASCII imprimíveis (inclui espaço).

  • Opcionalmente, a saída pode ter uma nova linha à direita, mas não deve haver outras linhas vazias.

  • As linhas da saída podem opcionalmente ter espaços à direita, mas não devem ter espaços à esquerda desnecessários.

Outros exemplos

Linhas vazias separam exemplos. Cada entrada é diretamente seguida por sua saída.

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

~

~

Pontuação

O código mais curto em bytes vence.

Passatempos de Calvin
fonte
A entrada pode ser uma matriz de caracteres 2D (uma matriz de caracteres)?
Luis Mendo
A primeira coluna da entrada pode conter espaços?
Kritixi Lithos
@LuisMendo Isso parece ok.
Passatempos de Calvin
@KritixiLithos Sim, pode.
Passatempos de Calvin

Respostas:

4

J , 12 bytes

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

Define um verbo anônimo. Experimente online!

Explicação

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

Em J, u &. v(leia-se: uabaixo v) significa "v, então u, então inverso de v". Reversão e transposição são auto-inversas, então o programa realmente significa "reverter, transpor, extrair anti-diagonais reversas, transpor, reverter".

Com entrada de exemplo:

abcd
1234
WXYZ

Marcha ré:

WXYZ
1234
abcd

Transpor:

W1a
X2b
Y3c
Z4d

Extrair anti-diagonais invertidas (e almofada com espaços):

W  
X1 
Y2a
Z3b
4c 
d  

Transpor:

WXYZ4d
 123c 
  ab  

Marcha ré:

  ab  
 123c 
WXYZ4d
Zgarb
fonte
2
Excelente demonstração do poder dos advérbios
miles
2
Eu acordei e lembrei que eram realmente conjunções.
miles
2

Gelatina , 11 ou 10 bytes

ZŒDṙLUz⁶ṚUY

Experimente online!

Um algoritmo bastante diferente da minha outra solução; este usa um builtin para acessar as diagonais, em vez de fazer as coisas manualmente.

Explicação:

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

As diagonais aparecem possivelmente na pior orientação possível (exigindo transposições, reversões e rotações repetidas) e na ordem errada (Jelly exibe a diagonal principal primeiro, portanto, temos que mover algumas diagonais do final para o início para obtê-las. em ordem). No entanto, isso ainda sai mais curto do que minha outra solução Jelly.


fonte
2

CJam , 29 bytes

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

Experimente online!

Explicação

Em vez de extrair as diagonais, descascamos as camadas do final, alternando esquerda e direita. Considere a seguinte entrada:

GFDB
EEDB
CCCB
AAAA

Se escrevermos as diagonais conforme exigido pelo desafio, obteremos:

   G
  EEF
 CCCDD
AAAABBB

Observe que esta é simplesmente (de baixo para cima), a linha mais abaixo, concatenada com a coluna mais à direita. Essa definição também funciona se a entrada for retangular.

{      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
fonte
Cuidado, isso ]envolverá toda a pilha! Eu acho que as funções devem funcionar, independentemente do conteúdo da pilha abaixo da entrada, e você parece concordar ^^
Lynn
@ Lynn whoops, esqueci que eu estava usando ]quando mudei para uma função.
Martin Ender
Eu acho que você poderia fazer [{)\z}h]e manter uma função, por 27 bytes.
Lynn
2

JavaScript, 116 101 bytes

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>

Eu só queria usar essa /.$|\n?(?!.*\n)..+/gmideia de padrão regex . ( https://regex101.com/r/mjMz9i/2 )

O sabor da expressão regular do JavaScript é decepcionante, tive que usar (?!.*\n)porque não foi \Zimplementado e, de alguma forma, não consegui usá-lo \0.

  • 15 bytes de desconto, graças à @ Neil.
Washington Guedes
fonte
Eu simplesmente adoro essa abordagem, mas você pode usar em .vez de [^]apenas precisar pular caracteres que não sejam de nova linha para encontrar uma nova linha, que economiza 2 bytes.
Neil
Eu não acho que isso ^seja necessário no regex final, porque \njá existe algum no início da string, portanto, isso salva outro byte.
Neil
Eu descobri uma maneira de jogar golfe '$&'+' '.repeat(n). Basicamente, essa expressão é justa, $&mas com um espaço adicionado a cada chamada, o que é trivial para implementar recursivamente - substitua n=0por r='$&'e f(z,n+1)com f(z,r+' ')e, em seguida, ré a sequência de substituição desejada. Se contei corretamente, isso salva 12 bytes.
Neil
@Neil. Isso é incrível !!, obrigado
Washington Guedes
1

Gelatina , 15 ou 14 bytes

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

Experimente online!

Este é um algoritmo que não usa o Jelly embutido para diagonais. Fazer isso pode torná-lo mais curto; Eu poderia muito bem tentar isso a seguir.

Aqui está como o algoritmo funciona. Vamos começar com esta entrada:

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

Começamos com L’⁶x;\. L’nos fornece o comprimento da entrada menos 1 (neste caso, 2). Então ⁶xnos fornece uma série de espaços desse comprimento ( " "neste caso); e ;\nos fornece os resultados cumulativos ao concatená-lo (um triângulo de espaços). Em seguida, invertemos o triângulo e o concatenamos no lado esquerdo do original ( ;"concatena os elementos correspondentes das listas, µprovoca forçosamente uma quebra na análise e, portanto, usa a entrada original como a segunda lista por padrão), fornecendo-nos o seguinte:

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

Essa é quase a solução que queremos, mas precisamos mover os elementos para baixo para alinhar com a última string. É uma questão de transpor ( Z), reverter dentro de cada linha ( U), transpor novamente ( Z) e reverter as linhas ( ):

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

transpor

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

reverter dentro de linhas

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

transpor

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

inverta as linhas

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

Por fim, Yingressa em novas linhas. Não está claro para mim se isso é necessário ou não para atender à especificação (que permite entrada como uma lista de seqüências de caracteres, mas não diz o mesmo sobre a saída), portanto, a contagem exata de bytes depende de sua inclusão ou omissão.


fonte
1

Pitão, 16 bytes

j_.t_M.Tm+*;l=tQ

Pitão grande :

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

Como as pessoas dizem que os idiomas de golfe são difíceis de ler, eu projetei o Big Pyth, que é facilmente legível e traduzível para o Pyth. O arquivo vinculado converte um fluxo de entrada do Big Pyth em Pyth. Cada token Big Pyth separado por espaço em branco corresponde a um token Pyth, um caractere ou um .seguido por um caractere. As exceções são os implicittokens, que estão implícitos no código Pyth.

Quero ver quão bom é o formato explicativo Big Pyth, então não darei nenhuma outra explicação. Pergunte-me se você quer algo explicado, no entanto.

isaacg
fonte
0

JavaScript (ES6), 140 bytes

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

Recebe entrada e saída como matrizes de strings. Também aceita uma entrada de matriz de caracteres bidimensional e salve 7 bytes se uma saída de matriz de caracteres bidimensional for aceitável. Explicação: A altura do resultado mé o mínimo da altura he largura wda matriz original, enquanto a largura é simplesmente um a menos que a soma da altura e largura da matriz original. A linha de origem dos caracteres na parte principal do resultado vem diretamente da linha apropriada da matriz original, contando a partir da parte inferior, enquanto na parte extra do resultado, a linha de origem sobe uma linha para cada coluna adicional. A coluna de origem para as duas metades do resultado é igual à coluna de destino movida uma coluna para a esquerda para cada linha de origem acima da parte inferior.

Neil
fonte
0

Oitava, 57 bytes

@(A){B=spdiags(A),C=B>0,D='  '(C+1),D(sort(C))=B(C),D}{5}
Rainer P.
fonte
0

Python 3, 247 bytes

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
fonte
Espaço em branco inútil em join(i) for.
Yytsi
0

Python 2, 150 bytes

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

Recebe entrada como lista de strings.

Arfie
fonte
0

Clojure, 194 bytes

Implementado da maneira mais difícil, agrupando caracteres Ge gerando linhas.

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

Toma a entrada como um vecde vecs como [[\a \b \c \d] [\1 \2 \3 \4] [\W \X \Y \Z]]. Exemplo:

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

  ab
 c123
d4WXYZ
NikoNyrh
fonte