Rectángulo de texto

13

Su programa recibe un texto como entrada, de al menos 8 caracteres de longitud, y siempre con un número par de caracteres. (no es necesario evaluar la corrección de la entrada).

Su objetivo es mostrar ese texto como un rectángulo. Por ejemplo, dado HelloWorldcomo entrada, mostrar

Hell
d  o
lroW

Reglas:

  • El texto gira en sentido horario (posición de inicio como desee)
  • Formará un rectángulo cerrado, lados de 1 carácter de ancho.
  • El rectángulo tendrá que abarcar la mayor parte del interior. (solo para descartar la respuesta trivial de mostrar el texto en dos líneas)
  • No se imprimen otros caracteres además del texto en sí y los espacios de relleno y los saltos de línea necesarios.

Como código de golf, gana el código más corto.

El ganador se selecciona a más tardar 10 días después de la primera respuesta válida.

vsz
fuente

Respuestas:

5

GolfScript, 56 53 40 38 caracteres

1/..,4/):l<n@l>{)" "l*2>@(n@.,l-}do-1%

Puede probar el guión en línea .

Howard
fuente
7

PostScript 50 binario, 113 ASCII

Esto usa salida gráfica. Hexdump del programa utilizando tokens binarios:

$ hexdump -C textRect_binary.ps 
00000000  74 5b 30 20 39 5b 74 92  62 34 92 36 92 38 92 10  |t[0 9[t.b4.6.8..|
00000010  32 92 19 5d 7b 92 2c 7b  32 92 19 7d 92 83 92 3e  |2..]{.,{2..}...>|
00000020  92 6e 7d 92 49 5d 39 20  39 92 6b 91 c7 39 92 8e  |.n}.I]9 9.k..9..|
00000030  92 c3                                             |..|
00000032

Descargar para probarlo . Usando Ghostscript, el texto a ser procesado se puede pasar al programa de la siguiente manera:

gs -st=helloworld textRect_binary.ps 

La salida gráfica se ve así:

salida procesada

El mismo código que usa tokens ASCII se ve así:

t[0 9[t length
4 div dup
ceiling
2 copy]{cvi{2 copy}repeat
exch neg}forall]9 9 moveto/Courier 9 selectfont
xyshow

La estrategia es usar xyshowpara definir dónde nos movemos después de mostrar cada personaje antes de mostrar el siguiente personaje. Comenzamos en la esquina inferior izquierda, moviéndonos en el sentido de las agujas del reloj, es decir, primero hacia arriba, luego hacia la derecha, luego hacia abajo y luego a la izquierda. Siempre estamos moviendo 9 unidades, así que primero tenemos un movimiento relativo de 0 9, luego 9 0, luego 0 -9, luego -9 0. Podemos pasar de un par de estos números al siguiente con la secuencia exch neg.

Necesitamos construir una matriz para xyshowque contenga estos pares de números, un par para cada personaje. Esto significa que si tenemos helloworldcomo ejemplo una cadena, que tiene 10 caracteres, queremos subir dos veces, luego tres veces a la derecha, luego dos veces hacia abajo y tres veces a la izquierda. Obtenemos estos valores (dos y tres) dividiendo la longitud de la cuerda entre 8, una vez redondeando al piso, una vez al techo.

Entonces, copiamos 0 9dos veces, luego cambiamos a las coordenadas relativas x / y usando exch neg, copiamos esas tres veces y así sucesivamente.

Este código comentado muestra lo que sucede en la pila:

