Znaki w ciągu ciągną się w kółko

23

(Zainspirowany wczesnym szkicem wyzwania fraktalnej linii PhiNotPi .)

Otrzymujesz szerokość W > 1, wysokość H > 1i ciąg znaków składający się z 2(W+H-2)drukowalnych znaków ASCII. Zadanie polega na wydrukowaniu tego ciągu owiniętego wokół prostokąta o określonej szerokości i wysokości, zaczynając od lewego górnego rogu, zgodnie z ruchem wskazówek zegara. Wnętrze prostokąta jest wypełnione spacjami. Mamy nadzieję, że przypadki testowe wyjaśnią to bardzo wyraźnie.

Możesz napisać program lub funkcję, pobierając dane wejściowe przez STDIN (lub najbliższą alternatywę), argument wiersza poleceń lub argument funkcji i albo drukując wynik do STDOUT (lub najbliższej alternatywy), albo zwracając go jako ciąg znaków.

Nie może być spacji wiodących ani końcowych (oprócz tych, które mogą znajdować się w ciągu wejściowym). Opcjonalnie możesz wypisać jeden końcowy znak nowej linii.

To jest kod golfowy, więc wygrywa najkrótsze przesłanie (w bajtach).

Przypadki testowe

Po każdym przypadku testowym "String" W Hnastępuje oczekiwany wynik.

"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

Liderów

Oto fragment kodu, który pozwala wygenerować zarówno zwykłą tabelę wyników, jak i przegląd zwycięzców według języka.

Aby upewnić się, że twoja odpowiedź się pojawi, zacznij od nagłówka, korzystając z następującego szablonu Markdown:

# Language Name, N bytes

gdzie Njest rozmiar twojego zgłoszenia. Jeśli poprawić swój wynik, to może zachować stare porachunki w nagłówku, uderzając je przez. Na przykład:

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

Martin Ender
źródło
8
Twoje tabele wyników są takie fajne.
Alex A.
2
Czy grałeś w golfa w swoim skrypcie liderów?
mbomb007
2
@ mbomb007 Nie, przepuściłem kod przez minizery, więc po rozwinięciu nie zajmie dużo miejsca. (Wydaje mi się, że usunięcie podziałów linii byłoby wystarczające.) Nadal mam nieuprawnioną wersję na dysku twardym.
Martin Ender
2
Jeśli zmienisz nazwę na „The Chars in the String Go Round and Round”, lepiej pasuje do rytmu utworu.
Justin

Odpowiedzi:

9

CJam, 27 bajtów

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

Naprawdę nie CJam, ale myślę, że to bije Martina. Główną różnicą jest to, że wciskamy nowy wiersz przed odczytem danych wejściowych i natychmiast drukujemy pierwszy wiersz, co eliminuje potrzebę przechowywania wysokości.

Pobiera dane wejściowe w kolejności

H "String" W

Wypróbuj online.

Sp3000
źródło
10

Python 2, 95 bajtów

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]

Drukuje pierwszą linię, następnie dwie pionowe linie, a następnie ostatnią linię.

Musi być coś krótszego niż printtrzykrotne pisanie , ale wszystko, co do tej pory próbowałem z zapisaniem do zmiennej i '\n'.joinbyło dłuższe.

xnor
źródło
Możesz przełączyć się na Python 3 i przechowywać druk w zmiennej ...
Omar,
1
@Omar To kończy się dłużej, ponieważ musisz użyć evalna wejściu i nawiasować instrukcje print.
FryAmTheEggman
Och, nie wziąłem evalpod uwagę! Nawias nie powinien stanowić większego problemu, ponieważ printw Pythonie 2 wymaga spacji po nim. Przejście od print blahdo p(blah)nadal oszczędza 3 postacie.
Omar,
9

CJam, 31 30 bajtów

Pod naciskiem Optimizera, oto moja własna próba. Nie jestem fanem wygrywania własnych wyzwań, dlatego liczę rodzinę APL (lub kogoś lepszego w CJam), aby to pokonać. ;)

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

