Karakter dalam String Berputar-putar


23

(Terinspirasi oleh konsep awal tantangan fraktal garis PhiNotPi .)

Anda diberi lebar W > 1, tinggi, H > 1dan string yang terdiri dari 2(W+H-2)karakter ASCII yang dapat dicetak. Tugasnya adalah untuk mencetak tali ini melilit persegi panjang dengan lebar dan tinggi yang diberikan, mulai dari sudut kiri atas, dalam arti searah jarum jam. Bagian dalam persegi panjang diisi dengan spasi. Kasus-kasus pengujian diharapkan membuat ini sangat jelas.

Anda dapat menulis sebuah program atau fungsi, mengambil input melalui STDIN (atau alternatif terdekat), argumen baris perintah atau argumen fungsi, dan mencetak hasilnya ke STDOUT (atau alternatif terdekat) atau mengembalikannya sebagai string.

Tidak boleh ada spasi awal atau akhir (selain dari yang mungkin ada dalam string input). Anda secara opsional dapat menampilkan satu baris baru.

Ini adalah kode golf, jadi pengiriman terpendek (dalam byte) menang.

Uji Kasus

Setiap test case "String" W Hdiikuti oleh output yang diharapkan.

"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

Papan peringkat

Berikut ini adalah Stack Snippet untuk menghasilkan leaderboard biasa dan gambaran umum pemenang berdasarkan bahasa.

Untuk memastikan bahwa jawaban Anda muncul, silakan mulai jawaban Anda dengan tajuk utama, menggunakan templat Penurunan harga berikut:

# Language Name, N bytes

di mana Nukuran kiriman Anda. Jika Anda meningkatkan skor Anda, Anda bisa menyimpan skor lama di headline, dengan mencoretnya. Contohnya:

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


8
Leaderboards Anda begitu dingin.
Alex A.

2
Apakah Anda golf naskah leaderboard Anda?
mbomb007

2
@ mbomb007 Tidak, saya menjalankan kode melalui minifiers, jadi tidak akan memakan banyak ruang saat diperluas. (Saya kira menghapus jeda baris sudah cukup.) Saya masih punya versi yang tidak dimodifikasi pada hard drive saya.
Martin Ender

2
Jika Anda menamainya dengan "The Chars in the String Go Round and Round", itu lebih cocok dengan irama lagu.
Justin

Jawaban:


9

CJam, 27 byte

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

Saya tidak benar-benar CJam, tapi saya pikir ini mengalahkan Martin. Perbedaan utama adalah bahwa kami mendorong baris baru sebelum membaca input dan segera mencetak baris pertama, meniadakan kebutuhan untuk menyimpan ketinggian.

Mengambil input dalam urutan

H "String" W

Cobalah online.


10

Python 2, 95 byte

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]

Mencetak baris pertama, lalu dua garis vertikal, lalu baris terakhir.

Pasti ada sesuatu yang lebih pendek daripada menulis printtiga kali, tetapi semua yang saya coba sejauh ini dengan menyimpan ke variabel dan '\n'.jointelah lebih lama.


Anda dapat beralih ke Python 3 dan menyimpan hasil cetak dalam variabel ...
Omar

1
@ Umur Itu akhirnya menjadi lebih lama karena Anda harus menggunakan evalpada input dan kurung pernyataan cetak.
FryAmTheEggman

Oh, saya belum evalmemperhitungkan! Tanda kurung seharusnya tidak terlalu menjadi masalah karena printdalam Python 2 membutuhkan ruang setelahnya. Pergi dari print blahke p(blah)masih menyimpan 3 karakter.
Omar

9

CJam, 31 30 byte

Atas desakan Pengoptimal, inilah usaha saya sendiri. Saya bukan penggemar memenangkan tantangan saya sendiri, jadi saya menghitung keluarga APL (atau seseorang yang lebih baik di CJam) untuk mengalahkan ini. ;)

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

Mengambil input dalam urutan yang sama seperti yang diberikan dalam pertanyaan:

"Hello, World! " 5 4

Uji di sini.

Satu byte disimpan berkat Pengoptimal.

Penjelasan

Awalnya, saya punya ide yang bagus untuk memulai dengan persegi panjang spasi dan kemudian benar-benar melilitkan tali di sekitarnya sambil memutar seluruh grid empat kali. Namun, saya sepertinya tidak bisa menggunakannya jika ada lebar atau tinggi atau keduanya 2. Jadi saya mencoba pendekatan naif (print top, loop over sides, print bottom), dan ternyata ternyata sangat pendek.

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.";

