Los personajes de la cadena dan vueltas y vueltas

23

(Inspirado en un primer borrador del desafío de línea fractal de PhiNotPi ).

Te dan un ancho W > 1, una altura H > 1y una cadena que consiste en 2(W+H-2)caracteres ASCII imprimibles. La tarea es imprimir esta cadena envuelta alrededor de un rectángulo del ancho y alto dados, comenzando en la esquina superior izquierda, en sentido horario. El interior del rectángulo está lleno de espacios. Con suerte, los casos de prueba deberían dejar esto muy claro.

Puede escribir un programa o función, tomando la entrada a través de STDIN (o la alternativa más cercana), argumento de línea de comando o argumento de función, e imprimiendo el resultado en STDOUT (o la alternativa más cercana) o devolviéndolo como una cadena.

No debe haber espacios iniciales o finales (aparte de los que podrían estar en la cadena de entrada). Opcionalmente, puede generar una nueva línea final.

Este es el código de golf, por lo que gana el envío más corto (en bytes).

Casos de prueba

Cada caso de prueba es "String" W Hseguido por la salida 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

Tablas de clasificación

Aquí hay un fragmento de pila para generar una tabla de clasificación regular y una descripción general de los ganadores por idioma.

Para asegurarse de que su respuesta se muestre, comience con un título, usando la siguiente plantilla de Markdown:

# Language Name, N bytes

¿Dónde Nestá el tamaño de su envío? Si mejora su puntaje, puede mantener los puntajes antiguos en el título, tachándolos. Por ejemplo:

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

Martin Ender
fuente
8
Tus tablas de clasificación son geniales.
Alex A.
2
¿Jugaste al golf en tu tabla de clasificación?
mbomb007
2
@ mbomb007 No, ejecuté el código a través de minificadores, por lo que no ocuparía mucho espacio cuando se expande. (Supongo que eliminar saltos de línea habría sido suficiente). Todavía tengo una versión no minificada en mi disco duro.
Martin Ender
2
Si cambiaste el nombre a "The Chars in the String Go Round and Round", se ajusta mejor al ritmo de la canción.
Justin

Respuestas:

9

CJam, 27 bytes

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

Realmente no soy CJam, pero creo que esto supera a Martin. La principal diferencia es que empujamos una nueva línea antes de leer la entrada e imprimimos la primera línea inmediatamente, negando la necesidad de almacenar la altura.

Toma entrada en el orden

H "String" W

Pruébalo en línea.

Sp3000
fuente
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 la primera línea, luego las dos líneas verticales, luego la última línea.

Tiene que haber algo más corto que escribir printtres veces, pero todo lo que he intentado hasta ahora con guardar en una variable y '\n'.joinha sido más largo.

xnor
fuente
Puede cambiar a Python 3 y almacenar la impresión en una variable ...
Omar
1
@Omar Eso termina siendo más largo porque tienes que usarlo evalen la entrada y poner entre corchetes las declaraciones de impresión.
FryAmTheEggman
¡Oh, no lo había tenido evalen cuenta! El paréntesis no debería ser un gran problema ya que printen Python 2 necesita un espacio después. Pasar de print blaha p(blah)todavía guarda 3 caracteres.
Omar
9

CJam, 31 30 bytes

Ante la insistencia de Optimizer, aquí está mi propio intento. No soy fanático de ganar mis propios desafíos, así que cuento con la familia APL (o alguien mejor en CJam) para vencer esto. ;)

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

Toma información en el mismo orden que se da en la pregunta:

"Hello, World! " 5 4

Pruébalo aquí.

Un byte guardado gracias a Optimizer.

Explicación

