Os caracteres na corda dão voltas e voltas


23

(Inspirado por um rascunho inicial do desafio da linha fractal do PhiNotPi .)

Você recebe uma largura W > 1, uma altura H > 1e uma sequência que consistem em 2(W+H-2)caracteres ASCII imprimíveis. A tarefa é imprimir essa sequência em volta de um retângulo da largura e altura especificadas, começando no canto superior esquerdo, no sentido horário. O interior do retângulo é preenchido com espaços. Esperamos que os casos de teste deixem isso muito claro.

Você pode escrever um programa ou função, recebendo entrada via STDIN (ou alternativa mais próxima), argumento de linha de comando ou argumento de função e imprimindo o resultado em STDOUT (ou alternativa mais próxima) ou retornando-o como uma sequência.

Não deve haver espaços à esquerda ou à direita (além daqueles que possam estar na cadeia de entrada). Opcionalmente, você pode gerar uma única nova linha à direita.

Isso é código de golfe, então a submissão mais curta (em bytes) vence.

Casos de teste

Cada caso de teste é "String" W Hseguido pela saída esperada.

"Hello, World! "
5 4
Hello
    ,
!    
dlroW

"+--+|||+--+|||"
4 5
+--+
|  |
|  |
|  |
+--+

">v<^"
2 2
>v
^<

"rock beats scissors beats paper beats "
11 10
rock beats 
          s
s         c
t         i
a         s
e         s
b         o
          r
r         s
epap staeb 

Note that the following string contains an escaped '"'.
"!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
46 3
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN
~                                            O
}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQP

Classificação

Aqui está um snippet de pilha para gerar uma classificação regular e uma visão geral dos vencedores por idioma.

Para garantir que sua resposta seja exibida, inicie-a com um título, usando o seguinte modelo de remarcação:

# Language Name, N bytes

onde Nestá o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:

# Ruby, <s>104</s> <s>101</s> 96 bytes


8
Suas tabelas de classificação são muito legais.
Alex A.

2
Você jogou seu script no placar de golfe?
mbomb007

2
@ mbomb007 Não, eu corri o código através de minificadores, para que não ocupasse muito espaço quando expandido. (Eu acho que remover quebras de linha teria sido suficiente.) Ainda tenho uma versão não minificada no meu disco rígido.
Martin Ender

2
Se você renomeou isso para "Os caracteres na corda vão girando e girando", ele se encaixa melhor no ritmo da música.
Justin

Respostas:


9

CJam, 27 bytes

Nl~:L/(os\2-{)L2-S*@(N@}*W%

Eu realmente não CJam, mas acho que isso bate em Martin. A principal diferença é que pressionamos uma nova linha antes de ler a entrada e imprimimos a primeira linha imediatamente, negando a necessidade de armazenar a altura.

Recebe entrada na ordem

H "String" W

Experimente online.


10

Python 2, 95 bytes

s,m,n=input()
print s[:n]
for i in range(m-2):print s[~i]+' '*(n-2)+s[n+i]
print s[1-m::-1][:n]

Imprime a primeira linha, as duas linhas verticais e a última linha.

Tem que haver algo mais curto do que escrever printtrês vezes, mas tudo o que tentei até agora ao salvar em uma variável e '\n'.joinfoi mais longo.


Você poderia mudar para Python 3 e loja de impressão em uma variável ...
Omar

1
@Omar Isso acaba sendo mais demorado porque você precisa usar evala entrada e colocar as instruções de impressão entre parênteses.
FryAmTheEggman 13/03/2015

Oh, eu não tinha levado evalem conta! O parêntese não deve ser muito problemático, já que printno Python 2 precisa de um espaço depois dele. Passar de print blahpara p(blah)ainda salva 3 caracteres.
Omar

9

CJam, 31 30 bytes

Por insistência do Optimizer, aqui está minha própria tentativa. Eu não sou fã de vencer meus próprios desafios, então estou contando a família APL (ou alguém melhor no CJam) para vencer isso. ;)

