文字矩形


13

您的程序将文本作为输入,至少8个字符长,并且始终由偶数个字符组成。(无需评估输入的正确性)。

您的目标是将该文本显示为矩形。例如,HelloWorld作为输入,显示

Hell
d  o
lroW

规则:

  • 文本顺时针旋转(根据需要开始位置)
  • 它将形成一个闭合的矩形,边长1个字符。
  • 矩形必须包含内部的大部分区域。(只是为了排除以两行显示文本的简单答案)
  • 除文本本身以及必要的填充空格和换行符外,没有其他字符被打印。

作为代码高尔夫球,最短的代码获胜。

在第一个有效答案出现后的10天内选择获胜者。

Answers:


5

GolfScript,56 53 40 38个字符

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

您可以在线测试脚本。


7

PostScript 50二进制,113 ASCII

这使用图形输出。使用二进制令牌对程序进行十六进制转储:

$ 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

下载尝试一下。使用Ghostscript,可以按以下方式将要渲染的文本传递给程序:

gs -st=helloworld textRect_binary.ps 

图形输出如下所示:

渲染输出

使用ASCII令牌的相同代码如下所示:

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

该策略xyshow用于定义在显示每个字符之后再显示下一个字符之前我们要移动的位置。我们从左下角开始,顺时针方向移动,即先向上,然后向右,然后向下然后向左。我们总是移动9个单位,因此首先我们有一个相对移动0 9,然后是9 0,然后是0 -9,然后是-9 0。我们可以从这些数字中的一对到序列中的下一个exch neg

我们需要构建一个数组来xyshow容纳这些数字对,每个字符一对。这意味着,如果我们有helloworld一个包含10个字符的字符串作为示例,我们想向上两次,然后向右三次,然后向下两次,向左三次。通过将字符串长度除以8(一次舍入到地板,一次舍入到天花板),可以得到这些值(两个和三个)。

因此,我们复制0 9两次,然后使用切换到相对x / y坐标exch neg,复制三次,依此类推。

这段注释后的代码显示了堆栈上发生的情况:

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

+1神圣的巴耶祖斯。我严重缺乏2级及更高水平的知识。
luser droog

你的意思是xyshow?很高兴向您介绍这一点-不久前您向我介绍了kshow,我当时并不了解;-)。
Thomas W.

@luserdroog:顺便说一句:我很自豪当前的GolfScript条目比我的二进制条目多10%以上的字符,但是令我感到困惑的是,我的ASCII版本与使用Ruby绘制的字符相距一个字符(实际上,甚至三个字符,因为Ruby代码可能会更进一步)。您有进一步优化的想法吗?
Thomas W.

@ThomasW。现在,我的GolfScript条目比您的二进制文件短24%;-)我仍然认为仍然有机会将其进一步缩短一两个字符。
霍华德

@霍华德:啊!有人能打败GolfScript吗?
Thomas W.

7

红宝石112 100

我是Ruby的新手,这是我的第一个代码高尔夫。我借鉴了memowe的perl实现,并尝试制作它的Ruby版本。这是112 100个字符,并假定您为x分配了一个字符串。期待与他人见面。

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

编辑以实施建议。我认为现在是100个字符。谢谢你们!


真好!您可以在第5行中保存两个字符(删除空格)。
Thomas W.

我喜欢。谢谢。可以像数组一样访问Ruby字符串看起来不错,我必须自己构建一个。:)
memowe

您可以替换x.lengthx.size(保存2个字符)
knut

1
还有8个正在使用puts x[0..w=l/2-h=l/4]
霍华德

5

Perl(124 118 109 + 3 = 112)

以前这很简单。将所有命令行选项均视为1个字符。

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

例:

$ 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

可以将其压缩:(1)(@s-$h*2)/2 == @s/2-$h(2)$w可以表示为$w=(@s=split//)/2-($h=int@s/4);,从而节省了两个分号
amon 2013年

更新了代码。
memowe 2013年

进一步有趣的东西:(1)该空间是数组插值var的默认值- $"节省1个字符。(2)– $w+$h == @s/2节省1个字符。(3)如果$w小一,我们可以简化$"x($w-1)。为此,$_必须将其增加1。节省3个字符。(4)最后的分号是überflüssig,节省1个字符。这导致了代码片段say@s[0..$w--];say$s[1-$_].$"x$w.$s[$w+$_]for+2..$h;say+reverse@s[@s/2..@s-$h](其中一些+很有趣,所以没有一个空格了)。
阿蒙

出色的高尔夫运动,@ amon,您能在我的帖子中对其进行编辑吗?这样,全世界可以看到谁做了。:)
memowe