Originalmente, tuve una muy buena idea para comenzar con el rectángulo de espacios y luego, literalmente, envolver la cuerda alrededor de él mientras giraba la cuadrícula completa cuatro veces. Sin embargo, parece que no puedo lograr que funcione en caso de que el ancho o la altura o ambos lo sean 2. Así que probé el enfoque ingenuo (imprimir arriba, bucle sobre los lados, imprimir abajo), y sorprendentemente resultó ser muy corto.

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.";
Martin Ender
fuente
Como podemos obtener la longitud de la cadena y tenemos V, no hay necesidad de guardar H. Simplemente repita el bloque hasta que solo queden V caracteres. l~;:V/(N@s{)V2-S*@(N@_,V-}gW%ahorra 1 char.
DocMax
@DocMax Desafortunadamente, eso no funciona para la altura 2. Sin embargo, es una buena idea, investigaré si puedo usarlo de alguna manera diferente.
Martin Ender
D'oh! Incluso mencionaste el problema H = 2 y todavía olvidé evitarlo.
DocMax
9

Pyth, 47 46 45 40 37 36 bytes

Este es el enfoque obvio implementado en Pyth. Imprime la primera línea indexando 0:widthy luego el medio, luego el final.

Gracias a @Jakube por el consejo con el uso zy Qpor dos entradas y el uso p.

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

Toma la entrada de stdin como una cadena y como una tupla de dimensiones, nueva línea separada:

Hello, World! 
5, 4

y escribe a stdout.

Probar aquí .

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
Maltysen
fuente
Usar zpara leer la cadena ahorra muchos caracteres. También t_Nes lo mismo que -_N1.
Jakube
37 caracteres son posibles con nuestro enfoque.
Jakube
@Jakube gracias por los consejos!
Maltysen
Un ahorro más de carbón. En lugar de ++usar py cambiar el zt_Ncon *d-k2.
Jakube
5

J, 61 bytes

Método:

Comenzando desde un (height-2)*(width-2)bloque de espacios, tomamos la cantidad necesaria de caracteres desde el final de la cadena y la agregamos al bloque actual. Repetimos esto 4 veces. El total de 5 estados ilustrados con el 'Hello, World! ' 5 4ejemplo (espacios reemplazados por Xs para facilitar la lectura):

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

El código:

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

Definición explícita de funciones. La función de dos operandos toma una cadena como argumento izquierdo y una lista de dos enteros como argumento derecho.

Ejemplo de uso:

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

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

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

Pruébelo en línea aquí.

randomra
fuente
Wow, estoy impresionado de que esto funcione para el ancho y la altura 2 en J.
Martin Ender
4

Pyth, 38 37

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

Originalmente tenía una solución 38 diferente, pero era básicamente una solución de golf de la respuesta de Maltysen. Así que decidí ir un poco diferente.

Pruébalo en línea .

              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]
Jakube
fuente
_>z_ttHes equivalente a <_zttH.
isaacg
@isaacg Gracias, ya vi algo similar en la respuesta de Maltysen.
Jakube
4

JavaScript (ES6), 110115

Funciona con 3 parámetros, devolviendo una cadena

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 versión 119 : sin formato corto para funciones, sin parámetros predeterminados. No hay razón para usar, for(of)incluso si es compatible

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 versión 126 : no para (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
}

Sin golf

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

Prueba en la consola 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)))

Salida

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
edc65
fuente
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 el enfoque directo.

Sp3000
fuente
3

Haskell, 164156 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))

La función pno imprime el resultado, pero lo devuelve como una cadena, por ejemplo, p 4 5 "+--+|||+--+|||"-> "+--+\n| |\n| |\n| |\n+--+\n". Para una mejor visualización putStr:

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

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

Cómo funciona: creo un bloque wx hde espacios y reemplazo la primera línea con el comienzo de la cadena de entrada. Luego giro el bloque en sentido antihorario y repito reemplazando la primera línea otras tres veces.

Para evitar volver a cortar el primer carácter después del turno 4, lo agrego a la cadena de entrada antes de comenzar.

"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

Editar: encontró una mejor manera de resolver el problema de cortar el primer carácter después del turno # 4.

nimi
fuente
Ah bueno ... esto es similar a lo que probé en CJam, excepto que funciona. ;)
Martin Ender
3

Postdata, 62 bytes

Por supuesto, esto usa tokens binarios, pero es 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

Aquí hay un hexdump del archivo ( 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

El resultado es realmente pequeño (como resultado de no escalar la fuente en absoluto), por lo que debe acercar un poco para verlo.

Esto aprovecha el xyshowoperador para escribir la cadena utilizando espacios de caracteres personalizados. En este caso, uso el espaciado vertical negativo para escribir, luego el espacio horizontal negativo para escribir hacia atrás, luego el espacio vertical positivo para escribir hacia arriba. Debido a esto, no necesito usar ningún tipo de manipulación de cadenas.

AJMansfield
fuente
3

> <>, 82 80 + 3 = 83 bytes

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

Página de Esolang para> <> (Pescado)

Esto resultó ser más corto de lo que esperaba. Utiliza el enfoque directo de imprimir la primera línea, luego las columnas rellenadas con los espacios centrales, luego la última línea.

Ingrese la cadena a través de STDIN y la altura y el ancho a través de la línea de comando con la -vbandera, así:

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

Explicación

: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)
Sp3000
fuente
2