Karena kita bisa mendapatkan panjang string dan kita memiliki V, tidak perlu menyimpan H. Cukup ulangi blok sampai hanya karakter V yang tersisa. l~;:V/(N@s{)V2-S*@(N@_,V-}gW%menghemat 1 char.
DocMax

@ DocMax Sayangnya, itu tidak bekerja untuk ketinggian 2. Ini ide yang bagus, saya akan melihat apakah saya bisa memanfaatkannya dengan cara yang berbeda.
Martin Ender

Doh! Anda bahkan menyebutkan masalah H = 2 dan saya masih lupa untuk mencegahnya.
DocMax

9

Pyth, 47 46 45 40 37 36 byte

Ini adalah pendekatan yang jelas diimplementasikan di Pyth. Ini mencetak baris pertama dengan mengindeks 0:widthdan kemudian tengah, lalu akhir.

Terima kasih kepada @Jakube untuk tip dengan menggunakan zdan Quntuk dua input dan menggunakan p.

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

Mengambil input dari stdin sebagai string dan sebagai tuple dimensi, baris baru dipisahkan:

Hello, World! 
5, 4

dan menulis ke stdout.

Coba di sini .

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

Menggunakan zuntuk membaca string menghemat cukup banyak karakter. Juga t_Nhal yang sama -_N1.
Jakube

37 karakter dimungkinkan dengan pendekatan kami.
Jakube

@ Jakube terima kasih atas tipsnya!
Maltysen

Satu lagi char saving. Alih-alih ++menggunakan pdan beralih zt_Ndengan *d-k2.
Jakube

5

J, 61 byte

Metode:

Mulai dari (height-2)*(width-2)blok ruang, kami mengambil jumlah karakter yang diperlukan dari akhir string dan menambahkannya ke blok saat ini. Kami ulangi ini 4 kali. Total 5 negara diilustrasikan dengan 'Hello, World! ' 5 4contoh (spasi diganti dengan Xs untuk keterbacaan):

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

Kode:

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

Definisi fungsi eksplisit. Fungsi dua-operan mengambil string sebagai argumen kiri dan daftar dua bilangan bulat sebagai argumen benar.

Contoh penggunaan:

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

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

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

Cobalah online di sini.


Wow, saya terkesan bahwa ini bekerja untuk lebar dan tinggi 2 di J.
Martin Ender

4

Pyth, 38 37

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

Awalnya saya punya solusi yang berbeda, tetapi pada dasarnya solusi golf jawaban Maltysen. Jadi saya memutuskan untuk sedikit berbeda.

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

_>z_ttHsetara dengan <_zttH.
isaacg

@isaacg Terima kasih, sudah melihat sesuatu yang mirip dalam jawaban Maltysen.
Jakube

4

JavaScript (ES6), 110 115

Berfungsi dengan 3 parameter, mengembalikan string

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 versi 119 : tidak ada format pendek untuk fungsi, tidak ada parameter default. Tidak ada alasan untuk menggunakan for(of)bahkan jika itu didukung

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 versi 126 : no for (of), no 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
}

Tidak disatukan

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

Uji di Firefox / konsol 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)))

Keluaran

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 byte

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]

Mengambil pendekatan langsung.


3

Haskell, 164 156 bytes

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

Fungsi ptidak mencetak output, tetapi mengembalikannya sebagai string, misalnya p 4 5 "+--+|||+--+|||"-> "+--+\n| |\n| |\n| |\n+--+\n". Untuk penggunaan layar yang lebih baik putStr:

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

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

Cara kerjanya: Saya membuat blok wx hspasi dan mengganti baris pertama dengan awal string input. Lalu saya memutar blok berlawanan arah jarum jam dan mengulangi mengganti baris pertama tiga kali.

Untuk mencegah pemotongan karakter pertama lagi setelah giliran # 4, saya menambahkannya ke string input sebelum memulai.

"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

Sunting: menemukan cara yang lebih baik untuk menyelesaikan masalah cut-off-first-character-after-turn-# 4.


Ah bagus ... ini mirip dengan apa yang saya coba di CJam, kecuali itu berfungsi. ;)
Martin Ender

3

Catatan tambahan, 62 byte

Ini tentu saja menggunakan token biner, tetapi ini setara dengan:

/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

Berikut ini adalah hexdump dari file ( 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}..]..

Jalankan sebagai:

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

Outputnya sangat kecil (karena tidak menskalakan font sama sekali), jadi Anda perlu memperbesar sedikit untuk melihatnya.

Ini mengambil keuntungan dari xyshowoperator untuk menulis string menggunakan spasi karakter khusus. Dalam hal ini, saya menggunakan spasi vertikal negatif untuk menulis, kemudian ruang horizontal negatif untuk menulis mundur, kemudian ruang vertikal positif untuk menulis ke atas. Karena itu, saya tidak perlu menggunakan manipulasi string apa pun.


3

> <>, 82 80 + 3 = 83 byte

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

Halaman Esolang untuk> <> (Ikan)