Pobiera dane wejściowe w tej samej kolejności, jak podano w pytaniu:

"Hello, World! " 5 4

Sprawdź to tutaj.

Jeden bajt zapisany dzięki Optymalizatorowi.

Wyjaśnienie

Początkowo miałem naprawdę fajny pomysł, aby zacząć od prostokąta odstępów, a następnie dosłownie owinąć wokół niego sznurek, obracając jednocześnie całą siatkę cztery razy. Jednak nie wydaje mi się, aby działało to w przypadku, gdy szerokość lub wysokość lub oba są 2. Wypróbowałem więc naiwne podejście (drukuj górę, pętla na bokach, drukuj dół) i, co zaskakujące, okazało się, że jest naprawdę krótkie.

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.";
Martin Ender
źródło
Ponieważ możemy uzyskać długość łańcucha i mamy V, nie trzeba zapisywać H. Po prostu powtarzaj blok, aż pozostaną tylko znaki V. l~;:V/(N@s{)V2-S*@(N@_,V-}gW%oszczędza 1 znak
DocMax,
@DocMax Niestety, to nie działa na wysokości 2. Jest to jednak dobry pomysł, przyjrzę się, czy mogę go użyć w inny sposób.
Martin Ender
Nie! Wspomniałeś nawet o problemie H = 2 i wciąż zapomniałem się przed nim uchronić.
DocMax,
9

Pyth, 47 46 45 40 37 36 bajtów

Jest to oczywiste podejście zastosowane w Pyth. Drukuje pierwszą linię, indeksując, 0:widtha następnie środek, a następnie koniec.

Dzięki @Jakube za wskazówkę przy użyciu zi Qza dwa wejścia i przy użyciu p.

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

Pobiera dane wejściowe ze stdin jako ciąg znaków i jako krotkę wymiarów, separator nowej linii:

Hello, World! 
5, 4

i pisze na standardowe wyjście.

Wypróbuj tutaj .

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
Maltysen
źródło
Używanie zdo odczytu łańcucha oszczędza sporo znaków. t_NJest to również to samo, co -_N1.
Jakube,
Przy naszym podejściu możliwe jest 37 znaków.
Jakube,
@Jakube dzięki za wskazówki!
Maltysen
Jeszcze jeden znak oszczędności. Zamiast ++używać pi przełączać za zt_Npomocą *d-k2.
Jakube,
5

J, 61 bajtów

Metoda:

Zaczynając od (height-2)*(width-2)bloku spacji, bierzemy niezbędną liczbę znaków z końca łańcucha i dodajemy go do bieżącego bloku. Powtarzamy to 4 razy. Łącznie 5 stanów zilustrowanych 'Hello, World! ' 5 4przykładem (spacje zastąpiono Xliterami s dla czytelności):

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

Kod:

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

Jawna definicja funkcji. Funkcja dwóch argumentów przyjmuje ciąg jako lewy argument, a listę dwóch liczb całkowitych jako prawy argument.

Przykładowe użycie:

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

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

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

Wypróbuj online tutaj.

randomra
źródło
Wow, jestem pod wrażeniem, że działa to dla szerokości i wysokości 2 w J.
Martin Ender
4

Pyth, 38 37

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

Początkowo miałem inne rozwiązanie 38, ale było to w zasadzie golfowe rozwiązanie odpowiedzi Maltysena. Postanowiłem więc pójść trochę inaczej.

Wypróbuj online .

              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]
Jakube
źródło
_>z_ttHjest równoważne z <_zttH.
isaacg
@isaacg Dzięki, już widziałem coś podobnego w odpowiedzi Maltysena.
Jakube,
4

JavaScript (ES6), 110 115

Funkcja z 3 parametrami, zwracająca ciąg znaków

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

Wersja Chrome 119 : brak krótkiego formatu dla funkcji, brak domyślnych parametrów. Nie ma powodu, aby używać, for(of)nawet jeśli jest obsługiwany

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 wersja 126 : nie dla (of), bez string.repeat

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
}

