Desdobrar uma string

27

Dada uma sequência quadrada, produza toda a saída da sequência em todas as etapas do desenrolamento.

A corda deve desenrolar no sentido horário um quarto de volta de cada vez.

Exemplos

Entrada :

A

Saída :

A

Nota : Também aceitarei a entrada duplicada para este caso de teste específico apenas se isso ajudar a reduzir sua contagem de bytes.

Entrada :

DC
AB

Saída :

DC
AB

  D
ABC

ABCD

Entrada :

GFE
HID
ABC

Saída :

GFE
HID
ABC

   HG
   IF
ABCDE

     IH
ABCDEFG

       I
ABCDEFGH

ABCDEFGHI

Entrada :

JIHG
KPOF
LMNE
ABCD

Saída :

JIHG
KPOF
LMNE
ABCD

    LKJ
    MPI
    NOH
ABCDEFG

       NML
       OPK
ABCDEFGHIJ

          ON
          PM
ABCDEFGHIJKL

            PO
ABCDEFGHIJKLMN

              P
ABCDEFGHIJKLMNO

ABCDEFGHIJKLMNOP

Regras

Isso é portanto o código mais curto em bytes vence.

  • Qualquer formato razoável pode ser usado para E / S, assumindo que seja consistente.
  • Os espaços devem ser usados ​​para preencher as linhas superiores da saída.
  • Deve ser capaz de lidar com a entrada de todos os caracteres imprimíveis (incluindo espaço: \x20- \x7e):
 ! "# $% & '() * +, -. / 0123456789:;? @ ABCDEFGHIJKLMNOPQRSTUVWXYZ [\] ^ _` abcdefghijklmnopqrstuvwxyz {|} ~
  • O espaço em branco à esquerda / à direita é permitido.
  • Você pode assumir que a string sempre será um quadrado.
  • Todas as brechas padrão são proibidas.

Inspiração: escreva um programa quadrado que produz o número de vezes que foi "desenrolado" .

Dom Hastings
fonte
Que possamos saída ["A","A"]para "A", como o meu programa faz (em vez de ["A"])? Parece-me razoável, uma vez que são apenas as posições inicial e final, e você apenas tenta desdobrar uma vez.
Xcoder
@ Mr.Xcoder Eu concordo, adicionar código para atender a esse caso de teste específico parece um desperdício de bytes. Aceito a entrada de byte único e atualizo a pergunta de acordo!
Dom Hastings
3
+1 de mim, desafio muito interessante. Este site precisa de mais, pois eles aumentam o nível de dificuldade e eliminam a trivialidade da maioria das soluções. Isso vai direto para a minha lista de desafios favoritos. Estou desapontado que isso tem poucas respostas, porém, eu realmente gostaria também ver outras abordagens inteligentes
Mr. Xcoder
@ Mr.Xcoder Estou feliz que você gostou! Eu gostaria de ter o crédito por ter tido a ideia sozinha, mas tudo graças ao desafio de @ HelkaHomba !
Dom Hastings

Respostas:

9

SOGL V0.12 , 21 20 19 18 17 bytes

