Die Zeichen in der Zeichenfolge werden fortlaufend geändert


23

(Inspiriert von einem frühen Entwurf der fraktalen Linienherausforderung von PhiNotPi .)

Sie erhalten eine Breite W > 1, eine Höhe H > 1und eine Zeichenfolge, die aus 2(W+H-2)druckbaren ASCII-Zeichen besteht. Die Aufgabe besteht darin, diese Zeichenfolge, beginnend in der oberen linken Ecke, im Uhrzeigersinn um ein Rechteck mit der angegebenen Breite und Höhe zu drucken. Die Innenseite des Rechtecks ​​ist mit Leerzeichen gefüllt. Die Testfälle sollten dies hoffentlich sehr deutlich machen.

Sie können ein Programm oder eine Funktion schreiben, Eingaben über STDIN (oder die nächstgelegene Alternative), ein Befehlszeilenargument oder ein Funktionsargument vornehmen und das Ergebnis entweder an STDOUT (oder die nächstgelegene Alternative) ausgeben oder als Zeichenfolge zurückgeben.

Es dürfen keine führenden oder nachfolgenden Leerzeichen (außer denjenigen, die sich möglicherweise in der Eingabezeichenfolge befinden) vorhanden sein. Optional können Sie eine einzelne nachgestellte Newline ausgeben.

Dies ist Codegolf, daher gewinnt die kürzeste Übermittlung (in Bytes).

Testfälle

Auf jeden Testfall "String" W Hfolgt die erwartete Ausgabe.

"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

Bestenlisten

Hier ist ein Stapel Snippet sowohl eine regelmäßige Rangliste und einen Überblick über die Gewinner von Sprache zu erzeugen.

Um sicherzustellen, dass Ihre Antwort angezeigt wird, beginnen Sie Ihre Antwort mit einer Überschrift. Verwenden Sie dazu die folgende Markdown-Vorlage:

# Language Name, N bytes

Wo Nist die Größe Ihres Beitrags? Wenn Sie Ihren Score zu verbessern, Sie können alte Rechnungen in der Überschrift halten, indem man sich durch das Anschlagen. Zum Beispiel:

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


8
Deine Bestenlisten sind so cool.
Alex A.

2
Hast du dein Leaderboard-Skript golfen?
mbomb007

2
@ mbomb007 Nein, ich habe den Code über Minifier ausgeführt, sodass er beim Erweitern nicht viel Platz beansprucht. (Ich denke, Zeilenumbrüche zu entfernen wäre ausreichend gewesen.) Ich habe immer noch eine unbeschränkte Version auf meiner Festplatte.
Martin Ender

2
Wenn Sie dies in "Die Zeichen in der Zeichenfolge gehen rund und rund" umbenannt haben, passt es besser zum Rhythmus des Songs.
Justin

Antworten:


9

CJam, 27 Bytes

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

Ich habe nicht wirklich CJam, aber ich denke, das schlägt Martin. Der Hauptunterschied besteht darin, dass wir vor dem Lesen der Eingabe eine neue Zeile einfügen und die erste Zeile sofort ausgeben , ohne dass die Höhe gespeichert werden muss.

Übernimmt die Eingabe in der Reihenfolge

H "String" W

Probieren Sie es online aus.


10

Python 2, 95 Bytes

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]

Druckt die erste Zeile, dann die beiden vertikalen Zeilen und dann die letzte Zeile.

Es muss etwas kürzeres als printdreimaliges Schreiben geben , aber alles, was ich bisher mit dem Speichern in einer Variablen versucht '\n'.joinhabe, war länger.


Sie könnten zu Python 3 wechseln und den Ausdruck in einer Variablen speichern ...
Omar

1
@Omar Das wird länger, weil Sie evaldie print-Anweisungen für die Eingabe verwenden und in eckige Klammern setzen müssen.
FryAmTheEggman

Oh, das hatte ich nicht evalberücksichtigt! Die Klammer sollte kein allzu großes Problem sein, da printin Python 2 ein Leerzeichen danach benötigt wird. Beim Wechsel von print blahnach werden p(blah)noch 3 Zeichen gespeichert.
Omar,

