Role o tapete

15

Essa pergunta é inspirada na pergunta de Kevin Cruijssen .

Agora que o tapete está arrumado, queremos enrolá-lo. Sua tarefa é escrever um programa que use uma string e retorne uma espiral feita com essa string (representando um tapete enrolado visto de lado).

O procedimento para uma etapa de rolar o tapete é o seguinte. Há um exemplo para ilustrar o que quero dizer. Observe que o exemplo começa com um tapete parcialmente enrolado para melhor entendimento:

ac
rpet
  • Separe a "cabeça" da "cauda" do tapete: a cabeça é o que foi rolado até agora, a cauda é o que resta a ser rolado.
Head: ac   Tail:
      rp          et
  • Gire a cabeça 90 °, no sentido horário.
Rotated head: ra   Tail (unchanged):
              pc                       et
  • se a largura da nova cabeça (aqui 2) for menor ou igual ao comprimento da cauda (aqui 2)
    • então, coloque em cima da cauda
    • caso contrário, o tapete (como estava no início da etapa) foi enrolado
New carpet: ra
            pc
            et

Repita o procedimento quantas vezes for necessário.


Dois exemplos mostrando todas as etapas do tapete rolando:

carpet

 c
 arpet

  ac
  rpet

    ra
    pc
    et
0123456789

 0
 123456789

  10
  23456789

    21
    30
    456789

      432
      501
      6789

Algumas precisões:

  • Você não precisa mostrar todas as etapas intermediárias, apenas o tapete enrolado (por exemplo, se você encontrar uma maneira não iterativa de calcular o resultado, é perfeito). Além disso, você não precisa imprimir nenhum espaço em branco à esquerda; nos exemplos acima, mostro apenas para alinhar as coisas.
  • Input é uma String, uma lista / matriz de caracteres
  • A saída é impressa em stdout ou em um arquivo.
  • A entrada é boa: o comprimento é de pelo menos 1 caractere e, no máximo, uma constante suficientemente pequena para que não cause problemas, mas você não pode usar essa constante em seu programa; o conteúdo da string é apenas caracteres legais ([a-zA-Z0-9]), codificando de acordo com sua preferência.
  • Isso é , então a resposta mais curta em bytes vence. Não permita que idiomas com código de golfe o desencorajem a postar respostas com idiomas que não sejam codegolf. Tente encontrar uma resposta o mais curta possível para 'qualquer' linguagem de programação.
  • As brechas padrão são proibidas.
  • Se possível, adicione um link com um teste para o seu código.
  • Além disso, adicione uma explicação para sua resposta, se achar necessário.
Bromind
fonte
2
Também este: codegolf.stackexchange.com/questions/125966/… , mas nenhum inclui a verificação de encerramento.
Bromind 05/04/19
3
Caso de teste sugerido: ProgrammingPuzzlesAndCodeGolf- o comprimento final da cauda maior que 1 me tropeçou.
Sok
1
Eu acho que você trocou as palavras "cabeça" e "cauda" aqui: "se a largura da nova cabeça [...] for maior ou igual ao comprimento da cauda [...]".
Erik the Outgolfer
1
Voto negativo devido a regras de entrada / saída excessivamente restritivas; Eu apaguei minha resposta do Python 2, pois não se pode usar printdentro de a lambda.
Chas Brown

Respostas:

7

Carvão , 15 bytes

FS«F¬℅§KV⁰⟲⁶→Pι

Experimente online! Link é a versão detalhada do código. Explicação:

FS«

Laço sobre o tapete.

F¬℅§KV⁰

Verifique se há algo acima do cursor.

⟲⁶

Caso contrário, role o tapete.

→Pι

Mova para a direita e emita o caractere atual.

Exemplo: Para a entrada 0123456789, ocorrem as seguintes ações:

0

0 é impresso.

01

O cursor se move para a direita e 1é impresso.

0
1

Como não há nada acima do 1 , a tela é girada.

0
12

O cursor se move para a direita e o 2é impresso.

