สี่เหลี่ยมผืนผ้าของข้อความ


13

โปรแกรมของคุณได้รับข้อความเป็นอินพุตอย่างน้อย 8 ตัวอักษรและประกอบด้วยจำนวนตัวอักษรเสมอ (ไม่จำเป็นต้องประเมินความถูกต้องของอินพุต)

เป้าหมายของคุณคือแสดงข้อความนั้นเป็นรูปสี่เหลี่ยมผืนผ้า ตัวอย่างเช่นกำหนดHelloWorldเป็นอินพุตให้แสดง

Hell
d  o
lroW

กฎ:

  • ข้อความหมุนไปตามเข็มนาฬิกา (ตำแหน่งเริ่มต้นตามที่คุณต้องการ)
  • มันจะเป็นรูปสี่เหลี่ยมผืนผ้าปิดด้านกว้าง 1 ตัวอักษร
  • สี่เหลี่ยมจะต้องครอบคลุมพื้นที่ส่วนใหญ่ภายใน (เพื่อแยกแยะคำตอบที่ไม่สำคัญในการแสดงข้อความในสองบรรทัด)
  • ไม่มีตัวอักษรอื่นใดพิมพ์นอกเหนือจากข้อความและช่องว่างภายในและช่องว่างที่จำเป็น

ในฐานะที่เป็น code-golf รหัสที่สั้นที่สุดจะเป็นผู้ชนะ

ผู้ชนะจะถูกเลือกไม่ช้ากว่า 10 วันหลังจากคำตอบที่ถูกต้องครั้งแรก

คำตอบ:



7

PostScript 50 ไบนารี 113 ASCII

สิ่งนี้ใช้เอาต์พุตกราฟิก Hexdump ของโปรแกรมโดยใช้โทเค็นไบนารี:

$ 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 0exch 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 bajeezus ศักดิ์สิทธิ์ ฉันขาดความรู้อย่างจริงจังในระดับ 2 และสูงกว่า
luser droog

คุณหมายถึงxyshowอะไร มีความสุขที่จะแนะนำคุณให้รู้จักกับคนนี้ - เมื่อไม่นานมานี้คุณแนะนำให้ฉันรู้จักkshowซึ่งฉันไม่ได้ตระหนักถึง ;-)
โทมัสดับเบิลยู.

@luserdroog: BTW: ฉันค่อนข้างภูมิใจที่รายการ GolfScript ปัจจุบันมีอักขระมากกว่ารายการไบนารี่ของฉันมากกว่า 10% แต่มันทำให้ฉันสับสนว่าเวอร์ชัน ASCII ของฉันเป็นตัวละครตัวหนึ่งจากการวาดด้วย Ruby (อันที่จริงแล้วแม้แต่สามคน) เพราะรหัส Ruby สามารถเล่นกอล์ฟเพิ่มเติมได้) คุณมีแนวคิดสำหรับการเพิ่มประสิทธิภาพเพิ่มเติมหรือไม่?
โทมัสดับบลิว

@ThomasW ตอนนี้รายการ GolfScript ของฉันสั้นกว่าไบนารีของคุณ 24% และฉันยังคิดว่ายังมีโอกาสที่จะทำให้สั้นลงอีกหนึ่งหรือสองตัวอักษร
Howard

@Howard: Argh !!! ทุกคนสามารถเอาชนะ GolfScript ได้ไหม
Thomas W.

7

ทับทิม112 100

ฉันใหม่กับรูบี้และนี่คือรหัสกอล์ฟครั้งแรกของฉัน ฉันเข้าสู่การใช้ perl ของ memowe และพยายามสร้าง 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 (ลบช่องว่าง)
โทมัสดับเบิลยู.

ฉันชอบมัน. ขอบคุณ ดูดีว่าสตริง Ruby สามารถเข้าถึงได้เหมือนอาเรย์ฉันต้องสร้างมันขึ้นมาเอง :)
บันทึก

คุณสามารถแทนที่x.lengthด้วยx.size(บันทึก 2 ตัวอักษร)
knut