9

CJam, 31 30 Bytes

Auf Optimizers Bestehen ist hier mein eigener Versuch. Ich bin kein Fan davon, meine eigenen Herausforderungen zu gewinnen, also zähle ich die APL-Familie (oder jemanden, der besser bei CJam ist), um dies zu übertreffen. ;)

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

Nimmt Eingaben in der gleichen Reihenfolge vor, wie in der Frage angegeben:

"Hello, World! " 5 4

Teste es hier.

Ein Byte gespart dank Optimizer.

Erläuterung

Ursprünglich hatte ich eine wirklich gute Idee, mit dem Rechteck der Räume zu beginnen und dann die Zeichenfolge buchstäblich darum zu wickeln, während ich das gesamte Gitter viermal drehte. Allerdings konnte ich das scheinbar nicht zum Laufen bringen, wenn Breite oder Höhe oder beides vorhanden waren 2. Also habe ich den naiven Ansatz ausprobiert (Druck oben, Schleife über den Seiten, Druck unten), und überraschenderweise stellte sich heraus, dass es wirklich kurz war.

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

Da wir die Länge der Zeichenfolge ermitteln können und V haben, muss H nicht gespeichert werden. Wiederholen Sie den Block, bis nur noch V-Zeichen übrig sind. l~;:V/(N@s{)V2-S*@(N@_,V-}gW%spart 1 Zeichen
DocMax,

@DocMax Leider funktioniert das bei Größe 2 nicht. Es ist jedoch eine gute Idee, zu prüfen, ob ich es irgendwie anders nutzen kann.
Martin Ender

D'oh! Sie haben sogar das H = 2-Problem erwähnt und ich habe immer noch vergessen, mich dagegen zu schützen.
DocMax,

9

Pyth, 47 46 45 40 37 36 Bytes

Dies ist der offensichtliche Ansatz, der in Pyth implementiert ist. Es druckt die erste Zeile durch Indizieren0:width und dann die Mitte und dann das Ende.

Danke an @Jakube für den Tipp mit using zund Qfür zwei Eingänge und using p.

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

Übernimmt die Eingabe von stdin als String und als Tupel von Dimensionen, durch Zeilenumbruch getrennt:

Hello, World! 
5, 4

und schreibt an stdout.

Probieren Sie es hier aus .

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

Das zLesen der Zeichenfolge spart eine Menge Zeichen. Ist auch t_Ndas selbe wie -_N1.
Jakube

37 Zeichen sind mit unserem Ansatz möglich.
Jakube,

@ Jakube danke für die Tipps!
Maltysen

Noch eine Char-Ersparnis. Anstatt zu ++benutzen pund das zt_Nmit umzuschalten *d-k2.
Jakube,

5

J, 61 Bytes

Methode:

Ausgehend von einem (height-2)*(width-2)Leerzeichenblock nehmen wir die erforderliche Anzahl von Zeichen vom Ende der Zeichenfolge und fügen sie dem aktuellen Block hinzu. Wir wiederholen dies 4 mal. Die insgesamt 5 mit dem 'Hello, World! ' 5 4Beispiel veranschaulichten Zustände (Leerzeichen werden Xaus Gründen der Lesbarkeit durch s ersetzt ):

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

Der Code:

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

Explizite Funktionsdefinition. Die Zwei-Operanden-Funktion verwendet eine Zeichenfolge als linkes Argument und eine Liste mit zwei Ganzzahlen als rechtes Argument.

Anwendungsbeispiel:

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

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

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

Probieren Sie es hier online aus.


Wow, ich bin beeindruckt, dass dies für Breite und Höhe 2 in J.
Martin Ender

4

Pyth, 38 37

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

Ich hatte ursprünglich eine andere 38-Lösung, aber es war im Grunde eine Golf-Lösung von Malcesens Antwort. Also habe ich beschlossen, ein bisschen anders zu gehen.

Probieren Sie es online aus .

              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_ttHist äquivalent zu <_zttH.
Isaacg

@isaacg Danke, schon mal was ähnliches in Maltysens Antwort gesehen.
Jakube,

4

JavaScript (ES6), 110 115

Funktion mit 3 Parametern, die einen String zurückliefern

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- Version 119 : Kein Kurzformat für Funktionen, keine Standardparameter. Kein Grund zu benutzenfor(of) auch wenn es unterstützt wird

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 Version 126 : nein für (von), kein 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
}