10
2

Como não há nada acima do 2 , a tela é girada.

10
23

O cursor se move para a direita e o 3é impresso.

10
234

O cursor se move para a direita e o 4é impresso.

21
30
4

Como não há nada acima do 4 , a tela é girada.

21
30
45

O cursor se move para a direita e o 5é impresso.

21
30
456

O cursor se move para a direita e o 6é impresso.

432
501
6

Como não há nada acima do 6 , a tela é girada.

432
501
67

O cursor se move para a direita e o 7é impresso.

432
501
678

O cursor se move para a direita e o 8é impresso.

432
501
6789

O cursor se move para a direita e o 9é impresso.

Neil
fonte
Fantástico. Então, basicamente, o Charcoal possui um operador "roll" embutido ?
Jonah
1
@ Jonah Bem, não vai rolar para mim, mas ao exibir a string caractere por caractere eu posso rolar conforme for, sim.
214 Neil
3

Pitão, 37 bytes

.U+j;bZ.WgleHJlhH,+_MChZ<eZJ>eZJ,]hQt

Experimente online aqui ou verifique todos os casos de teste de uma vez aqui .

.U+j;bZ.WgleHJlhH,+_MChZ<eZJ>eZJ,]hQtQ   Implicit: Q=eval(input())
                                         Trailing Q inferred
                                 ]hQ     First character of Q, wrapped in an array
                                    tQ   All but the first character of Q
                                ,        2-element array of the two previous results
                                           This yields array with rolled carpet (as array of strings) followed by the tail
       .W                                While condition function is truthy, execute inner function, with initial value of the above:
         gleHJlhH                          Condition function, input H
             JlhH                            Number of layers in the current rolled carpet, store in J
          leH                                Lenth of the tail
         g   J                               Is the above greater than or equal to J?
                 ,+_MChZ<eZJ>eZJ           Inner function, input Z
                   _MChZ                     Rotate the current rolled carpet (transpose, then reverse each row)
                  +     <eZJ                 Append the first J characters of the tail as a new row
                 ,                           Pair the above with...
                            >eZJ             ... all but the first J characters of the tail - this is the new tail
.U+j;bZ                                  Join the carpet roll on newlines and append the tail, implicit print
Sok
fonte
3

Casca , 24 bytes

►S=ÖLmFȯ:T↔ø§z:oΘḣĠ+CṘ2N

Experimente online!

Explicação

Implicit input, say s="carpets"

