Персонажі в рядку йдуть навколо і навколо


23

(Натхненний ранньою чергою виклику фрактальної лінії PhiNotPi .)

Вам задано ширину W > 1, висоту H > 1та рядок, що складається з 2(W+H-2)символів для друку ASCII. Завдання полягає в тому, щоб надрукувати цей рядок, обгорнутий навколо прямокутника заданої ширини та висоти, починаючи з верхнього лівого кута, за значенням за годинниковою стрілкою. Прямокутник всередині заповнений пробілами. Сподіваємось, тестові приклади повинні зробити це дуже зрозумілим.

Ви можете написати програму або функцію, взявши введення через STDIN (або найближчу альтернативу), аргумент командного рядка або аргумент функції, або друкуючи результат в STDOUT (або найближчу альтернативу) або повертаючи його як рядок.

Не повинно бути провідних чи кінцевих пробілів (крім тих, які можуть бути у вхідному рядку). Ви можете необов'язково виводити один зворотний рядок.

Це код гольфу, тому виграє найкоротше подання (у байтах).

Випробування

Кожен тестовий випадок "String" W Hсупроводжується очікуваним результатом.

"Hello, World! "
5 4
Hello
    ,
!    
dlroW

"+--+|||+--+|||"
4 5
+--+
|  |
|  |
|  |
+--+

">v<^"
2 2
>v
^<

"rock beats scissors beats paper beats "
11 10
rock beats 
          s
s         c
t         i
a         s
e         s
b         o
          r
r         s
epap staeb 

Note that the following string contains an escaped '"'.
"!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
46 3
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN
~                                            O
}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQP

Табло лідерів

Ось фрагмент стека для створення як звичайного табло, так і огляду переможців за мовою.

Щоб переконатися, що ваша відповідь відображається, будь ласка, почніть свою відповідь із заголовка, використовуючи наступний шаблон Markdown:

# Language Name, N bytes

де Nрозмір вашого подання. Якщо ви покращите свій рахунок, ви можете зберегти старі бали у заголовку, прокресливши їх. Наприклад:

# Ruby, <s>104</s> <s>101</s> 96 bytes


8
Ваші лідери такі круті.
Олексій А.

2
Ви грали у свій сценарій лідерів?
mbomb007

2
@ mbomb007 Ні, я запустив код через міні-міні, тому він не зайняв би багато місця при розширенні. (Напевно, видалення розривів рядків було б достатнім.) На моєму жорсткому диску все ще є непомічена версія.
Мартін Ендер

2
Якщо ви перейменовували це на "The Chars in the String Go Round and Round", воно краще відповідає ритму пісні.
Джастін

Відповіді:


9

CJam, 27 байт