Ungolfed

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

Prüfung In der Firefox / FireBug-Konsole

;[["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)))

Ausgabe

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 Bytes

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]

Auf direktem Weg.


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

Die Funktion pdruckt die Ausgabe nicht aus, sondern gibt sie als String zurück, zB p 4 5 "+--+|||+--+|||"-> "+--+\n| |\n| |\n| |\n+--+\n". Zur besseren Darstellung verwenden Sie putStr:

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

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

So funktioniert es: Ich erstelle einen wx- hBlock mit Leerzeichen und ersetze die erste Zeile durch den Anfang der Eingabezeichenfolge. Dann drehe ich den Block gegen den Uhrzeigersinn und wiederhole das Ersetzen der ersten Zeile noch dreimal.

Um zu verhindern, dass das erste Zeichen nach Runde 4 erneut abgeschnitten wird, hänge ich es vor dem Start an die Eingabezeichenfolge an.

"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

Bearbeiten: Es wurde ein besserer Weg gefunden, das Problem mit dem Cut-Off-First-Character-After-Turn- # 4 zu lösen.


Ah nice ... das ist ähnlich wie das, was ich in CJam ausprobiert habe, außer es funktioniert. ;)
Martin Ender

3

Postscript, 62 Bytes

Dies verwendet natürlich binäre Token, aber es ist äquivalent zu:

/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

Hier ist ein Hexdump der Datei ( 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}..]..

Rennen wie:

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

Die Ausgabe ist sehr klein (da die Schrift überhaupt nicht skaliert wird), Sie müssen also ein gutes Stück zoomen, um sie zu sehen.

Dadurch kann der xyshowOperator die Zeichenfolge mit benutzerdefinierten Zeichenabständen ausschreiben. In diesem Fall benutze ich den negativen vertikalen Abstand zum Aufschreiben, dann den negativen horizontalen Abstand zum Zurückschreiben und dann den positiven vertikalen Abstand zum Aufschreiben. Aus diesem Grund muss ich keine Zeichenfolgenmanipulation verwenden.


3

> <>, 82 80 + 3 = 83 Bytes

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

Esolang Seite für> <> (Fisch)

Dies stellte sich als kürzer heraus als ich erwartet hatte. Es verwendet den einfachen Ansatz, die erste Zeile, dann die mit den zentralen Leerzeichen aufgefüllten Spalten und dann die letzte Zeile zu drucken.

Geben Sie den String über STDIN und die Höhe und Breite über die Befehlszeile mit dem -vFlag ein, wie folgt :

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

Erläuterung

: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

Ein Shell-Skript für den Einstieg:

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

Übergeben Sie die Eingabe als Befehlszeilenargumente:

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

2

JavaScript, 161 160 158 Bytes

Die Methode, die ich mir ausgedacht habe, hat sich als viel zu lang herausgestellt, aber na ja, es war Übung. (Auch habe ich es zu buchstabieren 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}

Bei Eingaben, die keinen Sinn ergeben, ist die Ausgabe undefiniert (buchstäblich und einige Male), funktioniert jedoch für alle Testfälle.


sliceist kürzer als substr, es ist nicht genau das gleiche, aber in diesem Fall können Sie es verwenden
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()}

Anruf:

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

Ausgabe:

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

2

K, 55 54 Bytes

Verwenden des gleichen Ansatzes wie die J-Implementierung von randomra; Beginnen Sie mit einem Leerzeichenblock und fügen Sie vom Ende der Zeichenfolge bis zur Kante hinzu, während Sie viermal drehen:

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