5

Brainfuck - 194 187

+>,[>+[>+<-],]
>-->++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>[-]>[-]>[<<+<<+>>>>-]<<<<
[[<]>+[>]<-]<[<]>-
[>.[-]<[>+<-]>-]>[>]
++++++++++.<.[-]
>[>+++>>+<<<-]>++>--[<.>-]<<<<[<]>.[-]>[>]>>>>.
<<<<<[.<]

不错的尝试,但是它不起作用。底线是在错误的方向,违背规则1,而且它只有一个固定的高度,违反第3
VSZ

不知道为什么我翻了最后一行。当我编写它时,我完全想到了正确的方法。该修复程序实际上保存了7条命令。我没有对固定高度的东西进行处理,但不是您所说的琐碎的两行情况。也许将来我会做得更好。
captncraig 2013年

4

数学156 199 344

编辑:这是对先前代码的主要重写。它的工作原理基本相同,但现在将长度小于120个字符的字符串作为输入并自动调整正方形大小。

它仍然可以打些高尔夫球,但不会缩小到早期版本和Buggier版本的大小。

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

例子

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

图片1

图片2

图片3


嘿,一堆字符串?那真的是在违反规则,不是吗?
Thomas W.

@ThomasW。答案中的注释表明这不是最终解决方案。
kojiro

啊,我明白了!想知道我是否应该接受挑战并尝试使用PostScript中的类似方法...
Thomas W.

我喜欢现在的样子!
Thomas W.

@Thomas W.谢谢。要使格式在各种长度的字符串中正确显示,会花费很多字节。
DavidC

2

Perl +正则表达式:104(101 + 3)

(计数代码+开关)

这是一个使用正则表达式和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'

这只能在一条输入线上正确运行。

受memowe的启发,但基本上没有任何数组。


很抱歉这个愚蠢的问题:我该如何尝试?我将您的代码粘贴到命令行,然后键入一些内容,然后按Enter键,然后出现一些内容。但这不是盒子。我究竟做错了什么?
Thomas W.

@ThomasW。它对于我来说似乎有效,对于任意偶数个字符。上面的代码保证可以在bash和perl版本5.12+下使用。通过STDIN接受输入,并且仅第一行被正确处理。我不知道如何正确引用cmd.exe的代码。
阿蒙

1
嗯,可能是我的错。我可能使用了一串奇怪的长度。该作品: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)

这是受dude的Mathematica解决方案启发的。

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

用Ghostscript像这样

gs -st=hello! boxtext.ps

它产生类似的输出。

Hello_Code_Golf_World!

一月,二月,三月,四月,五月,六月,七月

它用来kshow一一显示字形。在显示了足以用于一侧的字形之后,将所有内容旋转-90度,然后再继续其余字形。

为了知道何时在侧面显示了足够的图示符,每显示一个图示符,我们就将计数器增加4。如果对字符串长度取模的计数器值小于4,则我们必须旋转:

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

在此处输入图片说明

已注释和未注释的源代码:

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

1

的Python 2.x:137

我是打高尔夫球的新手,因此可以肯定,这是可以改善的……

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]

视觉测试代码:

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

有趣的事情:此解决方案取决于整数数学。如果只是象征性地进行数学运算,则会发现h=(c-w-w)/2 => h=w-2,但是如果替换该结果,则其他所有结果将缺少两个左下角的字符。


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

1

斯卡拉(135)

以下代码段假定x包含要格式化的字符串,并且应将其粘贴在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)

如果没有安装Scala,则可以使用以下在线Scala解释器快速检查它:http : //www.simplyscala.com/。只需粘贴以下文本,然后按评估:

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)

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

测试

输入:

abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz

输出:

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

0

PHP(149)

要打印的文本应位于名为的变量中$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);

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]

编辑:它显然违反了包含内部最大面积的规则。


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

注意:-输入来自命令行

输入:-HelloWorld

输出:-

Hell
d  o
lroW

输入:-abcdefghijklmnopqrstuvwxyz

输出:-

abcdefghijkl
z          m
yxwvutsrqpon

请更仔细地阅读规则,尤其是nr。3.
vsz 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.