1
และ 8 puts x[0..w=l/2-h=l/4]ขึ้นโดยใช้
Howard

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

อัปเดตรหัส
memowe

สิ่งที่น่าสนใจเพิ่มเติม: (1) พื้นที่เป็นค่าเริ่มต้นของการแก้ไขอาร์เรย์ var $"–saves 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

golfification ที่ยอดเยี่ยม @amon คุณจะแก้ไขมันในโพสต์ของฉันได้ไหม ด้วยวิธีนี้โลกจะเห็นว่าใครเป็นคนทำ :)
บันทึก

5

Brainfuck - 194 187

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

ลองดี แต่มันไม่ทำงาน บรรทัดล่างอยู่ในทิศทางที่ไม่ถูกต้องตรงกันข้ามกับกฎที่ 1 และมีความสูงคงที่ซึ่งตรงกันข้ามกับกฎที่ 3
vsz

ไม่แน่ใจว่าทำไมฉันพลิกแถวสุดท้าย ฉันรู้วิธีที่ถูกต้องในขณะที่ฉันเขียนมัน การแก้ไขจริงบันทึก 7 คำสั่ง ฉันจัดการกับสิ่งที่ความสูงคงที่ แต่มันไม่ใช่เรื่องเล็กน้อย 2 เรื่องที่คุณพูดถึง บางทีฉันจะทำให้ดีขึ้นในอนาคต
captncraig

4

Mathematica 156 199 344

แก้ไข : นี่คือการเขียนที่สำคัญของรหัสก่อนหน้านี้ มันใช้งานได้เหมือนกัน แต่ตอนนี้รับอินพุตสตริงที่มีความยาว <120 ตัวอักษรและปรับขนาดสี่เหลี่ยมให้โดยอัตโนมัติ

มันยังสามารถเล่นกอล์ฟได้เล็กน้อย แต่จะไม่ลดลงถึงขนาดของรุ่นก่อนหน้าและรุ่นบั๊กเกอร์

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

pic1

pic2

pic3


เฮ้อาร์เรย์ของสตริง? นั่นเป็นการดัดกฎจริงๆใช่มั้ย
Thomas W.

@ThomasW ความคิดเห็นในคำตอบบ่งบอกว่าไม่ใช่ทางออกสุดท้าย
kojiro

อ่าฉันเข้าใจแล้ว! สงสัยว่าฉันควรจะท้าทายและลองทำสิ่งที่คล้ายกันใน PostScript หรือไม่
Thomas W.

ฉันชอบที่มันดูเหมือนตอนนี้!
โธมัสดับเบิลยู.

@Thomas W. ขอบคุณ การจัดรูปแบบให้เหมาะสมกับความยาวสตริงที่หลากหลายนั้นมีค่าใช้จ่ายเป็นจำนวนมาก
DavidC

2

Perl + Regexes: 104 (101 + 3)

(การนับรหัส + สวิตช์)

นี่เป็นวิธีการแก้ปัญหาโดยใช้ Regexes ที่ดีและ 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 แล้วบางอย่างก็ออกมา แต่มันไม่ใช่กล่อง ผมทำอะไรผิดหรือเปล่า?
โธมัสดับเบิลยู.

@ThomasW ดูเหมือนว่าจะทำงานสำหรับฉันสำหรับจำนวนตัวอักษรแม้โดยพลการ รหัสข้างต้นรับประกันว่าจะทำงานภายใต้ bash และ perl เวอร์ชั่น 5.12+ อินพุตถูกยอมรับผ่าน STDIN และประมวลผลบรรทัดแรกเท่านั้นอย่างถูกต้อง ฉันไม่รู้วิธีอ้างรหัสอย่างถูกต้องสำหรับ cmd.exe
amon

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'
โทมัสดับเบิลยู

2

PostScript (106)

นี้เป็นแรงบันดาลใจวิธีการแก้ปัญหาของ 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!

มกราคม _February, _March, เมษายน, _May, _June, _July

มันใช้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

ป้อนคำอธิบายรูปภาพที่นี่

รหัสแหล่งความคิดเห็นและ un-golfed:

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 ล่ามออนไลน์: 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.