Und einige Beispiele:

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

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

Bringen Sie es ein wenig für die Lesbarkeit,

Generiere einen NxM Block:

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

Mit transponieren ( +) und jeweils umkehren ( |:') um 90 Grad drehen :

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

Wenn wir also einen Block von Räumen haben tund einen String s, können wir ein Stück des Schwanzes von prepend szu t:

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

Wir verwenden das Formular, 4 {[x] ... }/( ... )um wiederholt eine Funktion auf ein Tupel anzuwenden, das aus der Zeichenfolge und der Matrix besteht, die wir erstellen. Jedes Mal, wenn wir diesen Rotations- und Verkettungsschritt ausführen, schneiden wir auch die Zeichenfolge ab.

bearbeiten:

Eine andere Idee ist es, die Eingabezeichenfolge bei jeder Drehung in die gewünschten Fragmente aufzuteilen, was den Hauptteil des Programms vereinfacht. Leider ist dies bei 56 Bytes etwas länger:

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

Wenn es einen besseren Weg gibt, diese Split-Punkte zu berechnen, bin ich offen für Vorschläge.

edit2:

Durch leichtes Umordnen entferne ich ein Paar Klammern. 54 Bytes!

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

2

K, 80 68 Bytes

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

Verkürzt von 80 dank @JohnE.

Original:

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

Ich weiß kaum, wie das Ding funktioniert.

Anwendungsbeispiel:

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

Es gibt einige mögliche Optimierungen, aber ich mache immer wieder Kona segfault ...


Sie können mit ‚Take‘ (Dyade #) und eine explizite Argumentliste dieses ein wenig verbessern: f:{[s;y;n]`0:(,n#s),({s[(#s)-x+2],((n-2)#" "),s@n+x}'!y-2),,n#|-4!s}. 68 Zeichen nach meiner Zählung.
JohnE

@ JohnE Danke! Ich wusste von der expliziten Liste der Argumente, aber irgendwie war mir das nicht klar. Ich hatte allerdings keine Ahnung von dyadic #.
kirbyfan64sos

2

R 178

Dies ist eine unbenannte Funktion, die s, w, hals Parameter verwendet wird. Ich wünschte, es gäbe eine schönere Möglichkeit, die Saite zu teilen.

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

Ungolfed

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

Testlauf

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

Dies war zwar immer noch schrecklich lang, stellte sich jedoch als viel einfacher (und kürzer) heraus, als ich in einer Abfrage dachte. Implementiert als Inline-Tabellenwertfunktion für 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

Dies wiederholt sich durch die Zeichenfolge @h mal. Die erste Rekursion schneidet @W Zeichen aus der Zeichenfolge aus. Die mittleren Rekursionen nehmen die letzte und die erste verbleibende Zeichenfolge mit einem Zeichenfolgenabstand dazwischen. Die letzte Rekursion kehrt das Verbleibende um. Es gibt ein paar verlorene Zeichen, die sich mit der Art und Weise befassen, wie SQL Server nachgestellte Leerzeichen in VARCHARS behandelt.

Testlauf

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 Bytes

Compiler verwendet - GCC 4.9.2 mit -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;}}

Teste es hier.

Erläuterung

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

}

Könnten Sie nicht Zeichen speichern, indem Sie char[][]stattdessen verwenden?
corsiKa

Nein, vector<vector<char>> M;M.resize(h,vector<char>(w,0));ist etwas kürzer alschar** M;M=new char*[h];while(i<h)M[i++]=new char[w]();
Anmol Singh Jaggi

1

Perl, 193 195 Bytes

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

Ich bin sicher, dass dies stark verbessert werden kann. Ich bin ein Anfänger. >, <


0

Java 11, 180 Bytes

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

Probieren Sie es online aus (HINWEIS: String.repeat(int)wird emuliert alsrepeat(String,int) für die gleiche Anzahl von Bytes , da Java 11 noch nicht auf TIO läuft.)

Erläuterung:

(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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.