t[0 9                % t [ 0 9
[t length            % t [ 0 9 [ length
4 div dup            % t [ 0 9 [ length/4 length/4
ceiling              % t [ 0 9 [ length/4=height width
2 copy]              % t [ 0 9 [height width height width]
{%forall             % t [ 0 9 ... x y height_or_width
  cvi                % t [ 0 9 ... x y height_or_width_integer
  {2 copy}           % t [ 0 9 ... x y height_or_width_integer {2 copy}
  repeat             % t [ 0 9 ... x y .. x y
  exch neg           % t [ 0 9 ... x y .. y -x
}forall]             % t [0 9 ... -9 0]
9 9 moveto/Courier 9 selectfont
xyshow
Thomas W.
fuente
+1 sagrado bajeezus. Soy seriamente deficiente en mi conocimiento del nivel 2 y más allá.
luser droog
Quieres decir xyshow? Feliz de presentarte esta, hace un tiempo me conociste kshow, de lo cual no estaba muy consciente ;-).
Thomas W.
@luserdroog: Por cierto: estoy bastante orgulloso de que la entrada actual de GolfScript tenga más del 10% más de caracteres que mi entrada binaria, pero me molesta que mi versión ASCII esté a un personaje de un sorteo con Ruby (en realidad, incluso tres, porque el código Ruby podría jugarse más). ¿Tienes alguna idea para una mayor optimización?
Thomas W.
@ThomasW. Ahora mi entrada de GolfScript es un 24% más corta que su binario ;-) Y todavía creo que todavía existe la posibilidad de acortarlo aún más en uno o dos caracteres.
Howard
@Howard: ¡Argh! ¿Alguien puede vencer a GolfScript?
Thomas W.
7

Ruby 112 100

Soy nuevo en Ruby y este es mi primer código de golf. Me basé en la implementación perl de memowe e intenté hacer una versión de Ruby. Esto es 112 100 caracteres y supone que asigna una cadena a x. Espero ver a los demás.

l=x.size
puts x[0..w=l/2-h=l/4]
1.upto(h-1){|i|puts x[-i]+' '*(w-1)+x[w+i]}
puts x[w+h..l-h].reverse

Editado para implementar sugerencias. Creo que ahora son 100 caracteres. ¡Gracias chicos!

jzig
fuente
¡Agradable! Puede guardar dos caracteres en la quinta línea (eliminar espacios).
Thomas W.
Me gusta. Gracias. Parece bueno que se pueda acceder a las cadenas de Ruby como una matriz, tuve que construir una sola. :)
memowe
Podría reemplazar x.lengthcon x.size(Guarda 2 caracteres)
knut
1
Y 8 más usando puts x[0..w=l/2-h=l/4].
Howard
5

Perl (124 118 109 + 3 = 112)

Esto anteriormente era bastante sencillo. Se contaron todas las opciones de línea de comando como 1 carácter cada una.

-nlE
$w=(@s=split//)/2-($h=int@s/4);say@s[0..$w--];say$s[1-$_].$"x$w.$s[$w+$_]for+2..$h;say+reverse@s[@s/2..@s-$h]

Ejemplo:

$ perl -nlE '$w=(@s=split//)/2-($h=int@s/4);say@s[0..$w--];say$s[1-$_].$"x$w.$s[$w+$_]for+2..$h;say+reverse@s[@s/2..@s-$h]'
abcdefghijklmnopqrstuvwxyz
abcdefgh
z      i
y      j
x      k
w      l
v      m
utsrqpon
memowe
fuente
Esto se puede compactar: ​​(1) (@s-$h*2)/2 == @s/2-$h(2) $wse puede representar como $w=(@s=split//)/2-($h=int@s/4);, ahorrando dos puntos
amon
Se actualizó el código.
memowe
Otras cosas interesantes: (1) el espacio es el valor predeterminado de la interpolación de matriz var $"–saves 1 char. (2) - $w+$h == @s/2ahorra 1 char. (3) Si $wes más pequeño por uno, podemos simplificar $"x($w-1). Para esto, $_se debe aumentar en 1. Se guarda como 3 caracteres. (4) El punto y coma final es überflüssig, ahorra 1 char. Esto lleva al fragmento de código say@s[0..$w--];say$s[1-$_].$"x$w.$s[$w+$_]for+2..$h;say+reverse@s[@s/2..@s-$h](con algunos +por diversión, por lo que no queda un solo espacio).
amon
Excelente golfificación, @amon, ¿lo editarías en mi publicación, por favor? De esa manera el mundo puede ver quién lo hizo. :)
memowe
5

Brainfuck - 194 187

+>,[>+[>+<-],]
>-->++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>[-]>[-]>[<<+<<+>>>>-]<<<<
[[<]>+[>]<-]<[<]>-
[>.[-]<[>+<-]>-]>[>]
++++++++++.<.[-]
>[>+++>>+<<<-]>++>--[<.>-]<<<<[<]>.[-]>[>]>>>>.
<<<<<[.<]
captncraig
fuente
Buen intento, pero no funciona. El resultado final es en la dirección incorrecta, contrario a la regla 1, y solo tiene una altura fija, contrario a la regla 3.
vsz
No estoy seguro de por qué volteé la última fila. Lo tenía totalmente en mente de la manera correcta mientras lo escribía. La solución realmente guarda 7 comandos. Hice caso omiso de la altura fija, pero no es el caso trivial de 2 líneas del que hablaste. Tal vez lo mejoraré en el futuro.
captncraig
4

Mathematica 156 199 344

Editar : esta es una reescritura importante del código anterior. Funciona esencialmente igual, pero ahora toma como entrada una cadena de longitud <120 caracteres y automáticamente dimensiona el cuadrado.

Todavía podría jugarse un poco, pero no se reducirá al tamaño de las versiones anteriores y con errores.

f@s_ := ({a, t, w, q} = {Automatic, Text, Quotient[StringLength@s, 2],
 Quotient[StringLength[s], 4] + 1};z = StringSplit[StringInsert[s <> ConstantArray[" ", 0],
 "*", {q, 2 q, 3 q}], "*"];
Graphics[{t[z[[1]], {0, q}],t[z[[2]], {q, 0}, a, {0, -1}],t[z[[3]], {0, -q}, a, {-1, 0}],
t[z[[4]], {-q, 0}, a, {0, 1}]},ImageSize -> 500,BaseStyle -> {FontFamily -> "Courier", 21},
PlotRange -> 34,ImagePadding -> 22])

Ejemplos

f["Hello Code Golf World!"]
f["January, February, March,April, May, June, July"]
f["This text is normal, this goes downwards,this is upside-down, and this is upwards"]

pic1

pic2

pic3

DavidC
fuente
Oye, ¿una serie de cuerdas? Eso realmente está doblando las reglas, ¿no?
Thomas W.
@ThomasW. Los comentarios en la respuesta indican que no es una solución final.
kojiro
¡Ah, ya veo! Me pregunto si debería aceptar el desafío e intentar algo similar en PostScript ...
Thomas W.
¡Me gusta cómo se ve ahora!
Thomas W.
@ Thomas W. Gracias. Hacer que el formato se vea bien para una amplia gama de longitudes de cadena cuesta muchos bytes.
DavidC
2

Perl + expresiones regulares: 104 (101 + 3)

(código de conteo + interruptores)

Aquí hay una solución con buenas expresiones regulares y un poco de Perl:

perl -plE'$w=($l=length)/2-($h=int$l/4);s/..{$w}\K.*/"\n".reverse$&/e;$"x=--$w;s/.\K(.*)(.)$/$"$2\n$1/while--$h'

Esto solo funcionará correctamente en una línea de entrada.

Inspirado por memowe, pero esencialmente sin ninguna matriz.

amon
fuente
Perdón por la pregunta tonta: ¿Cómo puedo probar esto? Estoy pegando su código en la línea de comando, luego escribo algo, presiono enter y sale algo. Pero no es una caja. ¿Qué estoy haciendo mal?
Thomas W.
@ThomasW. Parece funcionar para mí, para un número par arbitrario de caracteres. El código anterior está garantizado para funcionar con bash y perl versión 5.12+. La entrada se acepta a través de STDIN, y solo la primera línea se procesa correctamente. No sé cómo citar el código correctamente para cmd.exe.
amon
1
Ah, probablemente fue mi error. Probablemente usé una cadena de longitud impar. Esto funciona:echo thisworksgreat | perl -plE'$w=($l=length)/2-($h=int$l/4);s/..{$w}\K.*/"\n".reverse$&/e;$"x=--$w;s/.\K(.*)(.)$/$"$2\n$1/while--$h'
Thomas W.
2

PostScript (106)

Esto está inspirado en la solución Mathematica de dude .

0{= =
4 add dup
t length mod 4
lt{-90 rotate}if}0[0 3 -3 0 9 9]concat
0 moveto/Courier 5 selectfont
t kshow

Con Ghostscript llama a esto como

gs -st=hello! boxtext.ps

Produce resultados como.

Hello_Code_Golf_World!

Enero Febrero Marzo Abril Mayo junio Julio

Se usa kshowpara mostrar los glifos uno por uno. Después de que se hayan mostrado suficientes glifos para un lado, todo se gira -90 grados antes de continuar con los glifos restantes.

Para saber cuándo se han mostrado suficientes glifos en el lateral, incrementamos un contador en 4 cada vez que se muestra un glifo. Si el valor del contador módulo la longitud de la cadena es menor que 4, entonces sabemos que tenemos que rotar:

char  counter  mod 6  compared to 4
 h       4       4          =
 e       8       2          <   => rotate
 l      12       0          <   => rotate
 l      16       4          =
 o      20       2          <   => rotate
 !      24       0          <   => rotate

ingrese la descripción de la imagen aquí

Código fuente comentado y sin golf:

0                      % n
{%kshow                % n char1 char2
  = =                  % n
  4 add dup            % n' n'
  t length mod         % n' (n' mod t_length)
  4 lt                 % n' bool
  {-90 rotate}if       % n'
}                      % n kshowProc
% First 0 for moveto. We add it here to take 
% advantage of the surrounding self delimiting tokens.
0                      % n kshowProc 0
% We change the graphics state so that the drawn
% text is at a nice size and not off screen.
[0 3 -3 0 9 9]concat   % n kshowProc 0
0                      % n kshowProc 0 0
moveto                 % n kshowProc
/Courier 5 selectfont  % n kshowProc
t                      % n kshowProc text
kshow                  % n
Thomas W.
fuente
1

Python 2.x: 137

Soy nuevo en el código de golf y estoy bastante seguro de que esto se puede mejorar ...

def s(t):c=len(t);w=1+c/4;h=(c-w-w)/2;u=w+h;n='\n';print t[:w]+n+n.join(map(((w-2)*' ').join,zip(t[:w+u-1:-1],t[w:u])))+n+t[w+u-1:u-1:-1]

Código de prueba visual:

from itertools import chain
from string import letters
for i in range(8,101,2):
    t = ''.join(chain(letters))[:i]
    print '%d: %s' % (i, t)
    s(t)
    print '-----'

Algo de interés: esta solución depende de la matemática entera. Si solo hace los cálculos simbólicamente, lo encontrará h=(c-w-w)/2 => h=w-2, pero si sustituye ese resultado, a cualquier otro resultado le faltarán dos caracteres en la esquina inferior izquierda.

kojiro
fuente
1

K, 84

{-1'(*r;((|r 3),\:(w-2)#" "),'r 1;|(r:(0,+\(w;h;w;h:_(l-2*w:-_-(1+(l:#x)%4))%2))_x)2);}

.

k){-1'(*r;((|r 3),\:(w-2)#" "),'r 1;|(r:(0,+\(w;h;w;h:_(l-2*w:-_-(1+(l:#x)%4))%2))_x)2);}"HelloWorld"
Hell
d  o
lroW

k){-1'(*r;((|r 3),\:(w-2)#" "),'r 1;|(r:(0,+\(w;h;w;h:_(l-2*w:-_-(1+(l:#x)%4))%2))_x)2);}"Hellooooooooooooooo Worlddddd!"
Hellooooo
!       o
d       o
d       o
d       o
d       o
d       o
lroW oooo
tmartin
fuente
1

Scala (135)

El siguiente fragmento supone que xcontiene la cadena para formatear, y debe pegarse en el REPL de scala:

val (h,w)=((x.size+3)/4,println(_:Any));val s=x.grouped(h)toSeq;w(s(0));for((l,r)<-s(1)zip(s(3)reverse))w(r+" "*(h-2)+l);w(s(2)reverse)

Si no tiene instalado Scala, puede verificarlo rápidamente utilizando este intérprete de Scala en línea: http://www.simplyscala.com/ . Simplemente pegue el siguiente texto y presione evaluar:

val x="HelloWorld"
val (h,w)=((x.size+3)/4,println(_:Any));val s=x.grouped(h)toSeq;w(s(0));for((l,r)<-s(1)zip(s(3)reverse))w(r+" "*(h-2)+l);w(s(2)reverse)
Régis Jean-Gilles
fuente
1

Pitón 3 (120)

s=input()
n=len(s)
h=n//4
q=(n+2)//4-1
p=print
p(s[:q+2])
for i in range(1,h):p(s[n-i]+' '*q+s[q+1+i])
p(s[n-h:q+h:-1])

Prueba

entrada:

abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz

salida:

abcdefghijklmn
z            o
y            p
x            q
w            r
v            s
u            t
t            u
s            v
r            w
q            x
p            y
o            z
nmlkjihgfedcba
Rayo
fuente
0

PHP (149)

El texto a imprimir debe estar en una variable llamada $x.

@$s=substr;echo$s($x,-$w=($l=strlen($x)/2)-$h=$i=$l-2>>1).'
';while($i--)echo$x[$l+$i].str_repeat(' ',$w-2).$x[$h-$i-1].'
';echo$s(strrev($x),$l,$w);
Jonathan
fuente
0

Python2.7 (99)

t=''.join(raw_input().split())
u=len(t)/2-1
print t[:u]+"\n"+t[-1]+" "*(u-2)+t[u]+"\n"+t[-2:u:-1]

Editar: aparentemente viola la regla de abarcar el área máxima dentro.

sidi
fuente
0

JAVA - 320

public class A{
public static void main(String[] a){
String s=a[0];
int l=s.length(),h=l/2,f=h-1,i=0;       
for(i=0;i<f;i++)
System.out.print(s.charAt(i));
System.out.print("\n"+s.charAt(l-1));
for(i=0;i<f-2;i++)
System.out.print(" ");
System.out.println(s.charAt(h-1));
for(i=l-2;i>h-1;i--)
System.out.print(s.charAt(i));}}

Nota: - La entrada se toma de la línea de comando

Entrada: - HelloWorld

Salida: -

Hell
d  o
lroW

Entrada: - abcdefghijklmnopqrstuvwxyz

Salida: -

abcdefghijkl
z          m
yxwvutsrqpon
Vivekanand SV
fuente
Lea las reglas con más cuidado, especialmente nr. 3.
vsz