Retângulo de texto

13

Seu programa obtém um texto como entrada, com pelo menos 8 caracteres e sempre consistindo em um número par de caracteres. (não é necessário avaliar a correção da entrada).

Seu objetivo é exibir esse texto como um retângulo. Por exemplo, dado HelloWorldcomo uma entrada, exiba

Hell
d  o
lroW

Regras:

  • O texto gira no sentido horário (posição inicial como você quiser)
  • Ele formará um retângulo fechado, com 1 caractere de largura.
  • O retângulo terá que abranger a maior área dentro. (apenas para descartar a resposta trivial de exibir o texto em duas linhas)
  • Nenhum outro caractere é impresso além do próprio texto e dos espaços de preenchimento e alimentação de linha necessários.

Como código-golfe, o código mais curto vence.

O vencedor é selecionado não antes de 10 dias após a primeira resposta válida.

vsz
fonte

Respostas:

5

GolfScript, 56 53 40 38 caracteres

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

Você pode testar o script online .

Howard
fonte
7

PostScript 50 binário, 113 ASCII

Isso usa saída gráfica. Hexdump do programa usando tokens binários:

$ 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

Baixe para experimentar . Usando o Ghostscript, o texto a ser renderizado pode ser passado para o programa da seguinte maneira:

gs -st=helloworld textRect_binary.ps 

A saída gráfica é assim:

saída renderizada

O mesmo código usando tokens ASCII se parece com o seguinte:

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

A estratégia é usar xyshowpara definir para onde nos movemos depois de mostrar cada personagem antes de mostrar o próximo caractere. Estamos começando no canto inferior esquerdo, movendo no sentido horário, ou seja, primeiro para cima, depois para a direita, depois para baixo e para a esquerda. Estamos sempre movendo 9 unidades, então primeiro temos um movimento relativo de 0 9, então 9 0, então 0 -9, então -9 0. Podemos passar de um par desses números para o próximo com a sequência exch neg.

Precisamos construir uma matriz para xyshowque contenha esses pares de números, um par para cada caractere. Isso significa que, se tivermos helloworldcomo exemplo uma string, com 10 caracteres, queremos subir duas vezes, depois três vezes para a direita, depois duas vezes para baixo e esquerda três vezes. Obtemos esses valores (dois e três) dividindo o comprimento da corda por 8, uma vez arredondando para o chão e outra para o teto.

Então, copiamos 0 9duas vezes, depois alternamos para as coordenadas x / y relativas exch neg, copiamos essas três vezes e assim por diante.

Este código comentado mostra o que acontece na pilha:

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.
fonte
+1 bajeezus sagrados. Sou seriamente deficiente em meu conhecimento do nível 2 e além.
Luser droog
Você quer dizer xyshow? É um prazer apresentar-lhe este - há algum tempo você me apresentou kshow, do qual eu não sabia ;-).
Thomas W.
@luserdroog: BTW: Estou bastante orgulhoso de que a entrada atual do GolfScript tenha mais de 10% mais caracteres do que a minha entrada binária, mas me incomoda que minha versão ASCII esteja a um caractere de um empate com Ruby (na verdade, até três, porque o código Ruby pode ser jogado ainda mais). Você tem alguma idéia para mais otimização?
Thomas W.
@ThomasW. Agora minha entrada no GolfScript é 24% menor que o seu binário ;-) E ainda acho que ainda há a chance de encurtá-la ainda mais em um ou dois caracteres.
Howard
@ Howard: Argh !!! Alguém pode vencer o GolfScript?
Thomas W.
7

Ruby 112 100

Eu sou novo em Ruby e este é o meu primeiro código de golfe. Eu me baseiei na implementação perl do memowe e tentei fazer uma versão Ruby dela. São 112 100 caracteres e assume que você atribui uma sequência a x. Ansioso para ver os outros.

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 sugestões. Eu acho que são 100 caracteres agora. Obrigado rapazes!

jzig
fonte
Agradável! Você pode salvar dois caracteres na 5ª linha (remover espaços).
Thomas W.
Eu gosto disso. Obrigado. Parece bom que as seqüências de Ruby possam ser acessadas como uma matriz, eu tive que construir uma sozinha. :)
memowe
Você poderia substituir x.lengthcom x.size(Salva 2 caracteres)
Knut
1
E mais 8 usando puts x[0..w=l/2-h=l/4].
Howard
5

Perl (124 118 109 + 3 = 112)

Isso antigamente era bem direto. Contou todas as opções de linha de comando como 1 caractere cada.

-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]

Exemplo:

$ 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
fonte
Isto pode ser compactada: (1) (@s-$h*2)/2 == @s/2-$h(2) $wpode ser representada como $w=(@s=split//)/2-($h=int@s/4);, poupando, assim, duas vírgulas
amon
Atualizado o código.
memowe
Outras coisas interessantes: (1) o espaço é o valor padrão da interpolação da matriz var $"–saves 1 char. (2) - $w+$h == @s/2economiza 1 caractere. (3) Se $wfor menor por um, podemos simplificar $"x($w-1). Para isso, o valor $_deve ser aumentado em 1. Salva como 3 caracteres. (4) O ponto e vírgula final é überflüssig, economiza 1 caractere. Isso leva ao 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](com alguns +por diversão, então não resta um único espaço).
amon
Excelente golfificação, @amon, você poderia editá-la no meu post, por favor? Dessa forma, o mundo pode ver quem fez isso. :)
memowe
5