Ini ternyata lebih pendek dari yang saya harapkan. Ia menggunakan pendekatan langsung untuk mencetak baris pertama, lalu kolom-kolom yang diisi dengan spasi pusat, lalu baris terakhir.

Masukkan string melalui STDIN dan tinggi dan lebar melalui baris perintah dengan -vbendera, seperti:

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

Penjelasan

: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

Skrip shell untuk memulai:

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

Masukan input sebagai argumen baris perintah:

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

2

JavaScript, 161 160 158 byte

Metode yang saya hasilkan ternyata terlalu lama, tapi oh well, sudah praktik. (Juga, aku harus mengejanya 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}

Untuk input yang tidak masuk akal outputnya tidak terdefinisi (secara harfiah, dan beberapa kali), tetapi berfungsi untuk semua kasus uji.


slicelebih pendek daripada substr, itu tidak persis sama tetapi dalam kasus ini Anda dapat menggunakannya
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()}

panggilan:

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

keluaran:

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

2

K, 55 54 byte

Menggunakan pendekatan yang sama dengan implementasi J randomra; Mulailah dengan blok ruang dan tambahkan dari ujung tali ke tepi sambil berputar empat kali:

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

Dan beberapa contoh:

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

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

Memecahnya sedikit untuk dibaca,

Hasilkan blok NxM:

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

Putar 90 derajat dengan menggunakan transpose ( +) dan mundur-masing-masing ( |:'):

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

Jadi jika kita memiliki blok spasi tdan string s, kita dapat menambahkan sepotong ekor ske t:

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

Kami menggunakan formulir 4 {[x] ... }/( ... )untuk berulang kali menerapkan fungsi ke tuple yang terdiri dari string dan matriks yang kami bangun. Setiap kali kita melakukan langkah rotate-and-concatenate ini, kita juga memotong string.

edit:

Gagasan lain adalah mencoba memisahkan string input ke dalam fragmen yang kita inginkan pada setiap rotasi, yang menyederhanakan bagian utama program. Sayangnya ini berhasil menjadi sedikit lebih lama pada 56 byte:

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

Jika ada cara yang lebih baik untuk menghitung titik-titik perpecahan itu saya terbuka untuk saran.

edit2:

Mengatur ulang sedikit memungkinkan saya menghapus sepasang tanda kurung. 54 byte!

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

2

K, 80 68 byte

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

Dipersingkat dari 80 berkat @JohnE.

Asli:

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

Aku bahkan tidak tahu bagaimana ini bekerja.

Contoh penggunaan:

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

Ada beberapa kemungkinan optimasi, tapi saya terus membuat Kona segfault ...


Anda dapat memperbaiki ini sedikit dengan menggunakan 'mengambil' (diad #) dan daftar argumen eksplisit: f:{[s;y;n]`0:(,n#s),({s[(#s)-x+2],((n-2)#" "),s@n+x}'!y-2),,n#|-4!s}. 68 karakter menurut hitungan saya.
JohnE

@ JohnE Terima kasih! Saya tahu tentang daftar argumen eksplisit, tetapi entah bagaimana terlintas di benak saya; Saya tidak tahu tentang diad #.
kirbyfan64sos

2

R, 178

Ini adalah fungsi yang tidak disebutkan namanya s, w, hsebagai parameter. Saya berharap ada cara yang lebih baik untuk memisahkan tali.

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

Tidak disatukan

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

Uji coba

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

Meskipun masih sangat panjang, ini ternyata sedikit lebih mudah (dan lebih pendek) daripada yang saya pikirkan dalam sebuah query. Diimplementasikan sebagai fungsi bernilai tabel inline untuk 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

Ini berulang melalui string @ h kali. Rekursi pertama klip karakter @W dari string. Rekursi tengah mengambil yang terakhir dan yang pertama dari string yang tersisa dengan tali di antaranya. Rekursi terakhir membalikkan apa yang tersisa. Ada beberapa karakter yang hilang berurusan dengan cara SQL Server memperlakukan spasi tambahan di VARCHARS.

Uji Coba

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 byte

Kompiler yang digunakan - GCC 4.9.2 dengan -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;}}

Uji di sini.

Penjelasan

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

}

Tidak bisakah Anda menyimpan karakter dengan menggunakan char[][]saja?
corsiKa

Tidak, vector<vector<char>> M;M.resize(h,vector<char>(w,0));sedikit lebih pendek darichar** M;M=new char*[h];while(i<h)M[i++]=new char[w]();
Anmol Singh Jaggi

1

Perl, 193 195 byte

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

Saya yakin ini bisa sangat ditingkatkan. Saya seorang noob. >, <


0

Java 11, 180 byte

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

Cobalah secara online (CATATAN: String.repeat(int)diemulasikan repeat(String,int)untuk byte-count yang sama, karena Java 11 belum menggunakan TIO.)

Penjelasan:

(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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.