Nl~:L/(os\2-{)L2-S*@(N@}*W%

Я насправді не CJam, але я думаю, що це б'є Мартіна. Основна відмінність полягає в тому, що ми висуваємо новий рядок перед читанням вводу і негайно друкуємо перший рядок, не заперечуючи необхідності зберігання висоти.

Здійснює введення в порядку

H "String" W

Спробуйте в Інтернеті.


10

Python 2, 95 байт

s,m,n=input()
print s[:n]
for i in range(m-2):print s[~i]+' '*(n-2)+s[n+i]
print s[1-m::-1][:n]

Друкується перший рядок, потім дві вертикальні лінії, потім останній рядок.

Має бути щось коротше, ніж писати printтри рази, але все, що я намагався до цього часу, економив до змінної і '\n'.joinбуло довше.


Ви можете перейти на Python 3 і зберігати друк із змінною ...
Омар

1
@Omar Це закінчується довше, тому що ви повинні використовувати evalна вводі та дужці оператори друку.
FryAmTheEggman

О, я не брав evalдо уваги! В круглих дужках не повинно виникнути особливих проблем, оскільки printв Python 2 потрібний пробіл після нього. Перехід print blahдо місця p(blah)зберігає 3 символи.
Омар

9

CJam, 31 30 байт

На наполягання оптимізатора, ось моя власна спроба. Я не прихильник виграшу власних викликів, тому я вважаю, що сім'я APL (або хтось кращий у CJam) переможе це. ;)

l~:H;:V/(N@s{)V2-S*@(N@}H2-*W%

Вводиться в тому ж порядку, що і в запитанні:

"Hello, World! " 5 4

Перевірте це тут.

Один байт збережено завдяки Optimizer.

Пояснення

Спочатку у мене була справді приємна ідея почати з прямокутника пробілів, а потім буквально обернути рядок навколо нього, обертаючи всю сітку чотири рази. Однак я не міг би зробити так, щоб це працювало у випадку, коли ширина або висота або те й інше 2. Тож я спробував наївний підхід (друкований верх, петля над сторонами, друк знизу), і дивно він виявився дійсно коротким.

l~                             "Read and evaluate the input.";
  :H;                          "Store the height in H and discard it.";
     :V/                       "Store the width in V and split the input into chunks of size V.";
        (N                     "Slice off the first such chunk and push a newline.";
          @s                   "Pull up the other chunks and join them back together.";
            {          }H2-*   "Repeat this block H-2 times, printing the sides.";
             )                 "Slice off the last character of the string.";
              V2-S*            "Push V-2 spaces.";
                   @(          "Pull up the remaining string and slice off the first character.";
                     N@        "Push a newline and pull up the remaining string.";
                            W% "Reverse the remainder of the string, which is the bottom row.";

Оскільки ми можемо отримати довжину рядка і маємо V, не потрібно зберігати H. Просто повторіть блок, поки не залишиться лише V символів. l~;:V/(N@s{)V2-S*@(N@_,V-}gW%економить 1 чар.
DocMax

@DocMax На жаль, це не працює для висоти 2. Хоча це гарна ідея, я розберемось, чи можу я якось по-іншому використати його.
Мартін Ендер

D'oh! Ви навіть згадали про проблему H = 2, і я все-таки забув її захистити.
DocMax

9

Pyth, 47 46 45 40 37 36 байт

Це очевидний підхід, реалізований у Pyth. Він друкує перший рядок шляхом індексації, 0:widthа потім середину, потім кінець.

Дякую @Jakube за пораду з використанням zта Qза два входи та використання p.

AkYQ<zkV-Y2p*d-k2@zt_N@z+kN;<_<z-2Yk

Вводиться зі строку як рядок і як кордону розмірів, розділяючи новий рядок:

Hello, World! 
5, 4

і пише в stdout.

Спробуйте тут .

A              Double assignment
 kY            The vars k and Y
 Q             The dimension tuple
<zk            Prints out first line by doing z[:width]
V-Y2           For N in height-2
 p             Print out everything
  *d           Repeat " "
   -k2         Width-2 times
  @z           Index z
   -_N1        At index -N-1
  @z           Index z
   +kN         At index k+N
;              Close out loop
<_<z-2Yk       Print last line

Використання zдля читання рядка економить досить багато символів. Також t_Nте саме, що -_N1.
Якубе

При нашому підході можливі 37 знаків.
Якубе

@Jakube дякую за поради!
Малтісен

Ще одне заощадження. Замість ++використання pі перемикання zt_Nз *d-k2.
Якубе

5

J, 61 байт

Спосіб:

Починаючи з (height-2)*(width-2)блоку пробілів, ми беремо необхідну кількість символів з кінця рядка і додаємо його до поточного блоку. Повторюємо це 4 рази. Усього 5 станів, проілюстрованих на 'Hello, World! ' 5 4прикладі (пробіли замінені на Xs для читабельності):

XXX   !_   orld   ,_W   Hello
XXX   XX   XXX!   XXo   _XXX,
      XX   XXX_   XXr   !XXX_
      XX          XXl   dlroW
                  _!d   

Кодекс:

4 :'|:>{:((}.~{:@$);({.~{:@$)|.@|:@,])&>/^:4(|.x);'' ''$~y-2'

Явне визначення функції. Функція з двома операндами приймає рядок як лівий аргумент, а список двох цілих чисел - як аргумент.

Приклад використання:

   wrap_on=.4 :'|:>{:((}.~{:@$);({.~{:@$)|.@|:@,])&>/^:4(|.x);'' ''$~y-2'

   'Hello, World! ' wrap_on 5 4
Hello
    ,
!    
dlroW

   '>v<^' wrap_on 2 2
>v
^<

Спробуйте його онлайн тут.


Нічого собі, я вражений, що це працює для ширини та висоти 2 у Дж.
Мартін Ендер

4

Піта, 38 37

AGHQ<zGFNC,_>z_ttH>zGj*dttGN)<>_zttHG

Спочатку я мав інше рішення 38, але це було в основному рішенням гри в гольф відповіді Мальтісена. Тому я вирішив піти трохи інакше.

Спробуйте в Інтернеті .

              implicit: z=string from input, Q=pair of numbers from input
AGHQ          G=Q[0] (width), H=Q[1] (height)
<zG           print z[:G]
    _>z_ttH     last H-2 chars reversed
    >zG         all chars from the Gth position to end
  C,           zip these 2 strings to pairs
FN            for each pair N:
  j*dttGN       seperate the two chars by (G-2) spaces and print
)             end for
<>_zttHG     print last line z[::-1][H-2:][:G]

_>z_ttHеквівалентно <_zttH.
isaacg

@isaacg Спасибі, у відповіді Малтісен вже бачив щось подібне.
Якубе

4

JavaScript (ES6), 110 115

Функція з 3 параметрами, повертаючи рядок

F=(s,w,h,q=h+(w-=2),t=b='')=>
[for(c of s)q?t+=q<h?c+'\n'+s[w+h+w+q--]+' '.repeat(q&&w):(b+=s[w+q--],c):q]
&&t+b

Версія Chrome Chrome 119 : немає короткого формату для функцій, немає параметрів за замовчуванням Немає підстав використовувати, for(of)навіть якщо це підтримується

function F(s,w,h){
  for(q=h+(w-=2),t=b=i='';
      q;
      q<h?t+='\n'+s[w+h+w+q--]+' '.repeat(q&&w):b+=s[w+q--])
    t+=s[i++];
  return t+b
}

Версія ES5 126 : немає для (з), немає рядка.повторити

function F(s,w,h){
  for(q=h+(w-=2),t=b=i='';
      q;
      q<h?t+='\n'+s[w+h+w+q--]+Array(q&&-~w).join(' '):b+=s[w+q--])
    t+=s[i++];
  return t+b
}

Безумовно

F=(s,w,h)=>
{
  var q = h+(w-=2), // middle length 
      t = '', // top and body
      b = ''; // bottom row
  for(c of s)
    if (q > 0)
    {
      if (q < h)
      {
        t += c+'\n'; // right side, straight
        t += s[w+h+w+q]; // left side, backwards 
        if (q > 1) // body fill, except for the last line
          t += ' '.repeat(w)
      }
      else
      {
        t+=c, // top, straight
        b+=s[w+q] // bottom, backwards
      }
      --q
    }
  return t+b

Тест у консолі Firefox / FireBug

;[["Hello, World! ", 5, 4],["+--+|||+--+|||",4,5],[">v<^",2,2]
,["rock beats scissors beats paper beats ",11,10]
,["!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~",46,3]]
.forEach(test => console.log(F(...test)))

Вихід

Hello
    ,
!    
dlroW

+--+
|  |
|  |
|  |
+--+

>v
^<

rock beats 
          s
s         c
t         i
a         s
e         s
b         o
          r
r         s
epap staeb 

!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN
~                                            O
}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQP

3

Python 2, 97 байт

def f(s,w,h):print s[:w];i=0;exec'print s[~i]+" "*(w-2)+s[w+i];i+=1;'*(h-2);print s[1-h:w+h-3:-1]

Прийняття прямого підходу.


3

Haskell, 164 156 байт

import Data.List
r=replicate
p w h(s:t)=unlines$fst$n$n$n$n(r h$r w ' ',(w,h,s:t++[s]))
n(_:b,(w,h,s))=(transpose$map reverse$(take w s):b,(h,w,drop(w-1)s))

Функція pне друкує вихід, але повертає його як рядок, наприклад p 4 5 "+--+|||+--+|||"-> "+--+\n| |\n| |\n| |\n+--+\n". Для кращого використання дисплея putStr:

putStr $ p 4 5 "+--+|||+--+|||"

+--+
|  |
|  |
|  |
+--+

Як це працює: я створюю блок wx hпробілів і замінюю перший рядок початком вхідного рядка. Потім я обертаю блок проти годинникової стрілки і повторюю заміну першого рядка ще три рази.

Щоб уникнути скорочення першого символу після черги №4, я додаю його до вхідного рядка перед запуском.

"Hello World" example, 5 x 4


         |  Start               Turn #1          Turn #2     Turn #3   Turn #4
---------+--------------------------------------------------------------------
String   |  "Hello, World! H"   "o, World! H"    "World! H"  "d! H"    ""
left     | 
         |
Block    |  <empty>             Hello            o, W        World     d! H
before   |                                       l                     l  e
rotating |                                       l           ,         r  l
         |                                       e           olleH     o  l
         |                                       H                     W ,o

Редагувати: знайшов кращий спосіб вирішити проблему «Вирізати перший символ після повороту №4».


Ну добре ... це схоже на те, що я спробував у CJam, за винятком того, що працює. ;)
Мартін Ендер

3

Постскрипт, 62 байти

Це звичайно використовує двійкові лексеми, але це еквівалентно:

/Courier findfont setfont

0 h moveto

s [
    w {1 0} repeat pop pop
    h {0 -1} repeat pop pop
    w {-1 0} repeat pop pop
    h {0 1} repeat
] xyshow

Ось шістнадцятковий файл ( xxd round.ps):

0000000: 91c7 9243 9295 3020 6892 6b73 5b77 7b31  ...C..0 h.ks[w{1
0000010: 2030 7d92 8392 7592 7568 7b30 202d 317d   0}...u.uh{0 -1}
0000020: 9283 9275 9275 777b 2d31 2030 7d92 8392  ...u.uw{-1 0}...
0000030: 7592 7568 7b30 2031 7d92 835d 92c3       u.uh{0 1}..]..

Виконувати як:

gs -dw=11 -dh=10 -ss="rock beats scissors beats paper beats " round.ps

Вихід дійсно малий (внаслідок зовсім не масштабування шрифту), тому для його побачення потрібно збільшити масштаб.

Це використовує перевагу xyshowоператора, щоб виписати рядок, використовуючи спеціальні проміжки символів. У цьому випадку я використовую негативний вертикальний пробіл для запису, потім негативний горизонтальний простір для запису назад, потім позитивний вертикальний простір для запису вгору. Через це мені не потрібно використовувати будь-які струнні маніпуляції.


3

> <>, 82 80 + 3 = 83 байти

:2-&\
v!?:<oi-1
/?(0:i
\~ao{2-{~}
\{:?!v1-}o&:&
>:?v!~{{o}ao4.
^  >" "o1-
o;!?l<

Сторінка Esolang для> <> (Риба)

Це виявилося коротшим, ніж я очікував. Він використовує прямолінійний підхід до друку першого рядка, потім стовпчики, оббиті центральними пробілами, потім останній рядок.

Введіть рядок через STDIN та висоту та ширину за допомогою командного рядка з -vпрапором, наприклад:

py -3 fish.py round.fish -v <height> <width>

Пояснення

:2-&           Put W-2 in the register
:?!v1-io       Directly print the first W characters of the input
i:0(?/         Read the rest of the input
~ao{2-{~}      Pop a few leftovers 0s from above, decrement H by 2 and print a newline
               Stack now consists of H = H-2 at the bottom and the rest of the input reversed

[loop]

{:?!v          If H is 0...
  ~                Pop the 0
  l?!;o            Print the rest of the (reversed) input

               Otherwise...
  1-}              Decrement H
  o                Output the top of stack
  &:&              Copy I = W-2 from the register
  :?               If I is nonzero...
    " "o1-             Print a space and decrement I, then repeat from the previous line
  {{o}ao           Print the bottom input character and output a newline
  4.               Jump to the start of the loop (note that I = 0 is leftover from above)

2

Bash + coreutils, 124

Сценарій оболонки для початку роботи:

echo "${3:0:$1}"
fold -1<<<"${3:$1*2+$2-2}"|tac|paste - <(fold -1<<<"${3:$1:$2-2}")|expand -t$[$1-1]
rev<<<"${3:$1+$2-2:$1}"

Передати введення як аргументи командного рядка:

$ ./roundnround.sh 5 4 "Hello, World! "
Hello
    ,
!    
dlroW
$ 

2

JavaScript, 161 160 158 байт

Метод, який я придумав, виявився занадто довгим, але о, ну, це була практика. (Крім того, я отримав це для написання r+o[u]+'\n':d.)

function f(o,w,n){s=o.slice(0,w)+'\n';o=o.slice(w);n-=2;r='';for(u=w-2;u--;)r+=' ';for(u=d=0;d=o[2*n+w+~u],u<w+n;u++)s+=(u<n)?(d||' ')+r+o[u]+'\n':d;return s}

Для введення, яке не має сенсу, вихід не визначений (буквально, і в багато разів), але він працює для всіх тестових випадків.


sliceкоротше substr, це не зовсім те саме, але в цьому випадку ви можете використовувати його
edc65

2

Гровий, 140

f={a,x,y->println a.substring(0,x);(1..y-2).each{println a[a.length()-it]+' '*(x-2)+a[it+x-1]}println a.substring(x+y-2,2*x+y-2).reverse()}

дзвінок:

f('rock beats scissors beats paper beats ',11,10)

вихід:

rock beats 
          s
s         c
t         i
a         s
e         s
b         o
          r
r         s
epap staeb 

2

К, 55 54 байти

Використовуючи той самий підхід, що і J-реалізація випадкових; Почніть з блоку пробілів і додайте від хвоста струни до краю, обертаючи чотири рази:

f:{`0:*4{((,r#*|x),|:'+*x;(r:-#*x)_*|x)}/((y-2)#" ";x)}

І кілька прикладів:

  f["Hello,_World!_";4 5]
Hello
_   ,
!   _
dlroW

  f[">v<^";2 2]
>v
^<

Трохи зруйнувавши її для читабельності,

Створення блоку NxM:

  t:2 3#!6
(0 1 2
 3 4 5)

Поверніть на 90 градусів, використовуючи транспонирование ( +) та реверс кожного ( |:'):

  |:'+t
(3 0
 4 1
 5 2)

Отже, якщо у нас є пробіл tі рядок s, ми можемо додати скибочку хвоста sдо t:

  s: 12 18 17 8 9
12 18 17 8 9
  (,(-#t)#s),|:'+t
(8 9
 3 0
 4 1
 5 2)

Ми використовуємо форму, 4 {[x] ... }/( ... )щоб неодноразово застосовувати функцію до кортежу, що складається з рядка та матриці, яку ми будуємо. Кожен раз, коли ми робимо цей крок обертання і з'єднання, ми також рубаємо рядок.

редагувати:

Інша ідея - спробувати розділити вхідний рядок на потрібні нам фрагменти при кожному обертанні, що спрощує основну частину програми. На жаль, це працює трохи більше 56 байт:

f:{`0:((y-2)#" "){|:'(,y),+x}/(+\(0,y[0 1 0]-2 1 1))_|x}

Якщо є кращий спосіб обчислити ці точки розділення, я відкритий для пропозицій.

edit2:

Трохи перестановка дозволяє мені видалити пару круглих дужок. 54 байти!

f:{`0:((y-2)#" "){|:'(,y),+x}/(0,+\y[0 1 0]-2 1 1)_|x}

2

К, 80 68 байт

f:{[s;y;n]`0:(,n#s),({s[(#s)-x+2],((n-2)#" "),s@n+x}'!y-2),,n#|-4!s}

Скорочено з 80 завдяки @JohnE.

Оригінал:

f:{s:x;n:z;`0:(,s@!n),({s[(#s)+-2-x],({" "}'!n-2),s@n+x}'!y-2),,(|s@!-4+#s)@!n}

Я ледь навіть не знаю, як ця річ працює.

Приклад використання:

f["Hello, world! ";5;4]

Існує кілька можливих оптимізацій, але я продовжую робити Kona segfault ...


Ви можете поліпшити цей біт, використовуючи «взяти» (двійковій - #) і явний список аргументів: f:{[s;y;n]`0:(,n#s),({s[(#s)-x+2],((n-2)#" "),s@n+x}'!y-2),,n#|-4!s}. По моєму рахунку 68 символів.
JohnE

@JohnE Дякую! Я знав про явний список аргументів, але це якимось чином прослизнуло мені в думці; Я не мав поняття про діадичний #, хоча.
kirbyfan64sos

2

R, 178

Це неназвана функція, яка бере s, w, hпараметри. Я хотів би, щоб був приємніший спосіб розділити струну.

function(s,w,h){W=w+h-1;H=w+W-1;S=strsplit(s,'')[[1]];O=array(" ",c(h,w+1));O[,w+1]="\n";O[1:h,c(w,1)]=c(S[w:W],S[(W+W-1):H]);O=t(O);O[1:w,c(1,h)]=c(S[1:w],S[H:W]);cat(O,sep='')}

Безумовно

W=w+h-1;                                 # additional index points
H=w+W-1;                                 # additional index points
S=strsplit(s,'')[[1]];                   # vectorize the string
O=array(" ",c(h,w+1));                   # create an array of spaces
O[,w+1]="\n";                            # set newlines
O[1:h,c(w,1)]=c(S[w:W],S[(W+W-1):H]);    # build middles lines
O=t(O);                                  # transpose array
O[1:w,c(1,h)]=c(S[1:w],S[H:W]);          # build top and bottom lines
cat(O,sep='')                            # cat out results

Тестовий запуск

> (function(s,w,h){W=w+h-1;H=w+W-1;S=strsplit(s,'')[[1]];O=array(" ",c(h,w+1));O[,w+1]="\n";O[1:h,c(w,1)]=c(S[w:W],S[(W+W-1):H]);O=t(O);O[1:w,c(1,h)]=c(S[1:w],S[H:W]);cat(O,sep='')})("Hello, World! ",5,4)
Hello
    ,
!    
dlroW
> (function(s,w,h){W=w+h-1;H=w+W-1;S=strsplit(s,'')[[1]];O=array(" ",c(h,w+1));O[,w+1]="\n";O[1:h,c(w,1)]=c(S[w:W],S[(W+W-1):H]);O=t(O);O[1:w,c(1,h)]=c(S[1:w],S[H:W]);cat(O,sep='')})("+--+|||+--+|||",4,5)
+--+
|  |
|  |
|  |
+--+
> (function(s,w,h){W=w+h-1;H=w+W-1;S=strsplit(s,'')[[1]];O=array(" ",c(h,w+1));O[,w+1]="\n";O[1:h,c(w,1)]=c(S[w:W],S[(W+W-1):H]);O=t(O);O[1:w,c(1,h)]=c(S[1:w],S[H:W]);cat(O,sep='')})(">v<^",2,2)
>v
^<
> (function(s,w,h){W=w+h-1;H=w+W-1;S=strsplit(s,'')[[1]];O=array(" ",c(h,w+1));O[,w+1]="\n";O[1:h,c(w,1)]=c(S[w:W],S[(W+W-1):H]);O=t(O);O[1:w,c(1,h)]=c(S[1:w],S[H:W]);cat(O,sep='')})("rock beats scissors beats paper beats ",11,10)
rock beats 
          s
s         c
t         i
a         s
e         s
b         o
          r
r         s
epap staeb
> # Escaped the \ as well 
> (function(s,w,h){W=w+h-1;H=w+W-1;S=strsplit(s,'')[[1]];O=array(" ",c(h,w+1));O[,w+1]="\n";O[1:h,c(w,1)]=c(S[w:W],S[(W+W-1):H]);O=t(O);O[1:w,c(1,h)]=c(S[1:w],S[H:W]);cat(O,sep='')})("!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~",46,3)
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN
~                                            O
}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQP
> 

2

T-SQL, 307

Хоча це все ще жахливо довго, це виявилося зовсім легше (і коротше), ніж я думав у запиті. Реалізована як функція вбудованої таблиці в ціні для T-SQL.

CREATE FUNCTION f(@S VARCHAR(MAX),@ INT,@H INT)RETURNS TABLE RETURN WITH R AS(SELECT 2i,LEFT(@S,@)S,STUFF(@S,1,@,'')+'|'R UNION ALL SELECT i+1,CASE WHEN i<@H THEN LEFT(RIGHT(R,2),1)+REPLICATE(' ',@-2)+LEFT(R,1)ELSE REVERSE(LEFT(R,@))END,STUFF(STUFF(R,LEN(R)-1,1,''),1,1,'')FROM R WHERE i<=@H)SELECT S FROM R

Це повторюється через рядок @h разів. Перша рекурсія кліпує символи @W із рядка. Середні рекурсії беруть останню та першу із залишкової струни із накладкою на рядки між ними. Остання рекурсія повертає назад те, що залишилося. Є кілька втрачених символів, які стосуються того, як SQL Server обробляє пробіли у VARCHARS.

Тестовий запуск

WITH TestSet AS (
    SELECT *
    FROM (VALUES
        ('Hello, World! ',5,4),
        ('+--+|||+--+|||',4,5),
        ('>v<^',2,2),
        ('rock beats scissors beats paper beats ',11,10),
        ('!"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~andfoure',50,3)
        ) Test(S,W,H)
)
SELECT x.S 
FROM TestSet 
    CROSS APPLY (
        SELECT S FROM dbo.F(S,W,H)
        )x

S
----------------------------
Hello
    ,
!    
dlroW
+--+
|  |
|  |
|  |
+--+
>v
^<
rock beats 
          s
s         c
t         i
a         s
e         s
b         o
          r
r         s
epap staeb 
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQR
e                                                S
ruofdna~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUT

(24 row(s) affected)


2

MATLAB, 101

function f(H,W,S)
w=1:W;h=(0:H-3).';n=W+H-2;S(3*n)=' ';S([w;[2*n-h,3*n*ones(H-2,W-2),h+W+1];n-w+W+1])

1

C ++, 398 байт

Використаний компілятор - GCC 4.9.2 з -std=c++14прапором

#include<bits/stdc++.h>
using namespace std;string s;vector<vector<char>> M;int w,h,p,i,j;void F(int x,int y){if(p<s.size()&&(((!y||y==h-1)&&x>=0&&x<w)||((!x||x==w-1)&&y>=0&&y<h))&&!M[y][x])M[y][x]=s[p++],F(x+1,y),F(x,y+1),F(x-1,y),F(x,y-1);}int main(){getline(cin,s);cin>>w>>h;M.resize(h,vector<char>(w,0));F(0,0);while(i<h){j=0;while(j<w){if(!M[i][j])M[i][j]=32;cout<<M[i][j++];}i++;cout<<endl;}}

Перевірте це тут.

Пояснення

#include<bits/stdc++.h>
using namespace std;

string s; // input string
vector<vector<char>> M; // output matrix
int w, h, p, i, j;
// w = width
// h = height
// p = iterator over s
// i, j = iterators used later for printing answer

void F( int x, int y )
{
    // If the coordinates (x, y) are either on the first row/column or the last row/column and are not already populated with the input characters, populate them
    if ( p < s.size() && ( ( ( y == 0 || y == h - 1 ) && x >= 0 && x < w ) || ( ( x == 0 || x == w - 1 ) && y >= 0 && y < h ) ) && !M[y][x] )
    {
        M[y][x] = s[p++];
        F( x + 1, y );
        F( x, y + 1 );
        F( x - 1, y );
        F( x, y - 1 );
    }
}

int main()
{
    getline( cin, s );
    cin >> w >> h;
    // Input taken !!

    M.resize( h, vector<char>( w, 0 ) ); // Fill the matrix with null characters initially

    F( 0, 0 ); // This function does all the work

    // Now printing the matrix
    while ( i < h )
    {
        j = 0;
        while ( j < w )
        {
            if ( !M[i][j] )
            {
                M[i][j] = ' ';  // Replace '\0' with ' '
            }
            cout << M[i][j++];
        }
        i++;
        cout << endl;
    }

}

Не вдалося зберегти символи, скориставшись char[][]натомість?
corsiKa

Ні, vector<vector<char>> M;M.resize(h,vector<char>(w,0));трохи коротше, ніжchar** M;M=new char*[h];while(i<h)M[i++]=new char[w]();
Анмоль Сінгх Яггі

1

Перл, 193, 195 байт

($s,$w,$h,$i,$y)=(@ARGV,0,2);
$o.=substr$s,$i,$w;
$i+=$w;
$o.=sprintf"\n%s%*s",substr($s,2*($w+$h)-$y++-3,1)||' ',$w-1,substr($s,$i++,1)while$y<$h;
print$o."\n".reverse(substr($s,$i,$w))."\n";

Я впевнений, що це можна значно покращити. Я ноб. >, <


0

Java 11, 180 байт

(s,w,h)->{var r=s.substring(0,w)+"\n";int i=w;for(var S=s.split("");i<w+h-2;)r+=S[3*w+2*h-i-5]+" ".repeat(w-2)+S[i++]+"\n";return r+new StringBuffer(s.substring(i,i+w)).reverse();}

Спробуйте в режимі он-лайн (ПРИМІТКА: String.repeat(int)емулюється як repeat(String,int)для того ж байтового рахунку, оскільки Java 11 ще не є на TIO.)

Пояснення:

(s,w,h)->{               // Method with String & 2 int parameters and String return-type
  var r=s.substring(0,w)+"\n";
                         //  Result-String, starting at the the first row of output,
                         //  which is a substring in the range [0, `w`)
  int i=w;               //  Index-integer, starting at `w`
  for(var S=s.split(""); //  Split the input-String into a String-array of characters
      i<w+h-2;)          //  Loop `i` in the range [`w`, `w+h-2`)
    r+=                  //   Append the result-String with:
       S[3*w+2*h-i-5]    //    The character at index `2*w+2*h-4 - i+w-1`
       +" ".repeat(w-2)  //    Then append `w-2` amount of spaces
       +S[i++]           //    Then append the character at index `i`
       +"\n";            //    And a trailing new-line
  return r               //  After the loop, return `r` as result
         +new StringBuffer(s.substring(i,i+w)).reverse();
                         //  Appended with the last row of output,
                         //  which is a substring in the range [`i`, `i+w`) reversed

0

Вугілля деревне , 4 байти

BNNS

Спробуйте в Інтернеті (багатослівний) або спробуйте онлайн (чисто) .

Пояснення:

В основному побудова для цього завдання. Візьміть перші два цілі входи як ширину та висоту, а друкуйте поле як третій вхідний рядок:

Box(InputNumber(), InputNumber(), InputString())
BNNS
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.