Bash + coreutils, 124

Un script de shell para comenzar:

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}"

Pase la entrada como argumentos de línea de comando:

$ ./roundnround.sh 5 4 "Hello, World! "
Hello
    ,
!    
dlroW
$ 
Trauma digital
fuente
2

JavaScript, 161 160 158 bytes

El método que se me ocurrió resultó demasiado largo, pero bueno, ha sido una práctica. (Además, lo deletreé 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 una entrada que no tiene sentido, la salida no está definida (literalmente, y muchas veces), pero funciona para todos los casos de prueba.

vvye
fuente
slice es más corto que substr , no es exactamente lo mismo, pero en este caso puede usarlo
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()}

llamada:

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

salida:

rock beats 
          s
s         c
t         i
a         s
e         s
b         o
          r
r         s
epap staeb 
Kamil Mikolajczyk
fuente
2

K 55 54 bytes

Usando el mismo enfoque que la implementación J de randomra; Comience con un bloque de espacios y agregue desde la cola de la cuerda hasta el borde mientras gira cuatro veces:

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

Y algunos ejemplos:

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

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

Desglosándolo un poco para facilitar la lectura,

Generar un bloque NxM:

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

Gire 90 grados usando transpose ( +) y reverse-each ( |:'):

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

Entonces, si tenemos un bloque de espacios ty una cadena s, podemos anteponer una porción de la cola 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 el formulario 4 {[x] ... }/( ... )para aplicar repetidamente una función a una tupla que consiste en la cadena y la matriz que estamos construyendo. Cada vez que hacemos este paso de rotación y concatenación, también cortamos la cadena.

editar:

Otra idea es intentar dividir la cadena de entrada en los fragmentos que queremos en cada rotación, lo que simplifica el cuerpo principal del programa. Desafortunadamente, esto resulta ser un poco más largo a 56 bytes:

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

Si hay una mejor manera de calcular esos puntos divididos, estoy abierto a sugerencias.

edit2:

Reorganizar ligeramente me permite eliminar un par de paréntesis. 54 bytes!

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

K, 80 68 bytes

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

Reducido de 80 gracias 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}

Apenas sé cómo funciona esto.

Ejemplo de uso:

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

Hay algunas optimizaciones posibles, pero sigo haciendo Kona segfault ...

kirbyfan64sos
fuente
Usted puede mejorar esto un poco mediante el uso de 'toma' (diádica #) y una 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 por mi cuenta.
JohnE
@JohnE ¡Gracias! Sabía acerca de la lista de argumentos explícitos, pero de alguna manera se me olvidó; Sin embargo, no tenía idea sobre el número diádico.
kirbyfan64sos
2

R, 178

Esta es una función sin nombre que toma s, w, hcomo parámetros. Desearía que hubiera una mejor manera de dividir la cuerda.

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='')}

Sin golf

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

Prueba de funcionamiento

> (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
> 
MickyT
fuente
2

T-SQL, 307

Aunque todavía es terriblemente largo, resultó ser bastante más fácil (y más corto) de lo que pensaba en una consulta. Implementado como una función con valores de tabla en línea 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

Esto se repite a través de la cadena @h veces. La primera recursión recorta @ W caracteres de la cadena. Las recursiones medias toman el último y el primero de la cadena restante con relleno de cadena entre ellas. La última recursión invierte lo que queda. Hay algunos caracteres perdidos relacionados con la forma en que SQL Server trata los espacios finales en VARCHARS.

Prueba de funcionamiento

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)
MickyT
fuente
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])
knedlsepp
fuente
1

C ++, 398 bytes

Compilador utilizado - GCC 4.9.2 con -std=c++14bandera

#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;}}

Pruébalo aquí.

Explicación

#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;
    }

}
Anmol Singh Jaggi
fuente
¿No podrías guardar los personajes usando en su char[][]lugar?
corsiKa
No, vector<vector<char>> M;M.resize(h,vector<char>(w,0));es un poco más corto quechar** M;M=new char*[h];while(i<h)M[i++]=new char[w]();
Anmol Singh Jaggi
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";

Estoy seguro de que esto se puede mejorar mucho. Soy un novato. >, <

Stephen Menton
fuente
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();}

Pruébelo en línea (NOTA: String.repeat(int)se emula repeat(String,int)para el mismo recuento de bytes, porque Java 11 aún no está en TIO).

Explicación:

(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
Kevin Cruijssen
fuente