l~:H;:V/(N@s{)V2-S*@(N@}H2-*W%

Recebe entrada na mesma ordem que a pergunta:

"Hello, World! " 5 4

Teste aqui.

Um byte economizado graças ao Optimizer.

Explicação

Originalmente, eu tinha uma ideia muito boa de começar com o retângulo de espaços e, em seguida, literalmente enrolar a corda ao redor dela enquanto girava a grade inteira quatro vezes. No entanto, não consegui fazer isso funcionar no caso de largura, altura ou ambas 2. Então, tentei a abordagem ingênua (parte superior de impressão, laço nas laterais, parte inferior de impressão) e, surpreendentemente, ela foi realmente curta.

l~                             "Read and evaluate the input.";
  :H;                          "Store the height in H and discard it.";
     :V/                       "Store the width in V and split the input into chunks of size V.";
        (N                     "Slice off the first such chunk and push a newline.";
          @s                   "Pull up the other chunks and join them back together.";
            {          }H2-*   "Repeat this block H-2 times, printing the sides.";
             )                 "Slice off the last character of the string.";
              V2-S*            "Push V-2 spaces.";
                   @(          "Pull up the remaining string and slice off the first character.";
                     N@        "Push a newline and pull up the remaining string.";
                            W% "Reverse the remainder of the string, which is the bottom row.";

Como podemos obter o comprimento da string e temos V, não há necessidade de salvar H. Apenas repita o bloco até restarem apenas V caracteres. l~;:V/(N@s{)V2-S*@(N@_,V-}gW%salva 1 caractere.
DocMax 13/03/2015

@DocMax Infelizmente, isso não funciona para a altura 2. É uma boa ideia, porém, vou ver se posso usá-lo de uma maneira diferente.
Martin Ender

D'oh! Você até mencionou o problema H = 2 e ainda me esqueci de me proteger.
DocMax 13/03/2015

9

Pitão, 47 46 45 40 37 36 bytes

Essa é a abordagem óbvia implementada no Pyth. Imprime a primeira linha indexando 0:widthe depois no meio e depois no final.

Obrigado a @Jakube pela dica de usar ze Qpor duas entradas e uso p.

AkYQ<zkV-Y2p*d-k2@zt_N@z+kN;<_<z-2Yk

Recebe a entrada do stdin como uma sequência e como uma tupla de dimensões, nova linha separada:

Hello, World! 
5, 4

e escreve para stdout.

Experimente aqui .

A              Double assignment
 kY            The vars k and Y
 Q             The dimension tuple
<zk            Prints out first line by doing z[:width]
V-Y2           For N in height-2
 p             Print out everything
  *d           Repeat " "
   -k2         Width-2 times
  @z           Index z
   -_N1        At index -N-1
  @z           Index z
   +kN         At index k+N
;              Close out loop
<_<z-2Yk       Print last line

Usar zpara ler a string economiza muitos caracteres. Também t_Né a mesma coisa que -_N1.
Jakube 13/03/2015

São possíveis 37 caracteres com a nossa abordagem.
Jakube 13/03/2015

@Jakube obrigado pelas dicas!
Maltysen 13/03/2015

Mais uma economia de char. Em vez de ++usar pe alterne zt_Ncom *d-k2.
Jakube 13/03/2015

5

J, 61 bytes

Método:

Começando com um (height-2)*(width-2)bloco de espaços, pegamos a quantidade necessária de caracteres do final da string e a adicionamos ao bloco atual. Repetimos isso 4 vezes. O total de 5 estados ilustrados com o 'Hello, World! ' 5 4exemplo (espaços substituídos por Xs para facilitar a leitura):

XXX   !_   orld   ,_W   Hello
XXX   XX   XXX!   XXo   _XXX,
      XX   XXX_   XXr   !XXX_
      XX          XXl   dlroW
                  _!d   

O código:

4 :'|:>{:((}.~{:@$);({.~{:@$)|.@|:@,])&>/^:4(|.x);'' ''$~y-2'

Definição de função explícita. A função de dois operandos usa uma string como argumento à esquerda e uma lista de dois números inteiros como argumento à direita.

Exemplo de uso:

   wrap_on=.4 :'|:>{:((}.~{:@$);({.~{:@$)|.@|:@,])&>/^:4(|.x);'' ''$~y-2'

   'Hello, World! ' wrap_on 5 4
Hello
    ,
!    
dlroW

   '>v<^' wrap_on 2 2
>v
^<

Experimente online aqui.


Uau, estou impressionado que isso funciona para a largura e altura 2 em J.
Martin Ender

4

Pyth, 38 37

AGHQ<zGFNC,_>z_ttH>zGj*dttGN)<>_zttHG

Originalmente, eu tinha uma solução diferente, mas era basicamente a solução para o problema da resposta de Maltysen. Então eu decidi ir um pouco diferente.

Experimente online .

              implicit: z=string from input, Q=pair of numbers from input
AGHQ          G=Q[0] (width), H=Q[1] (height)
<zG           print z[:G]
    _>z_ttH     last H-2 chars reversed
    >zG         all chars from the Gth position to end
  C,           zip these 2 strings to pairs
FN            for each pair N:
  j*dttGN       seperate the two chars by (G-2) spaces and print
)             end for
<>_zttHG     print last line z[::-1][H-2:][:G]

_>z_ttHé equivalente a <_zttH.
Isaacg 13/03/2015

@isaacg Obrigado, já vi algo semelhante na resposta de Maltysen.
Jakube 13/03/2015

4

JavaScript (ES6), 110 115

Função com 3 parâmetros, retornando uma string

F=(s,w,h,q=h+(w-=2),t=b='')=>
[for(c of s)q?t+=q<h?c+'\n'+s[w+h+w+q--]+' '.repeat(q&&w):(b+=s[w+q--],c):q]
&&t+b

Chrome versão 119 : sem formato curto para funções, sem parâmetros padrão. Não há razão para usar, for(of)mesmo que seja suportado

function F(s,w,h){
  for(q=h+(w-=2),t=b=i='';
      q;
      q<h?t+='\n'+s[w+h+w+q--]+' '.repeat(q&&w):b+=s[w+q--])
    t+=s[i++];
  return t+b
}

ES5 versão 126 : no for (of), no string.repeat

function F(s,w,h){
  for(q=h+(w-=2),t=b=i='';
      q;
      q<h?t+='\n'+s[w+h+w+q--]+Array(q&&-~w).join(' '):b+=s[w+q--])
    t+=s[i++];
  return t+b
}

Ungolfed

F=(s,w,h)=>
{
  var q = h+(w-=2), // middle length 
      t = '', // top and body
      b = ''; // bottom row
  for(c of s)
    if (q > 0)
    {
      if (q < h)
      {
        t += c+'\n'; // right side, straight
        t += s[w+h+w+q]; // left side, backwards 
        if (q > 1) // body fill, except for the last line
          t += ' '.repeat(w)
      }
      else
      {
        t+=c, // top, straight
        b+=s[w+q] // bottom, backwards
      }
      --q
    }
  return t+b

Teste no console Firefox / FireBug

;[["Hello, World! ", 5, 4],["+--+|||+--+|||",4,5],[">v<^",2,2]
,["rock beats scissors beats paper beats ",11,10]
,["!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~",46,3]]
.forEach(test => console.log(F(...test)))

Saída

Hello
    ,
!    
dlroW

+--+
|  |
|  |
|  |
+--+

>v
^<

rock beats 
          s
s         c
t         i
a         s
e         s
b         o
          r
r         s
epap staeb 

!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN
~                                            O
}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQP

3

Python 2, 97 bytes

def f(s,w,h):print s[:w];i=0;exec'print s[~i]+" "*(w-2)+s[w+i];i+=1;'*(h-2);print s[1-h:w+h-3:-1]

Tomando a abordagem direta.


3

Haskell, 164 156 bytes

import Data.List
r=replicate
p w h(s:t)=unlines$fst$n$n$n$n(r h$r w ' ',(w,h,s:t++[s]))
n(_:b,(w,h,s))=(transpose$map reverse$(take w s):b,(h,w,drop(w-1)s))

A função pnão imprime a saída, mas a retorna como uma sequência, por exemplo p 4 5 "+--+|||+--+|||"- -> "+--+\n| |\n| |\n| |\n+--+\n". Para melhor visualização, use putStr:

putStr $ p 4 5 "+--+|||+--+|||"

+--+
|  |
|  |
|  |
+--+

Como funciona: crio um bloco wx hde espaços e substituo a primeira linha pelo início da string de entrada. Depois, giro o bloco no sentido anti-horário e repito substituindo a primeira linha mais três vezes.

Para impedir o corte do primeiro caractere novamente após o turno # 4, anexe-o à string de entrada antes de iniciar.

"Hello World" example, 5 x 4


         |  Start               Turn #1          Turn #2     Turn #3   Turn #4
---------+--------------------------------------------------------------------
String   |  "Hello, World! H"   "o, World! H"    "World! H"  "d! H"    ""
left     | 
         |
Block    |  <empty>             Hello            o, W        World     d! H
before   |                                       l                     l  e
rotating |                                       l           ,         r  l
         |                                       e           olleH     o  l
         |                                       H                     W ,o

Edit: encontrou uma maneira melhor de resolver o problema do cut-off-first-character-after-turn- # 4.


Ah legal ... isso é semelhante ao que eu tentei no CJam, exceto que funciona. ;)
Martin Ender