Bez golfa

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

Przetestuj w konsoli 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)))

Wydajność

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
edc65
źródło
3

Python 2, 97 bajtów

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]

Podejście bezpośrednie.

Sp3000
źródło
3

Haskell, 164 156 bajtów

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

Funkcja pnie drukuje wyniku, ale zwraca go jako ciąg, np. p 4 5 "+--+|||+--+|||"-> "+--+\n| |\n| |\n| |\n+--+\n". Dla lepszego wykorzystania wyświetlacza putStr:

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

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

Jak to działa: tworzę wx hblok spacji i zastępuję pierwszy wiersz początkiem ciągu wejściowego. Następnie obracam blok przeciwnie do ruchu wskazówek zegara i powtarzam zastępując pierwszą linię jeszcze trzy razy.

Aby zapobiec wycinaniu pierwszego znaku po zakończeniu tury # 4, dołączam go do ciągu wejściowego przed rozpoczęciem.

"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

Edycja: znalazłem lepszy sposób rozwiązania problemu odcięcia pierwszego znaku po skręcie # 4.

nimi
źródło
Ach miło ... jest to podobne do tego, co próbowałem w CJam, tyle że działa. ;)
Martin Ender
3

Postscript, 62 bajty

To oczywiście używa tokenów binarnych, ale jest to równoważne z:

/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

Oto zrzut pliku ( 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}..]..

Uruchom jako:

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

Wyjście jest naprawdę małe (w wyniku braku skalowania czcionki), więc musisz trochę powiększyć, aby go zobaczyć.

Dzięki temu xyshowoperator może napisać ciąg przy użyciu niestandardowych odstępów między znakami. W tym przypadku używam ujemnych odstępów pionowych, aby zapisać, następnie ujemnych odstępów poziomych, aby pisać do tyłu, a następnie dodatnich odstępów pionowych, aby pisać do góry. Z tego powodu nie muszę używać żadnych manipulacji ciągami.

AJMansfield
źródło
3

> <>, 82 80 + 3 = 83 bajty

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

Strona Esolang dla> <> (Ryba)

To okazało się krótsze niż się spodziewałem. Wykorzystuje proste podejście do drukowania pierwszej linii, następnie kolumn wypełnionych środkowymi spacjami, a następnie ostatniej linii.

Wprowadź ciąg znaków za pomocą STDIN, a wysokość i szerokość za pomocą wiersza polecenia z -vflagą, tak jak poniżej:

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

Wyjaśnienie

: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)
Sp3000
źródło
2

Bash + coreutils, 124

Skrypt powłoki na początek:

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

Przekaż dane wejściowe jako argumenty wiersza poleceń:

$ ./roundnround.sh 5 4 "Hello, World! "
Hello
    ,
!    
dlroW
$ 
Cyfrowa trauma
źródło
2

JavaScript, 161 160 158 bajtów

Metoda, którą wymyśliłem, okazała się zbyt długa, ale no cóż, to była praktyka. (Poza tym mam to przeliterować 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}

Dla danych wejściowych, które nie mają sensu, dane wyjściowe są niezdefiniowane (dosłownie i kilka razy), ale działa we wszystkich przypadkach testowych.

vvye
źródło
slicejest krótszy niż substr, nie jest dokładnie taki sam, ale w tym przypadku możesz go użyć
edc65
2

Groovy, 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()}

połączenie:

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

wydajność:

rock beats 
          s
s         c
t         i
a         s
e         s
b         o
          r
r         s
epap staeb 
Kamil Mikołajczyk
źródło
2

K, 55 54 bajtów

Stosując to samo podejście, co implementację J randomry; Zacznij od bloku spacji i dodaj od ogona sznurka do krawędzi, obracając cztery razy:

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

I kilka przykładów:

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

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

Trochę go rozbijając dla czytelności,

Wygeneruj blok NxM:

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