ø;[;ο⁴№č▓┼№TJι;jI

Experimente aqui! ( adicionado porque isso espera entrada na pilha)

Explicação:

ø;[;ο⁴№č▓┼№TJι;jI
ø;               push an empty string below the input           stack with the input GFE,HID,ABC
  [              while [ToS (the array) isn't empty] do       ["", [["G","F","E"],["H","I","D"],["A","B","C"]]]  
                                                                stack at the second time looping
   ;               duplicate 2nd from top                     [[[H,G], [I,F], [D,E]], "ABC"]
    ο              wrap it in an array                        [[[H,G], [I,F], [D,E]], ["ABC"]]
     ⁴             duplicate 2nd from top                     [[[H,G], [I,F], [D,E]], ["ABC"], [[H,G], [I,F], [D,E]]]
      №            reverse vertically                         [[[H,G], [I,F], [D,E]], ["ABC"], [[D,E], [I,F], [H,G]]]
       č▓          join the inner arrays (┼ fails otherwise)  [[[H,G], [I,F], [D,E]], ["ABC"], ["DE", "IF", "HG"]]
         ┼         add the 2 parts together                   [[[H,G], [I,F], [D,E]], ["ABCDE", "   IF", "   HG"]]
          №        reverse vertically again                   [[[H,G], [I,F], [D,E]], ["   HG", "   IF", "ABCDE"]]
           T       print that without popping                 [[[H,G], [I,F], [D,E]], ["   HG", "   IF", "ABCDE"]]
            J      take the last line off                     [[[H,G], [I,F], [D,E]], ["   HG", "   IF"], "ABCDE"]
             ι     remove the rest of the array               [[[H,G], [I,F], [D,E]], "ABCDE"]
              ;j   remove the last line of the original array ["ABCDE", [[H,G], [I,F]]]
                I  rotate it clockwise                        ["ABCDE", [[I,H], [F,G]]]
dzaima
fonte
7

Python 2 , 209 207 205 203 202 201 200 196 bytes

-4 bytes graças a @Quelklef !

s=input();l=len;k=''.join;exec"print s;s=[x for x in[' '*l(s[0])+k(x[:-1]for x in s[-2::-1])[t::l(s[0])-1]for t in range(l(s[0]))][:-1]+[s[-1]+k(x[-1]for x in s)[-2::-1]]if x.strip()];"*(2*l(s)-1)

Experimente online!

Python 2 , 219 217 215 213 212 211 207 bytes

s=input();l=len;k=''.join;exec"print'\\n'.join(s);s=[x for x in[' '*l(s[0])+k(x[:-1]for x in s[-2::-1])[t::l(s[0])-1]for t in range(l(s[0]))][:-1]+[s[-1]+k(x[-1]for x in s)[-2::-1]]if x.strip()];"*(2*l(s)-1)

Experimente online!

O primeiro gera como uma lista de Strings, o segundo gera como ASCII-art.

Mr. Xcoder
fonte
Eu acho que [::-1][1:]pode ser [-2::-1], como na resposta de Lynn.
Quelklef 23/08/19
@Quelklef Muito obrigado!
Xcoder
4

Carvão , 42 35 bytes

AEθSθW⊟θ«⪫θ¶AEι⮌⪫Eθ§μλωθ⊞υι↙←⮌⪫υωD⎚

Experimente online! Link é a versão detalhada do código. Editar: salvou 7 bytes principalmente alternando de matrizes de caracteres para seqüências de caracteres. Explicação:

AEθSθ

Leia o quadrado de entrada como uma matriz de cadeias na variável q.

W⊟θ«

Enquanto a última string da matriz não estiver vazia, remova-a.

⪫θ¶

Imprima o restante da matriz.

AEι⮌⪫Eθ§μλωθ

Gire o restante da matriz fazendo um loop por cada caractere da última string e juntando o lcaractere de cada string restante na matriz invertida.

⊞υι↙←⮌⪫υω

Anexe a última sequência removida anteriormente a u, que contém o valor não distribuído e imprima-a.

D⎚

Produza o resultado e limpe a tela pronta para a próxima iteração.

Observe que esta versão gera o desdobramento final em uma linha separada, se isso for indesejável para 38 bytes:

AEθSθW⊟θ«⊞υι←E⁺⟦⪫υω⟧⮌θ⮌κAEι⮌⪫Eθ§μλωθD⎚

Experimente online! Link é a versão detalhada do código. Explicação: ←E⁺⟦⪫υω⟧⮌θ⮌κinverte a matriz atual, acrescenta a linha não enrolada, inverte os caracteres em cada linha e imprime tudo de cabeça para baixo, produzindo o resultado desejado.

Neil
fonte
Eu tentei fazê-lo de forma mais Charcoal-y, mas eu não poderia trabalhar para fora onde o Rotatee Trimcomandos deixar o cursor ...
Neil
3

Haskell , 127 120 bytes

e=[]:e
i#[x]=[]
i#s|t<-foldl(flip$zipWith(:))e$init s,j<-i++last s=(map((j>>" ")++)(init t)++[j++last t]):j#t
f s=s:""#s

Experimente online!

Entrada é uma lista de linhas, por exemplo, ["DC","AB"]para o segundo caso de teste, a saída é uma lista de listas de linhas: [["DC","AB"],[" D","ABC"],["ABCD"]]. Use mapM (putStrLn . unlines)para imprimir bem o resultado.

Edit: Salvo 7 bytes, percebendo que quanto menortranspose eu encontrei um pouco vem a calhar, porque pode ser modificado para reverter cada transposta diretamente.

Laikoni
fonte
2

05AB1E , 18 bytes

[Dí.Bí»,¤UR¦ζŽ`Xì)

Experimente online!

Explicação

[            Ž       # while stack is not empty, do:
 D                   # duplicate current list
  í                  # reverse each element
   .B                # pad with spaces to equal length
     í               # reverse each element again
      »,             # join with newlines and print
        ¤U           # store the last element in X
          R¦         # reverse the list and remove the first element
            ζ        # zip with spaces as filler
              `      # split elements separately to stack
               Xì    # prepend X to the last element
                 )   # join the stack to a list
Emigna
fonte
2

J, 62 bytes

|."1@([:(#~[:-.[:*/"1' '=])|.@{:(}:@],{:@],[)|:@}:)^:(1<#)^:a:

Experimente online!

Tenho certeza que isso pode ser muito praticado. Isso imprime espaço em branco extra, mas apenas devido à maneira como J formata as matrizes contidas na matriz de saída para ter a mesma forma.

Acho que quando eu comentar e comentar exatamente o que estou fazendo, talvez eu tenha uma idéia melhor de como jogar isso (depois de fazer isso agora, eu realmente não sei ...). Para fins de golfe, vale a pena notar que

  • Eu tenho que o caso especial 1 entradas de linha (a parte while do loop)
  • Eu tenho que eliminar todas as linhas que consistem apenas de espaços em branco (certamente deve haver um builtin para isso ou uma maneira melhor de fazê-lo), que é o filtro próximo ao fim
  • Existem muitos limites, funções de identidade e atops

Explicação

Ao desfazer isso, dividirei a função principal em três.

unfurl_reversed   =. |.@{: (}:@] , {:@] , [) |:@}:
whitespace_filter =. #~ [: -. [: */"1 ' ' = ]
unfurl            =. |."1@(whitespace_filter @: unfurl_reversed) ^: (1 < #) ^: a:

test_case         =. 3 3 $ 'GFEHIDABC'

Trabalharemos com o segundo caso de teste.

unfurl_reversed

|.@{: (}:@] , {:@] , [) |:@}:

Isso dá uma seqüência de caracteres desenrolada uma vez, mas ao contrário. Tudo isso está sendo feito no sentido inverso e em uma ordem específica, de forma que o modo como J preencha automaticamente as seqüências de caracteres com espaços para corresponder à forma da matriz em que estão, forneça o espaçamento correto.

|:@}: é a transposição do corte da entrada

   |:@}: test_case
GH
FI
ED

|.@{: é o reverso da cauda da entrada

   |.@{: test_case
CBA

Acho que você pode ver o que queremos fazer: queremos acrescentar o reverso da cauda à última parte da transposição do corte (isso é um bocado, mas basicamente anexa CBAao final de ED). Isso nos dará um passo de desenrolar, invertido.

(}:@],{:@],[) faz exatamente isso.

Ele anexa CBAa e ED, em seguida, associa isso ao restante da matriz. Nossa produção, portanto, é

   unfurl_reversed test_case
GH   
FI   
EDCBA

whitespace_filter

#~ [: -. [: */"1 ' ' = ]
                 ' ' = ]  Equate each element to space
            */"1          Product of each row (all true?)
      -.                  Negate