3

Postscript, 62 bytes

Obviamente, isso usa tokens binários, mas é equivalente a:

/Courier findfont setfont

0 h moveto

s [
    w {1 0} repeat pop pop
    h {0 -1} repeat pop pop
    w {-1 0} repeat pop pop
    h {0 1} repeat
] xyshow

Aqui está um hexdump do arquivo ( xxd round.ps):

0000000: 91c7 9243 9295 3020 6892 6b73 5b77 7b31  ...C..0 h.ks[w{1
0000010: 2030 7d92 8392 7592 7568 7b30 202d 317d   0}...u.uh{0 -1}
0000020: 9283 9275 9275 777b 2d31 2030 7d92 8392  ...u.uw{-1 0}...
0000030: 7592 7568 7b30 2031 7d92 835d 92c3       u.uh{0 1}..]..

Correr como:

gs -dw=11 -dh=10 -ss="rock beats scissors beats paper beats " round.ps

A saída é realmente pequena (como resultado de não ter escalado a fonte), portanto, é necessário aumentar o zoom um pouco para vê-la.

Isso tira vantagem do xyshowoperador para escrever a sequência usando espaçamento de caracteres personalizado. Nesse caso, eu uso o espaçamento vertical negativo para escrever, depois o espaço horizontal negativo para escrever para trás, depois o espaço vertical positivo para escrever para cima. Por causa disso, não preciso usar nenhum tipo de manipulação de string.