CṘ2N  Break s into chunks:
   N   Natural numbers: [1,2,3,4,..
 Ṙ2    Repeat each twice: [1,1,2,2,3,3,4,4,..
C      Break s into chunks of these lengths: ["c","a","rp","et","s"]
       The last chunk is shorter if we run out of characters.

§z:oΘḣĠ+  Attempt to merge suffix of chunks:
      Ġ    Cumulative reduce chunk list from right
       +   by concatenation: ["carpets","arpets","rpets","ets","s"]
   oΘḣ     Prefixes of chunk list (empty and nonempty): [[],["c"],..,["c","a","rp","et","s"]]
§z         Zip these by
  :        appending: [["carpets"],["c","arpets"],..,["c","a","rp","et","s"]]
           These are all versions of the chunk list where some suffix has been merged.

mFȯ:T↔ø  Roll each list:
m         Map
 F        reduce from left
      ø   starting from empty character matrix
  ȯ:T↔    by this function:
    T↔     Reverse and transpose (rotating by 90 degrees)
  ȯ:       then append next chunk as new row.
         Result: [["carpets"],["c","arpets"],..,["epr","tca","s"]]

►S=ÖL  Select the matrix rolled by the correct amount:
►       Find element that maximizes
 S=     being equal to
   ÖL   sort by length.
        This selects a matrix whose rows have non-decreasing lengths.
        Ties are broken by choosing the rightmost one.
       Result: ["ra","pc","ets"]

Implicitly print each row separated by newlines.
Zgarb
fonte
2

J , 69 bytes

-3 bytes graças ao FrownyFrog

[:(}:@[,{:@[,])&>/[:((|:@|.@[,#@[$]);#@[}.])&>/^:(<:&#&>/)^:_,.@{.;}.

Experimente online!

explicação

[: (}:@[ , {:@[ , ])&>/ [: ((|:@|.@[ , #@[ {. ]) ; #@[ }. ])&>/^:(<:&#&>/)^:_ }. ;~ 1 1 $ {.

O algoritmo é direto, apesar de ser um pouco detalhado para J.

Estratégia geral: reduza a entrada para uma mesa quadrada, com uma peça restante (possivelmente vazia).

À medida que reduzimos, usaremos uma lista de 2 elementos. Nosso "resultado até agora" será a primeira caixa e "os itens restantes a serem processados" serão a segunda caixa. A primeira caixa será inicializada no cabeçalho da entrada (mas convertida em uma tabela):

1 1 $ {.

e "itens restantes a serem processados" serão a cauda da entrada:

}. ;~

Agora temos:

┌─┬─────┐
│c│arpet│
└─┴─────┘

onde o 'c' é na verdade uma tabela 1x1.

Reduzimos isso usando um loop J Do ... While:

^:(...)^:_

Onde a parte entre parênteses é a condição "continue":

<:&#&>/

que diz "continue enquanto o comprimento da caixa direita é maior ou igual ao comprimento da caixa esquerda (ou seja, o comprimento lateral da matriz quadrada)

O que significa "continuar"? Isso é definido no verbo à esquerda do primeiro ^:, que nos diz como obter o resultado atual e produzir a próxima iteração. Esse verbo é:

((|:@|.@[ , #@[ {. ]) ; #@[ }. ])&>/

Vamos dividir:

((|:@|.@[ , #@[ {. ]) ; #@[ }. ])&>/
(  verb in parens               )&>/ NB. put the verb in parens
                                     NB. between the two items
                                     NB. of our list, and unbox
                                     NB. them into left / right
                                     NB. args ([ / ]) for the verb
 (|:@|.@[ , #@[ {. ]) ; #@[ }. ]     NB. breaking down verb in 
                                     NB. parens...
                      ; ....         NB. new "remaining items":
                            }. ]     NB. remove from remaining
                        #@[          NB. the size of a side of
                                     NB. the result matrix
                ....  ;              NB. new "result":
  |:@|.@[                            NB. rotate existing result
          ,                          NB. and put it on top of
            #@[ {. ]                 NB. the items we removed
                                     NB. from remaining items

Ou seja, este é apenas um algoritmo descrito no OP traduzido literalmente em J.

Finalmente, lidamos com os (possivelmente 0) itens restantes, a cauda do nosso rolo de carpete:

(}:@[ , {:@[ , ])&>/

Isso diz "pegue tudo, exceto o último olmo do resultado":

}:@[ 

e anexá-lo aos ,últimos itens do resultado {:@[com os itens restantes anexados ao último item, ]

Jonah
fonte
Ah, J ... cartas são para noobs
RK.
,.pode fazer o que 1 1$]faz e $pode ser usado como {..
FrownyFrog
@FrownyFrog ty. Cheguei a 70 bytes com sua primeira sugestão, mas não tinha certeza se entendi $ can be used as {.- você pode esclarecer?
Jonah
1
A última linha da explicação, você usa {. para truncar, esse pode ser um $, tanto quanto eu entendo.
precisa saber é o seguinte
Além disso, você pode substituir o direito [: com um @
FrownyFrog
1

R , 146 132 bytes

function(s){m=F[F]
while({m=rbind(t(m)[,F:0],s[1:F])
s=s[-1:-F]
length(s)>sum(F<-dim(m))})0
write(m[F:1,],1,F[1],,"")
cat(s,sep="")}

Experimente online!

Implementa o procedimento de enrolar o tapete. Leva a entrada como uma lista de caracteres e imprime em stdout.

Salva 14 bytes, encontrando uma maneira de usar um do-whileloop e inicializando usando F.

function(s){
m=F[F]					# logical(0); create an empty array (this gets automatically promoted to character(0) later
while(					# do-while loop
      {m=rbind(t(m)[,F:0],s[1:F])	# rotate m counterclockwise and add the first F characters of s to the bottom
       s=s[-1:-F]			# remove those characters
       length(s)>sum(F<-dim(m))})0	# while the number of characters remaining is greater than the sum of m's dimensions
write(m[F:1,],1,F[1],,"")		# write the rolled portion write writes down the columns, we reverse each column
cat(s,sep="")				# and write the remaining characters
}
Giuseppe
fonte
1

Gelatina , 30 bytes

Parece excessivamente longo ...

ḢW,ðZU;Ls@¥©ḢWɗ,®Ẏ¤ð/ẈṢƑ$¿ḢY;Ɗ

Experimente online!

Quão?

ḢW,ðZU;Ls@¥©ḢWɗ,®Ẏ¤ð/ẈṢƑ$¿ḢY;Ɗ - Main Link: list of characters
Ḣ                              - pop and yield head
 W                             - wrap in a list
  ,                            - pair with (the remaining list after Ḣ)
                         ¿     - while...
                        $      - ...condition: last two links as a monad:
                     Ẉ         -   length of each
                       Ƒ       -   is invariant under:
                      Ṣ        -     sort
                    /          - ...do: reduce by:
   ð               ð           -   the enclosed dyadic chain -- i.e. f(head, tail):
    Z                          -     transpose
     U                         -     reverse each (giving a rotated head)
              ɗ                -     last three links as a dyad:
          ¥                    -       last two links as a dyad:
       L                       -         length (i.e. number of rows in current roll)
         @                     -         with swapped arguments:
        s                      -           split (the tail) into chunks of that length
           ©                   -       (copy to register for later)
            Ḣ                  -       pop and yield head (Note register "copy" is altered too)
             W                 -       wrap in a list
      ;                        -     concatenate (the rotated head with the first chunk of the tail)
                  ¤            -     nilad followed by link(s) as a nilad:
                ®              -       recall from register (other chunks of tail, or an empty list)
                 Ẏ             -       tighten (the chunks to a flat list)
               ,               -     pair (the concatenate result with the tightened chunks)
                             Ɗ - last three links as a monad:
                          Ḣ    -   pop and yield head
                           Y   -   join with newline characters
                            ;  -   concatenate (the remaining tail)
                               - when running as a full program implicitly prints
Jonathan Allan
fonte
1

05AB1E , 41 bytes

g©L¦€DD2šηO®>‹Ï©IŽ8OS®g4α._.ΛðÜI®O®g->.$«

Muito tempo, mas eu queria usar o Canvas. O que provavelmente foi uma má escolha agora que eu terminei e acabou sendo esse tempo ..

Experimente online . (Não há suíte de testes, porque parece haver um problema estranho com o built-in ..)

Explicação:

Deixe-me começar dando uma explicação geral do Canvas e o que eu queria que meu código realizasse. Informações mais detalhadas podem ser encontradas nesta dica relevante do 05AB1E , mas para esse desafio eu queria fazer o seguinte:

O Canvas integrado usa três parâmetros:

  • uma: O tamanho da (s) linha (s). Para este desafio, isso seria uma lista [2,2,3,3,4,4,5,5,...].
  • b: Os caracteres que queremos exibir. Para esse desafio, isso seria simplesmente a string de entrada.
  • c: A direção na qual queremos desenhar essas linhas de caracteres. Para esse desafio, essas seriam as direções[2,0 0,6,4] ([,,,]) girado nvezes, dependendo da sequência de entrada, para ter uma direção inicial diferente (ou seja, a entrada carpeté[0 0,6,4,2]em vez disso e a entrada 0123456789ABCDEFGHIé[6,4,2,0 0] em vez de).

Quanto ao código:

g                # Get the length of the (implicit) input-string
 ©               # Store it in the register (without popping)
  L              # Create a list in the range [1,length]
   ¦             # Remove the first item to make the range [2,length]
    D           # Duplicate each to get the list [2,2,3,3,4,4,5,5,...]
      D2š        # Create a copy and prepend a 2: [2,2,2,3,3,4,4,5,5,...]
         η       # Get the prefixes: [[2],[2,2],[2,2,2],[2,2,2,3],...]
          O      # Sum each prefix: [2,4,6,9,12,16,20,...]
           ®     # Push the length from the register again
            >‹   # Check for each summed prefix if it's <= length
              Ï  # And only leave the truthy values
               © # And store this in the register (without popping)
                 # (This is our `a` for the Canvas builtin)
I                # Push the input-string
                 # (This is our `b` for the Canvas builtin)
Ž8O              # Push compressed integer 2064
   S             # Converted to a list of digits: [2,0,6,4]
    ®g           # Push the list from the register, and get its length
      4α         # Get the absolute difference with 4
        ._       # And rotate the [2,0,6,4] that many times towards the left
                 # (This is our `c` for the Canvas builtin)
               # Now use the Canvas builtin, without printing it yet
  ðÜ             # Remove any trailing spaces (since the Canvas implicitly makes a rectangle)
     ®O          # Push the sum of the list from the register
       ®g-       # Subtract the length of the list from the register
          >      # And add 1
    I      .$    # Remove that many leading characters from the input-string
             «   # And append it at the end of the roll created by the Canvas
                 # (after which the result is output implicitly)

Veja este 05AB1E ponta do meu (seção Como comprimir grandes inteiros? ) Para entender por que Ž8Oé 2064.

Kevin Cruijssen
fonte
0

Python 3 , 112 bytes

r=lambda t,h=[[]]:len(h)>len(t)and h[:-1]+[h[-1]+list(t)]or r(t[len(h):],list(zip(*h[::-1]))+[list(t)[:len(h)]])

Nesse caso, a saída é o valor da função.

Experimente online!

Se preferir, aqui outra solução (mais longa, 129 bytes ) que imprime diretamente a entrada rolada:

r=lambda t,h=['']:len(h)>len(t)and set(map(print,h[:-1]+[h[-1]+t]))or r(t[len(h):],list(map(''.join,zip(*h[::-1])))+[t[:len(h)]])

Experimente online!

PieCot
fonte
1
precisa imprimi-lo
somente ASCII
@ Somente ASCII: citando o autor da pergunta: "Se retornar ao invés de imprimir mostrar uma grande melhoria ou um bom truque, poste uma resposta (e explique que você está retornando, não imprimindo)" . Então eu acho que está tudo bem.
PieCot
0

MATLAB / oitava , 154 bytes

Não é o mais curto, mas jogar golfe no MATLAB / Octave é sempre divertido :)

function h=r(t,h);n=fliplr(h');s=size(n,2);q=numel(t);if s<=q h=r(t(max(s,1)+1:end),[n; t(1:max(s,1))]);elseif q>0 h(:,end+q)=' ';h(end,end-q+1:end)=t;end

Experimente online!

PieCot
fonte
1
infelizmente, op diz que você tem que imprimir
ASCII-only
@ Somente ASCII, conforme explicado aqui ( it.mathworks.com/matlabcentral/answers/… ), stdout no mundo do Matlab refere-se à janela de comando. Dado que o resultado da avaliação de cada comando é impresso automaticamente na janela de comandos, acho que essa resposta pode ser considerada consistente com os requisitos da pergunta.
PieCot
talvez queira deixar isso mais claro então
ASCII-only
@ ASCII-only Eu não entendo o que você quer dizer, realmente. É uma função, como você chama, o resultado será impresso automaticamente na janela de comando (por exemplo, stdout). O que há de errado nisso? Até a resposta R funciona assim ...
#
1
Agora você disp, eu diria que você deve remover a dispdeixar as pessoas que não sabem R que faz gravação para STDOUT por padrão
ASCII-only