Прямокутник тексту


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

Завантажте, щоб спробувати . Використовуючи 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двічі, потім переходимо на відносні координати х / у, використовуючи 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, про що я насправді не знав ;-).
Thomas W.

@luserdroog: BTW: Я дуже пишаюся тим, що в поточному записі GolfScript є більше ніж на 10% більше символів, ніж мій бінарний запис, але мене помиляє, що моя версія ASCII на один символ від розіграшу з Ruby (насправді навіть три, тому що код Рубі можна було додатково пограти в гольф). Чи є у вас ідеї для подальшої оптимізації?
Thomas W.

@ThomasW. Тепер мій запис у GolfScript на 24% коротший, ніж ваш двійковий ;-) І я все ще думаю, що є ще шанс скоротити його ще більше на одну чи дві символи.
Говард

@Howard: Argh !!! Чи може хтось коли-небудь перемогти GolfScript?
Томас В.

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-му рядку (видалити пробіли).
Thomas W.

Мені це подобається. Спасибі. Добре виглядає, що до рядків Ruby можна отримати доступ як до масиву, я повинен був створити його сам. :)
memowe

Ви можете замінити x.lengthна x.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);, таким чином заощаджуючи два крапки з комою
амон

Оновлено код.
пам’ятка

Інші цікаві речі: (1) пробіл - це значення за замовчуванням інтерполяції масиву var $"–saves 1 char. (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

Відмінна гольфіфікація, @amon, чи не відредагуєте ви це в моєму дописі? Таким чином світ може побачити, хто це зробив. :)
memowe

5

Brainfuck - 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. Спасибі Отримання формату для правильного пошуку для широкого діапазону довжин рядків коштує чимало байтів.
DavidC

2

Perl + реджекси: 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'
Thomas W.

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

введіть тут опис зображення

Вихідний код із коментарями та без гольфу:

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

К, 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містить рядок для форматування, і його слід вставити в масштабову відповідь:

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

Пітон 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.