Obróć o 90 stopni za pomocą transpozycji ( +) i odwrotnie ( |:'):

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

Jeśli więc mamy blok spacji ti ciąg znaków s, możemy dołączyć kawałek ogona sdo t:

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

Używamy formularza, 4 {[x] ... }/( ... )aby wielokrotnie stosować funkcję do krotki składającej się z łańcucha i budowanej macierzy. Za każdym razem, gdy wykonujemy ten krok rotacji i konkatenacji, również odcinamy sznurek.

edytować:

Innym pomysłem jest próba podzielenia łańcucha wejściowego na fragmenty, które chcemy przy każdym obrocie, co upraszcza główną część programu. Niestety okazuje się, że jest nieco dłuższy przy 56 bajtach:

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

Jeśli istnieje lepszy sposób na obliczenie tych punktów podziału, jestem otwarty na sugestie.

edycja2:

Lekkie przestawienie pozwala mi usunąć parę nawiasów. 54 bajty!

f:{`0:((y-2)#" "){|:'(,y),+x}/(0,+\y[0 1 0]-2 1 1)_|x}
JohnE
źródło
2

K, 80 68 bajtów

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

Skrócono z 80 dzięki @JohnE.

Oryginalny:

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

Ledwo wiem, jak to działa.

Przykładowe użycie:

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

Istnieje kilka możliwych optymalizacji, ale ciągle robię Kona segfault ...

kirbyfan64sos
źródło
Można poprawić ten kawałek za pomocą „brać” (dwójkowym #) oraz listę argumentów wyraźny: f:{[s;y;n]`0:(,n#s),({s[(#s)-x+2],((n-2)#" "),s@n+x}'!y-2),,n#|-4!s}. 68 znaków według mojej liczby.
JohnE
@JohnE Thanks! Wiedziałem o wyraźnej liście argumentów, ale jakoś umykało mi to; Jednak nie miałem pojęcia o dyadic #.
kirbyfan64sos
2

R 178

Jest to nienazwana funkcja przyjmująca s, w, hjako parametry. Chciałbym, żeby był lepszy sposób na rozerwanie struny.

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='')}

Bez golfa

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

Testowe uruchomienie

> (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
> 
MickyT
źródło
2

T-SQL, 307

Choć wciąż strasznie długie, okazało się to o wiele łatwiejsze (i krótsze) niż myślałem w zapytaniu. Zaimplementowano jako funkcję cenioną w tabeli wbudowanej dla 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

Powtarza się to przez ciąg @h razy. Pierwsza rekurencja przycina znaki @W z ciągu. Środkowe rekurencje zajmują ostatnią i pierwszą pozostałą strunę z dopełnieniem struny pomiędzy. Ostatnia rekurencja odwraca to, co zostało. Istnieje kilka zagubionych znaków, które dotyczą sposobu, w jaki SQL Server traktuje końcowe spacje na VARCHARS.

Testowe uruchomienie

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)
MickyT
źródło
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])
knedlsepp
źródło
1

C ++, 398 bajtów

Używany kompilator - GCC 4.9.2 z -std=c++14flagą

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

Sprawdź to tutaj.

Wyjaśnienie

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

}
Anmol Singh Jaggi
źródło
Czy nie możesz zapisać znaków, używając char[][]zamiast tego?
corsiKa
Nie, vector<vector<char>> M;M.resize(h,vector<char>(w,0));jest nieco krótszy niżchar** M;M=new char*[h];while(i<h)M[i++]=new char[w]();
Anmol Singh Jaggi
1

Perl, 193 195 bajtów

($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";

Jestem pewien, że można to znacznie poprawić. Jestem nowicjuszem. >, <

Stephen Menton
źródło
0

Java 11, 180 bajtów

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

Wypróbuj online (UWAGA: String.repeat(int)jest emulowany jak repeat(String,int)dla tej samej liczby bajtów, ponieważ Java 11 nie jest jeszcze w TIO).

Wyjaśnienie:

(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
Kevin Cruijssen
źródło