#~                        Filter rows that are true

Basicamente, isso testa para ver se alguma linha é completamente espaços e a remove, se for. Não faz nada para a primeira iteração do caso de teste.

Isso é necessário (pelo menos até que eu encontre uma alternativa), pois caso contrário, eventualmente estaremos desenrolando espaço em branco em nossa string de saída.

desenrolar

|."1@(whitespace_filter @: unfurl_reversed) ^: (1 < #) ^: a:

O desenrolar basicamente une as outras funções e casos especiais de entrada de caracteres únicos.

Quando o poder do verbo ( ^:) recebe a caixa vazia ( a:), ele aplica uma função em uma entrada até convergir e coletar os resultados em uma matriz.

(1 < #) verifica se as linhas são sempre maiores que 1 (para o caso especial de 1 entrada de linhas).

|."1inverte cada linha e inverte os resultados de whitespace_filter @: unfurl.

Cole
fonte
1

Python 2 , 143 132 bytes

a=input()
while 1:print'\n'.join(a);b=map(''.join,zip(*map(str.strip,a[-2::-1])));a[-1]+=b.pop();a[:-1]=[len(a[0])*' '+x for x in b]

Experimente online!

Em cada iteração, bé a “cabeça” da string (primeiras n-1 linhas), girada 90 graus: se afor, [" NML", " OPK", "ABCDEFGHIJ"]então bé ["ON", "PM", "KL"].

Para desenrolar uma string uma vez, anexamos a linha final de bto a[-1](giving "ABCDEFGHIJKL") e, em seguida, recalculamos a[:-1]adicionando espaços ao restante das strings b.

Terminamos tentando sair bquando está vazio.

Python 2 , 132 bytes

a=input()
while 1:s=str.strip;print'\n'.join(a);a[:-1]=[len(a[0])*' '+''.join(x)for x in zip(*map(s,a[-2::-1]))];a[-1]+=s(a.pop(-2))

Experimente online!

Mesma ideia, escrita de forma diferente. Terminamos tentando a.pop(-2)quando apossui apenas um elemento.

Lynn
fonte
1

Perl 5 , 155 bytes

$"=$,;@a=map[/./g],<>;while(@a){say' 'x(length$s)."@$_"for@a[0..@a-2];say$s.="@{pop@a}";say@b=();for$i(0..$#a){$q=0;$b[$q++][$#a-$i]=$_ for@{$a[$i]}}@a=@b}

Experimente online!

Economizou alguns bytes sem realmente modificar a lógica. O fluxo abaixo ainda está basicamente correto.

# Perl 5 , 163 bytes

$"=$,;@a=map[/./g],<>;while(@a){say' 'x(length$s)."@{$a[$_]}"for 0..@a-2;say$s.="@{pop@a}";say@b=();for$i(0..$#a){$b[$_][$#a-$i]=$a[$i][$_]for 0..$#{$a[$i]}}@a=@b}

Experimente online!

Quão?

$"=$,; #set the array output separator to null
@a=map[/./g],<>;   # take the input as a 2-D array @a
while(@a){         # repeat while there are still things to unfurl
  say' 'x(length$s)."@{$a[$_]}"for 0..@a-2; # output all but last
                                            # line of the remaining
                                            # square
  say$s.="@{pop@a}";  # remove bottom row, add it to the unfurled string $s
                      # and output it
  say@b=();           # clear temporary array; output empty array, causing
                      # a newline to output

                      # rotate remaining shape 90 degrees:
  for$i(0..$#a){$b[$_][$#a-$i]=$a[$i][$_]for 0..$#{$a[$i]}}
  @a=@b               # replace input with rotated array
}
Xcali
fonte
Bom método, mas estou atrás da saída em cada estágio do desenrolamento, você poderia atualizar para imprimir todas as etapas? Desculpe!
Dom Hastings
1
OK, eu reescrevi.
Xcali
Perfeito, obrigado! Desculpe por causar bytes extras ...
Dom Hastings