텍스트의 사각형


13

프로그램은 텍스트를 입력으로, 최소 8 자 이상이며 항상 짝수 문자로 구성합니다. (입력의 정확성을 평가할 필요가 없음).

목표는 해당 텍스트를 사각형으로 표시하는 것입니다. 예를 들어, HelloWorld입력으로 표시

Hell
d  o
lroW

규칙 :

  • 텍스트가 시계 방향으로 이동합니다 (원하는대로 시작 위치)
  • 측면은 1 자 너비의 닫힌 사각형을 형성합니다.
  • 사각형은 내부의 가장 많은 영역을 포함해야합니다. (단 두 줄로 텍스트를 표시하는 사소한 대답을 배제하기 위해)
  • 텍스트 자체와 필요한 패딩 공간 및 줄 바꿈 외에 다른 문자는 인쇄되지 않습니다.

코드 골프로서 가장 짧은 코드가 승리합니다.

첫 번째 유효한 답변 후 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

사용해보십시오 . 고스트 스크립트를 사용하여 렌더링 할 텍스트를 다음과 같이 프로그램에 전달할 수 있습니다.

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로 나누면 (한 번 바닥으로, 한 번은 천장으로)이 값 (2와 3)을 얻습니다.

따라서 우리는 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 : BTW : 현재 GolfScript 항목이 이진 항목보다 10 % 더 많은 문자를 가지고 있다는 것을 자랑스럽게 생각합니다.하지만 ASCII 버전이 Ruby를 사용하여 그리기에서 한 문자 떨어져 있다는 사실을 알게되었습니다. 루비 코드가 더 골프화 될 수 있기 때문입니다). 추가 최적화에 대한 아이디어가 있습니까?
Thomas W.

@ThomasW. 이제 내 GolfScript 항목이 바이너리보다 24 % 더 짧습니다. ;-) 그리고 여전히 한 두 글자 정도 더 단축 할 가능성이 여전히 있다고 생각합니다.
Howard

@Howard : 아아! 누구나 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 자라고 생각합니다. 고마워요!


좋은! 다섯 번째 줄에 두 문자를 저장할 수 있습니다 (공백 제거).
Thomas W.

나는 그것을 좋아한다. 감사. 루비 문자열이 배열처럼 액세스 될 수있는 것처럼 보입니다. 나는 스스로 직접 만들어야했습니다. :)
memowe

당신은 대체 할 수 x.lengthx.size(2 개 문자를 저장)
크 누트

1
그리고 8 더 사용 puts x[0..w=l/2-h=l/4]합니다.
Howard

5

펄 (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);, 따라서 2 개의 세미콜론을 절약 할 수있다
amon

코드를 업데이트했습니다.
memowe

더 흥미로운 점은 다음과 같습니다. (1) 공백은 배열 보간의 기본값 $"입니다. var –saves 1 char. (2) $w+$h == @s/2–1 문자를 저장합니다. (3) $w1 씩 작 으면 단순화 할 수 있습니다 $"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

훌륭한 골프화, @amon 내 게시물에서 편집 하시겠습니까? 그렇게하면 세상은 누가 그랬는지 알 수 있습니다. :)
memowe

5

브레인 퍽 - 194 187

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

시도는 좋지만 작동하지 않습니다. 결론은 규칙 1과 반대로 잘못된 방향이며 규칙 3과 반대로 고정 된 높이 만 있습니다.
vsz

마지막 줄을 왜 뒤집 었는지 모르겠습니다. 글을 쓸 때 올바른 방법을 염두에 두었습니다. 이 수정은 실제로 7 개의 명령을 저장합니다. 나는 고정 된 높이에 대해 경찰에 나섰지 만 그것은 당신이 이야기 한 사소한 2 라인 케이스가 아닙니다. 아마 나는 앞으로 더 나아질 것입니다.
captncraig

4

매쓰 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.

@ 토마스 W. 감사합니다. 광범위한 문자열 길이를 올바르게 표시하려면 많은 바이트가 필요합니다.
DavidC

2

펄 + 정규식 : 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'

이것은 하나의 입력 라인 에서만 올바르게 작동합니다 .

메모에서 영감을 얻었지만 본질적으로 배열은 없습니다.


바보 같은 질문에 대해 유감스럽게 생각합니다. 어떻게 시도 할 수 있습니까? 코드를 명령 줄에 붙여 넣은 다음 무언가를 입력하고 Enter 키를 누르면 무언가가 나옵니다. 그러나 그것은 상자가 아닙니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?
Thomas W.

@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'
Thomas W.

2

포스트 스크립트 (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!

1 월, _2 월, _3 월, 4 월, _5 월, _6 월, _7 월

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

파이썬 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형식화 할 문자열을 포함하고 있으며 스칼라 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)

스칼라가 설치되어 있지 않으면 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

파이썬 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

파이썬 2.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

자바-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.