Brainfuck - 194 187

+>,[>+[>+<-],]
>-->++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>[-]>[-]>[<<+<<+>>>>-]<<<<
[[<]>+[>]<-]<[<]>-
[>.[-]<[>+<-]>-]>[>]
++++++++++.<.[-]
>[>+++>>+<<<-]>++>--[<.>-]<<<<[<]>.[-]>[>]>>>>.
<<<<<[.<]
captncraig
fonte
Boa tentativa, mas não funciona. A linha inferior está na direção errada, contrária à regra 1, e só tem uma altura fixa, contrária à regra 3.
vsz
Não sei por que eu virei a última linha. Eu tinha tudo em mente da maneira correta enquanto escrevia. A correção realmente salva 7 comandos. Eu resolvi a questão da altura fixa, mas não é o caso trivial de 2 linhas que você falou. Talvez eu melhore no futuro.
Captncraig
4

Mathematica 156 199 344

Edit : Esta é uma grande reescrita do código anterior. Funciona essencialmente da mesma forma, mas agora recebe como entrada uma string de comprimento <120 caracteres e dimensiona automaticamente o quadrado.

Ainda poderia ser um pouco jogado, mas não chegará ao tamanho das versões anteriores e mais complicadas.

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])

Exemplos

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
fonte
Ei, uma variedade de cordas? Isso está realmente distorcendo as regras, não é?
Thomas W.
@ThomasW. Os comentários na resposta indicam que não é uma solução final.
Kojiro
Ah entendi! Maravilha se eu deveria aceitar o desafio e tentar algo semelhante em PostScript ...
Thomas W.
Eu gosto da aparência agora!
Thomas W.
@ Thomas W. Obrigado. Obter o formato correto para uma ampla variedade de comprimentos de string custa muitos bytes.
DavidC
2

Perl + Regexes: 104 (101 + 3)

(código de contagem + comutadores)

Aqui está uma solução usando bons Regexes e um pouco 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'

Isso funcionará apenas corretamente em uma linha de entrada.

Inspirado por memowe, mas essencialmente sem matrizes.

amon
fonte
Desculpem a pergunta idiota: Como posso tentar isso? Estou colando seu código na linha de comando, digite algo, pressione enter e algo sai. Mas não é uma caixa. O que estou fazendo de errado?
21413 Thomas Thomas
@ThomasW. Parece funcionar para mim, para um número par e arbitrário de caracteres. É garantido que o código acima funcione na versão 5.12+ do bash e perl. A entrada é aceita via STDIN e apenas a primeira linha é processada corretamente. Não sei como citar o código corretamente para o cmd.exe.
amon
1
Ah, provavelmente foi meu erro. Eu provavelmente usei uma corda de comprimento estranho. Isso 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)

Isso é inspirado na solução Mathematica do cara .

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

Com o Ghostscript, chame isso como

gs -st=hello! boxtext.ps

Produz saída como.

Hello_Code_Golf_World!

Janeiro fevereiro Março Abril Maio Junho Julho

Ele usa kshowpara mostrar os glifos um por um. Depois de mostrar glifos suficientes para um lado, tudo é girado em -90 graus antes de continuar com os glifos restantes.

Para saber quando glifos suficientes foram mostrados ao lado, incrementamos um contador em 4 cada vez que um glifo é mostrado. Se o valor do contador modulo o comprimento da string for menor que 4, sabemos que precisamos rotacionar:

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

insira a descrição da imagem aqui

Código fonte comentado e sem golfe:

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.
fonte
1

Python 2.x: 137

Eu sou novo em codificar golfe e tenho certeza de que isso pode ser melhorado…

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 teste 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 interessante: Esta solução depende da matemática inteira. Se você fizer as contas simbolicamente, descobrirá isso h=(c-w-w)/2 => h=w-2, mas se você substituir esse resultado, todos os outros resultados perderão dois caracteres inferior esquerdo.

kojiro
fonte
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
fonte
1

Scala (135)

O seguinte trecho assume que xcontém a cadeia de caracteres a ser formatada e deve ser colado no scala REPL:

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)

Se você não tem o scala instalado, pode verificar rapidamente usando este interpretador online do Scala: http://www.simplyscala.com/ . Basta colar o seguinte texto e pressionar a tecla avaliar:

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
fonte
1

Python 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])

Teste

entrada:

abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz

resultado:

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
Raio
fonte
0

PHP (149)

O texto a ser impresso deve estar em uma variável chamada $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
fonte
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]

Edit: Aparentemente, viola a regra de abranger a área máxima dentro.

sidi
fonte
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: - A entrada é retirada da linha de comando

Entrada: - HelloWorld

Resultado : -

Hell
d  o
lroW

Entrada: - abcdefghijklmnopqrstuvwxyz

Resultado : -

abcdefghijkl
z          m
yxwvutsrqpon
Vivekanand SV
fonte
Por favor, leia as regras com mais cuidado, especialmente o nº. 3.
vsz 24/01