3

> <>, 82 80 + 3 = 83 bytes

:2-&\
v!?:<oi-1
/?(0:i
\~ao{2-{~}
\{:?!v1-}o&:&
>:?v!~{{o}ao4.
^  >" "o1-
o;!?l<

Página Esolang para> <> (Peixe)

Isso acabou sendo mais curto do que eu esperava. Ele usa a abordagem direta de imprimir a primeira linha, depois as colunas preenchidas com os espaços centrais e depois a última linha.

Insira a string via STDIN e a altura e largura via linha de comando com o -v bandeira, da seguinte maneira:

py -3 fish.py round.fish -v <height> <width>

Explicação

:2-&           Put W-2 in the register
:?!v1-io       Directly print the first W characters of the input
i:0(?/         Read the rest of the input
~ao{2-{~}      Pop a few leftovers 0s from above, decrement H by 2 and print a newline
               Stack now consists of H = H-2 at the bottom and the rest of the input reversed

[loop]

{:?!v          If H is 0...
  ~                Pop the 0
  l?!;o            Print the rest of the (reversed) input

               Otherwise...
  1-}              Decrement H
  o                Output the top of stack
  &:&              Copy I = W-2 from the register
  :?               If I is nonzero...
    " "o1-             Print a space and decrement I, then repeat from the previous line
  {{o}ao           Print the bottom input character and output a newline
  4.               Jump to the start of the loop (note that I = 0 is leftover from above)

2

Bash + coreutils, 124

Um script de shell para você começar:

echo "${3:0:$1}"
fold -1<<<"${3:$1*2+$2-2}"|tac|paste - <(fold -1<<<"${3:$1:$2-2}")|expand -t$[$1-1]
rev<<<"${3:$1+$2-2:$1}"

Passe a entrada como argumentos da linha de comando:

$ ./roundnround.sh 5 4 "Hello, World! "
Hello
    ,
!    
dlroW
$ 

2

JavaScript, 161 160 158 bytes

O método que eu inventei ficou muito tempo, mas tudo bem, tem sido prática. (Além disso, entendi bem r+o[u]+'\n':d.)

function f(o,w,n){s=o.slice(0,w)+'\n';o=o.slice(w);n-=2;r='';for(u=w-2;u--;)r+=' ';for(u=d=0;d=o[2*n+w+~u],u<w+n;u++)s+=(u<n)?(d||' ')+r+o[u]+'\n':d;return s}

Para entradas que não fazem sentido, a saída é indefinida (literalmente e várias vezes), mas funciona para todos os casos de teste.


sliceé menor do que substr, não é exatamente o mesmo, mas neste caso, você pode usá-lo
edc65

2

Groovy, 140

f={a,x,y->println a.substring(0,x);(1..y-2).each{println a[a.length()-it]+' '*(x-2)+a[it+x-1]}println a.substring(x+y-2,2*x+y-2).reverse()}

ligar:

f('rock beats scissors beats paper beats ',11,10)

saída:

rock beats 
          s
s         c
t         i
a         s
e         s
b         o
          r
r         s
epap staeb 

2

K, 55 54 bytes

Usando a mesma abordagem da implementação J do randomra; Comece com um bloco de espaços e adicione da cauda da corda até a borda enquanto gira quatro vezes:

f:{`0:*4{((,r#*|x),|:'+*x;(r:-#*x)_*|x)}/((y-2)#" ";x)}

E alguns exemplos:

  f["Hello,_World!_";4 5]
Hello
_   ,
!   _
dlroW

  f[">v<^";2 2]
>v
^<

Quebrando um pouco para facilitar a leitura,

Gere um bloco NxM:

  t:2 3#!6
(0 1 2
 3 4 5)

Gire 90 graus usando transpose ( +) e inverta cada ( |:'):

  |:'+t
(3 0
 4 1
 5 2)

Então, se temos um bloco de espaços te uma corda s, podemos preceder uma fatia da cauda de sa t:

  s: 12 18 17 8 9
12 18 17 8 9
  (,(-#t)#s),|:'+t
(8 9
 3 0
 4 1
 5 2)

Usamos o formulário 4 {[x] ... }/( ... )para aplicar repetidamente uma função a uma tupla que consiste na string e na matriz que estamos construindo. Cada vez que executamos essa etapa de rotação e concatenação, também cortamos a corda.

editar:

Outra idéia é tentar dividir a string de entrada nos fragmentos que queremos a cada rotação, o que simplifica o corpo principal do programa. Infelizmente, isso funciona um pouco mais a 56 bytes:

f:{`0:((y-2)#" "){|:'(,y),+x}/(+\(0,y[0 1 0]-2 1 1))_|x}

Se houver uma maneira melhor de calcular esses pontos de divisão, estou aberto a sugestões.

edit2:

Reorganizar um pouco permite remover um par de parênteses. 54 bytes!

f:{`0:((y-2)#" "){|:'(,y),+x}/(0,+\y[0 1 0]-2 1 1)_|x}

2

K, 80 bytes 68

f:{[s;y;n]`0:(,n#s),({s[(#s)-x+2],((n-2)#" "),s@n+x}'!y-2),,n#|-4!s}

Reduzido de 80, graças a @JohnE.

Original:

f:{s:x;n:z;`0:(,s@!n),({s[(#s)+-2-x],({" "}'!n-2),s@n+x}'!y-2),,(|s@!-4+#s)@!n}

Eu nem sei como isso funciona.

Exemplo de uso:

f["Hello, world! ";5;4]

Existem algumas otimizações possíveis, mas continuo fazendo o Kona segfault ...


Você pode melhorar esta um pouco usando 'take' (dyadic #) e uma lista de argumentos explícitos: f:{[s;y;n]`0:(,n#s),({s[(#s)-x+2],((n-2)#" "),s@n+x}'!y-2),,n#|-4!s}. 68 caracteres pela minha contagem.
Johne

@JohnE Thanks! Eu sabia sobre a lista de argumentos explícitos, mas de alguma forma me escapou; Eu não tinha idéia do número diádico, no entanto.
kirbyfan64sos

2

R, 178

Esta é uma função sem nome, tendo s, w, hcomo parâmetros. Eu gostaria que houvesse uma maneira melhor de dividir a corda.

function(s,w,h){W=w+h-1;H=w+W-1;S=strsplit(s,'')[[1]];O=array(" ",c(h,w+1));O[,w+1]="\n";O[1:h,c(w,1)]=c(S[w:W],S[(W+W-1):H]);O=t(O);O[1:w,c(1,h)]=c(S[1:w],S[H:W]);cat(O,sep='')}

Ungolfed

W=w+h-1;                                 # additional index points
H=w+W-1;                                 # additional index points
S=strsplit(s,'')[[1]];                   # vectorize the string
O=array(" ",c(h,w+1));                   # create an array of spaces
O[,w+1]="\n";                            # set newlines
O[1:h,c(w,1)]=c(S[w:W],S[(W+W-1):H]);    # build middles lines
O=t(O);                                  # transpose array
O[1:w,c(1,h)]=c(S[1:w],S[H:W]);          # build top and bottom lines
cat(O,sep='')                            # cat out results

Execução de teste

> (function(s,w,h){W=w+h-1;H=w+W-1;S=strsplit(s,'')[[1]];O=array(" ",c(h,w+1));O[,w+1]="\n";O[1:h,c(w,1)]=c(S[w:W],S[(W+W-1):H]);O=t(O);O[1:w,c(1,h)]=c(S[1:w],S[H:W]);cat(O,sep='')})("Hello, World! ",5,4)
Hello
    ,
!    
dlroW
> (function(s,w,h){W=w+h-1;H=w+W-1;S=strsplit(s,'')[[1]];O=array(" ",c(h,w+1));O[,w+1]="\n";O[1:h,c(w,1)]=c(S[w:W],S[(W+W-1):H]);O=t(O);O[1:w,c(1,h)]=c(S[1:w],S[H:W]);cat(O,sep='')})("+--+|||+--+|||",4,5)
+--+
|  |
|  |
|  |
+--+
> (function(s,w,h){W=w+h-1;H=w+W-1;S=strsplit(s,'')[[1]];O=array(" ",c(h,w+1));O[,w+1]="\n";O[1:h,c(w,1)]=c(S[w:W],S[(W+W-1):H]);O=t(O);O[1:w,c(1,h)]=c(S[1:w],S[H:W]);cat(O,sep='')})(">v<^",2,2)
>v
^<
> (function(s,w,h){W=w+h-1;H=w+W-1;S=strsplit(s,'')[[1]];O=array(" ",c(h,w+1));O[,w+1]="\n";O[1:h,c(w,1)]=c(S[w:W],S[(W+W-1):H]);O=t(O);O[1:w,c(1,h)]=c(S[1:w],S[H:W]);cat(O,sep='')})("rock beats scissors beats paper beats ",11,10)
rock beats 
          s
s         c
t         i
a         s
e         s
b         o
          r
r         s
epap staeb
> # Escaped the \ as well 
> (function(s,w,h){W=w+h-1;H=w+W-1;S=strsplit(s,'')[[1]];O=array(" ",c(h,w+1));O[,w+1]="\n";O[1:h,c(w,1)]=c(S[w:W],S[(W+W-1):H]);O=t(O);O[1:w,c(1,h)]=c(S[1:w],S[H:W]);cat(O,sep='')})("!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~",46,3)
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN
~                                            O
}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQP
> 

2

T-SQL, 307

Embora ainda horrendamente longo, isso acabou sendo um pouco mais fácil (e mais curto) do que eu pensava em uma consulta. Implementado como uma função com valor de tabela embutida para T-SQL.

CREATE FUNCTION f(@S VARCHAR(MAX),@ INT,@H INT)RETURNS TABLE RETURN WITH R AS(SELECT 2i,LEFT(@S,@)S,STUFF(@S,1,@,'')+'|'R UNION ALL SELECT i+1,CASE WHEN i<@H THEN LEFT(RIGHT(R,2),1)+REPLICATE(' ',@-2)+LEFT(R,1)ELSE REVERSE(LEFT(R,@))END,STUFF(STUFF(R,LEN(R)-1,1,''),1,1,'')FROM R WHERE i<=@H)SELECT S FROM R

Isso ocorre através da sequência @h vezes. A primeira recursão recorta os caracteres @W da string. As recursões do meio retiram a última e a primeira da string restante, com preenchimento de string entre elas. A última recursão reverte o que resta. Existem alguns caracteres perdidos que lidam com a maneira como o SQL Server trata os espaços finais no VARCHARS.

Execução de teste

WITH TestSet AS (
    SELECT *
    FROM (VALUES
        ('Hello, World! ',5,4),
        ('+--+|||+--+|||',4,5),
        ('>v<^',2,2),
        ('rock beats scissors beats paper beats ',11,10),
        ('!"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~andfoure',50,3)
        ) Test(S,W,H)
)
SELECT x.S 
FROM TestSet 
    CROSS APPLY (
        SELECT S FROM dbo.F(S,W,H)
        )x

S
----------------------------
Hello
    ,
!    
dlroW
+--+
|  |
|  |
|  |
+--+
>v
^<
rock beats 
          s
s         c
t         i
a         s
e         s
b         o
          r
r         s
epap staeb 
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQR
e                                                S
ruofdna~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUT

(24 row(s) affected)


2

MATLAB, 101

function f(H,W,S)
w=1:W;h=(0:H-3).';n=W+H-2;S(3*n)=' ';S([w;[2*n-h,3*n*ones(H-2,W-2),h+W+1];n-w+W+1])

1

C ++, 398 bytes

Compilador usado - GCC 4.9.2 com -std=c++14sinalizador

#include<bits/stdc++.h>
using namespace std;string s;vector<vector<char>> M;int w,h,p,i,j;void F(int x,int y){if(p<s.size()&&(((!y||y==h-1)&&x>=0&&x<w)||((!x||x==w-1)&&y>=0&&y<h))&&!M[y][x])M[y][x]=s[p++],F(x+1,y),F(x,y+1),F(x-1,y),F(x,y-1);}int main(){getline(cin,s);cin>>w>>h;M.resize(h,vector<char>(w,0));F(0,0);while(i<h){j=0;while(j<w){if(!M[i][j])M[i][j]=32;cout<<M[i][j++];}i++;cout<<endl;}}

Teste aqui.

Explicação

#include<bits/stdc++.h>
using namespace std;

string s; // input string
vector<vector<char>> M; // output matrix
int w, h, p, i, j;
// w = width
// h = height
// p = iterator over s
// i, j = iterators used later for printing answer

void F( int x, int y )
{
    // If the coordinates (x, y) are either on the first row/column or the last row/column and are not already populated with the input characters, populate them
    if ( p < s.size() && ( ( ( y == 0 || y == h - 1 ) && x >= 0 && x < w ) || ( ( x == 0 || x == w - 1 ) && y >= 0 && y < h ) ) && !M[y][x] )
    {
        M[y][x] = s[p++];
        F( x + 1, y );
        F( x, y + 1 );
        F( x - 1, y );
        F( x, y - 1 );
    }
}

int main()
{
    getline( cin, s );
    cin >> w >> h;
    // Input taken !!

    M.resize( h, vector<char>( w, 0 ) ); // Fill the matrix with null characters initially

    F( 0, 0 ); // This function does all the work

    // Now printing the matrix
    while ( i < h )
    {
        j = 0;
        while ( j < w )
        {
            if ( !M[i][j] )
            {
                M[i][j] = ' ';  // Replace '\0' with ' '
            }
            cout << M[i][j++];
        }
        i++;
        cout << endl;
    }

}

Não foi possível salvar os caracteres usando char[][]?
corsiKa

Não, vector<vector<char>> M;M.resize(h,vector<char>(w,0));é um pouco menor quechar** M;M=new char*[h];while(i<h)M[i++]=new char[w]();
Anmol Singh Jaggi 14/03

1

Perl, 193 195 bytes

($s,$w,$h,$i,$y)=(@ARGV,0,2);
$o.=substr$s,$i,$w;
$i+=$w;
$o.=sprintf"\n%s%*s",substr($s,2*($w+$h)-$y++-3,1)||' ',$w-1,substr($s,$i++,1)while$y<$h;
print$o."\n".reverse(substr($s,$i,$w))."\n";

Tenho certeza que isso pode ser bastante melhorado. Eu sou um noob. >, <


0

Java 11, 180 bytes

(s,w,h)->{var r=s.substring(0,w)+"\n";int i=w;for(var S=s.split("");i<w+h-2;)r+=S[3*w+2*h-i-5]+" ".repeat(w-2)+S[i++]+"\n";return r+new StringBuffer(s.substring(i,i+w)).reverse();}

Experimente on-line (NOTA: String.repeat(int)é emulado como repeat(String,int)para a mesma contagem de bytes, porque o Java 11 ainda não está no TIO.)

Explicação:

(s,w,h)->{               // Method with String & 2 int parameters and String return-type
  var r=s.substring(0,w)+"\n";
                         //  Result-String, starting at the the first row of output,
                         //  which is a substring in the range [0, `w`)
  int i=w;               //  Index-integer, starting at `w`
  for(var S=s.split(""); //  Split the input-String into a String-array of characters
      i<w+h-2;)          //  Loop `i` in the range [`w`, `w+h-2`)
    r+=                  //   Append the result-String with:
       S[3*w+2*h-i-5]    //    The character at index `2*w+2*h-4 - i+w-1`
       +" ".repeat(w-2)  //    Then append `w-2` amount of spaces
       +S[i++]           //    Then append the character at index `i`
       +"\n";            //    And a trailing new-line
  return r               //  After the loop, return `r` as result
         +new StringBuffer(s.substring(i,i+w)).reverse();
                         //  Appended with the last row of output,
                         //  which is a substring in the range [`i`, `i+w`) reversed

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.