Rechteck aus Text

13

Ihr Programm erhält einen Text als Eingabe, der mindestens 8 Zeichen lang ist und immer aus einer geraden Anzahl von Zeichen besteht. (keine Notwendigkeit, die Richtigkeit der Eingabe zu bewerten).

Ihr Ziel ist es, diesen Text als Rechteck anzuzeigen. Wird beispielsweise HelloWorldals Eingabe angegeben, wird angezeigt

Hell
d  o
lroW

Regeln:

  • Text dreht sich im Uhrzeigersinn (Startposition nach Belieben)
  • Es wird ein geschlossenes Rechteck mit einer Seitenbreite von 1 Zeichen gebildet.
  • Das Rechteck muss den größten Bereich innerhalb des Rechtecks ​​umfassen. (nur um die triviale Antwort auszuschließen, dass der Text in zwei Zeilen angezeigt wird)
  • Außer dem Text selbst und den erforderlichen Leerzeichen und Zeilenumbrüchen werden keine weiteren Zeichen gedruckt.

Als Code-Golf gewinnt der kürzeste Code.

Der Gewinner wird frühestens 10 Tage nach der ersten gültigen Antwort ausgewählt.

vsz
quelle

Antworten:

5

GolfScript, 56 53 40 38 Zeichen

1/..,4/):l<n@l>{)" "l*2>@(n@.,l-}do-1%

Sie können das Skript online testen .

Howard
quelle
7

PostScript 50 binär, 113 ASCII

Dies verwendet eine grafische Ausgabe. Hexdump des Programms mit Binärtoken:

$ hexdump -C textRect_binary.ps 
00000000  74 5b 30 20 39 5b 74 92  62 34 92 36 92 38 92 10  |t[0 9[t.b4.6.8..|
00000010  32 92 19 5d 7b 92 2c 7b  32 92 19 7d 92 83 92 3e  |2..]{.,{2..}...>|
00000020  92 6e 7d 92 49 5d 39 20  39 92 6b 91 c7 39 92 8e  |.n}.I]9 9.k..9..|
00000030  92 c3                                             |..|
00000032

Laden Sie es herunter, um es zu testen . Mit Ghostscript kann der zu rendernde Text wie folgt an das Programm übergeben werden:

gs -st=helloworld textRect_binary.ps 

Die grafische Ausgabe sieht folgendermaßen aus:

gerenderte Ausgabe

Derselbe Code, der ASCII-Token verwendet, sieht folgendermaßen aus:

t[0 9[t length
4 div dup
ceiling
2 copy]{cvi{2 copy}repeat
exch neg}forall]9 9 moveto/Courier 9 selectfont
xyshow

Die Strategie besteht darin, xyshowzu definieren, wohin wir uns bewegen, nachdem wir jedes Zeichen gezeigt haben, bevor wir das nächste Zeichen zeigen. Wir beginnen in der unteren linken Ecke und bewegen uns im Uhrzeigersinn, dh zuerst nach oben, dann nach rechts, dann nach unten und dann nach links. Wir bewegen uns immer 9 Einheiten, so erste haben wir eine Relativbewegung 0 9, dann 9 0, dann 0 -9, dann -9 0. Mit der Sequenz können wir von einem Paar dieser Zahlen zum nächsten gelangen exch neg.

Wir müssen ein Array erstellen xyshow, das diese Zahlenpaare enthält, ein Paar für jedes Zeichen. Das heißt, wenn wir helloworldals Beispiel einen String haben, der 10 Zeichen hat, wollen wir zweimal nach oben, dann dreimal nach rechts, dann zweimal nach unten und dreimal nach links. Wir erhalten diese Werte (zwei und drei), indem wir die Stringlänge durch 8 dividieren, einmal auf den Boden gerundet, einmal an die Decke.

Also kopieren wir 0 9zweimal und wechseln dann mit zu den relativen x / y-Koordinaten exch neg, kopieren diese dreimal und so weiter.

Dieser kommentierte Code zeigt, was auf dem Stapel passiert:

t[0 9                % t [ 0 9
[t length            % t [ 0 9 [ length
4 div dup            % t [ 0 9 [ length/4 length/4
ceiling              % t [ 0 9 [ length/4=height width
2 copy]              % t [ 0 9 [height width height width]
{%forall             % t [ 0 9 ... x y height_or_width
  cvi                % t [ 0 9 ... x y height_or_width_integer
  {2 copy}           % t [ 0 9 ... x y height_or_width_integer {2 copy}
  repeat             % t [ 0 9 ... x y .. x y
  exch neg           % t [ 0 9 ... x y .. y -x
}forall]             % t [0 9 ... -9 0]
9 9 moveto/Courier 9 selectfont
xyshow
Thomas W.
quelle
+1 Heiliger Bajeezus. Ich habe ernsthafte Mängel in meinen Kenntnissen der Stufe 2 und darüber hinaus.
Luser Droog
Du meinst xyshow? Gerne stellst du dir dieses hier vor - vor einiger Zeit hast du mich vorgestellt kshow, was mir nicht wirklich bewusst war ;-).
Thomas W.
@luserdroog: Übrigens: Ich bin ziemlich stolz darauf, dass der aktuelle GolfScript-Eintrag mehr als 10% mehr Zeichen enthält als mein Binäreintrag, aber es stört mich, dass meine ASCII-Version ein Zeichen von Ruby entfernt ist (tatsächlich sogar drei, weil der Ruby-Code weiter golfen werden könnte). Haben Sie Ideen zur weiteren Optimierung?
Thomas W.
@ThomasW. Jetzt ist mein GolfScript-Eintrag 24% kürzer als Ihr Binary ;-) Und ich denke immer noch, dass es noch möglich ist, ihn um ein oder zwei Zeichen weiter zu verkürzen.
Howard
@ Howard: Argh !!! Kann jemand jemals GolfScript schlagen?
Thomas W.
7

Ruby 112 100

Ich bin neu in Ruby und dies ist mein erster Code Golf. Ich habe mich an Memowes Perl-Implementierung orientiert und versucht, eine Ruby-Version davon zu erstellen. Dies ist 112 100 Zeichen und setzt voraus, dass Sie x eine Zeichenfolge zuweisen. Ich freue mich darauf, andere zu sehen.

l=x.size
puts x[0..w=l/2-h=l/4]
1.upto(h-1){|i|puts x[-i]+' '*(w-1)+x[w+i]}
puts x[w+h..l-h].reverse

Bearbeitet, um Vorschläge umzusetzen. Ich denke, es sind jetzt 100 Zeichen. Danke Leute!

jzig
quelle
Nett! Sie können zwei Zeichen in der 5. Zeile speichern (Leerzeichen entfernen).
Thomas W.
Ich mag das. Vielen Dank. Sieht gut aus, dass auf Ruby-Strings wie auf ein Array zugegriffen werden kann, ich musste eins selbst bauen. :)
memowe
Du könntest ersetzen x.lengthdurch x.size(Speichert 2 Zeichen)
knut
1
Und 8 weitere mit puts x[0..w=l/2-h=l/4].
Howard
5

Perl (124 118 109 + 3 = 112)

Das war früher ziemlich einfach. Zählte alle Befehlszeilenoptionen als jeweils 1 Zeichen.

-nlE
$w=(@s=split//)/2-($h=int@s/4);say@s[0..$w--];say$s[1-$_].$"x$w.$s[$w+$_]for+2..$h;say+reverse@s[@s/2..@s-$h]

Beispiel:

$ perl -nlE '$w=(@s=split//)/2-($h=int@s/4);say@s[0..$w--];say$s[1-$_].$"x$w.$s[$w+$_]for+2..$h;say+reverse@s[@s/2..@s-$h]'
abcdefghijklmnopqrstuvwxyz
abcdefgh
z      i
y      j
x      k
w      l
v      m
utsrqpon
memowe
quelle
Dies kann komprimiert werden: (1) (@s-$h*2)/2 == @s/2-$h(2) $wkann als dargestellt werden $w=(@s=split//)/2-($h=int@s/4);, wodurch zwei Semikolons
gespeichert werden
Der Code wurde aktualisiert.
Memowe
Weitere interessante Dinge: (1) Das Leerzeichen ist der Standardwert der Array-Interpolation var $"–saves 1 char. (2) - $w+$h == @s/2Speichert 1 Zeichen. (3) Wenn $wum eins kleiner ist, können wir vereinfachen $"x($w-1). Dafür muss der $_Wert um 1 erhöht werden. Speichert wie 3 Zeichen. (4) Das abschließende Semikolon ist überflüssig, spart 1 Zeichen. Dies führt zu dem Codefragment say@s[0..$w--];say$s[1-$_].$"x$w.$s[$w+$_]for+2..$h;say+reverse@s[@s/2..@s-$h](mit ein paar +zum Spaß, so dass kein einziges Leerzeichen übrig bleibt).
amon
Hervorragende Golf-Qualifikation, @amon, würdest du es bitte in meinem Beitrag bearbeiten? Auf diese Weise kann die Welt sehen, wer es getan hat. :)
memowe
5

Brainfuck - 194 187

+>,[>+[>+<-],]
>-->++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>[-]>[-]>[<<+<<+>>>>-]<<<<
[[<]>+[>]<-]<[<]>-
[>.[-]<[>+<-]>-]>[>]
++++++++++.<.[-]
>[>+++>>+<<<-]>++>--[<.>-]<<<<[<]>.[-]>[>]>>>>.
<<<<<[.<]
captncraig
quelle
Netter Versuch, aber es klappt nicht. Die unterste Zeile ist entgegen Regel 1 in die falsche Richtung und hat entgegen Regel 3 nur eine feste Höhe.
vsz
Ich bin mir nicht sicher, warum ich die letzte Reihe umgedreht habe. Ich habe es mir genau so überlegt, wie ich es geschrieben habe. Das Update speichert tatsächlich 7 Befehle. Ich habe die Sache mit der festen Höhe ausgemerzt, aber es ist nicht der triviale 2-Zeilen-Fall, über den Sie gesprochen haben. Vielleicht werde ich es in Zukunft besser machen.
Captncraig
4

Mathematica 156 199 344

Bearbeiten : Dies ist eine umfangreiche Neufassung des früheren Codes. Es funktioniert im Wesentlichen genauso, nimmt jedoch als Eingabe eine Zeichenfolge mit einer Länge von <120 Zeichen und passt die Größe des Quadrats automatisch an.

Es könnte noch ein bisschen Golf gespielt werden, wird aber nicht die Größe der früheren und fehlerhafteren Versionen erreichen.

f@s_ := ({a, t, w, q} = {Automatic, Text, Quotient[StringLength@s, 2],
 Quotient[StringLength[s], 4] + 1};z = StringSplit[StringInsert[s <> ConstantArray[" ", 0],
 "*", {q, 2 q, 3 q}], "*"];
Graphics[{t[z[[1]], {0, q}],t[z[[2]], {q, 0}, a, {0, -1}],t[z[[3]], {0, -q}, a, {-1, 0}],
t[z[[4]], {-q, 0}, a, {0, 1}]},ImageSize -> 500,BaseStyle -> {FontFamily -> "Courier", 21},
PlotRange -> 34,ImagePadding -> 22])

Beispiele

f["Hello Code Golf World!"]
f["January, February, March,April, May, June, July"]
f["This text is normal, this goes downwards,this is upside-down, and this is upwards"]

pic1

pic2

pic3

DavidC
quelle
Hey, eine Reihe von Streichern? Das verstößt wirklich gegen die Regeln, oder?
Thomas W.
@ThomasW. Die Kommentare in der Antwort zeigen an, dass es keine endgültige Lösung ist.
Kojiro
Ah ich sehe! Ich frage mich, ob ich die Herausforderung annehmen und etwas Ähnliches in PostScript ausprobieren soll ...
Thomas W.
Ich mag, wie es jetzt aussieht!
Thomas W.
@ Thomas W. Danke. Das richtige Format für einen großen Bereich von Zeichenfolgenlängen zu erhalten, kostet viele Bytes.
DavidC
2

Perl + Regexes: 104 (101 + 3)

(Zählcode + Schalter)

Hier ist eine Lösung mit netten Regexes und ein bisschen Perl:

perl -plE'$w=($l=length)/2-($h=int$l/4);s/..{$w}\K.*/"\n".reverse$&/e;$"x=--$w;s/.\K(.*)(.)$/$"$2\n$1/while--$h'

Dies funktioniert nur auf einer Eingangsleitung korrekt .

Inspiriert von memowe, aber im Wesentlichen ohne Arrays.

amon
quelle
Sorry für die blöde Frage: Wie kann ich das ausprobieren? Ich füge deinen Code in die Befehlszeile ein, tippe dann etwas ein, drücke die Eingabetaste und etwas kommt heraus. Aber es ist keine Schachtel. Was mache ich falsch?
Thomas W.
@ThomasW. Es scheint für mich zu funktionieren, für eine beliebige gerade Anzahl von Zeichen. Der obige Code funktioniert garantiert unter Bash und Perl Version 5.12+. Die Eingabe wird über STDIN akzeptiert und nur die erste Zeile wird korrekt verarbeitet. Ich kann den Code für cmd.exe nicht richtig zitieren.
amon
1
Ah, war wahrscheinlich mein Fehler. Ich habe wahrscheinlich eine Saite von ungerader Länge verwendet. Dies funktioniert:echo thisworksgreat | perl -plE'$w=($l=length)/2-($h=int$l/4);s/..{$w}\K.*/"\n".reverse$&/e;$"x=--$w;s/.\K(.*)(.)$/$"$2\n$1/while--$h'
Thomas W.
2

PostScript (106)

Dies ist inspiriert von der Mathematica-Lösung von Dude .

0{= =
4 add dup
t length mod 4
lt{-90 rotate}if}0[0 3 -3 0 9 9]concat
0 moveto/Courier 5 selectfont
t kshow

Bei Ghostscript nennt man das so

gs -st=hello! boxtext.ps

Es erzeugt eine Ausgabe wie.

Hallo_Code_Golf_Welt!

Januar Februar März April Mai Juni Juli

Hiermit kshowwerden die Glyphen einzeln angezeigt. Nachdem genügend Glyphen für eine Seite angezeigt wurden, wird alles um -90 Grad gedreht, bevor mit den verbleibenden Glyphen fortgefahren wird.

Um zu wissen, wann genügend Glyphen auf der Seite angezeigt wurden, erhöhen wir jedes Mal, wenn eine Glyphe angezeigt wird, einen Zähler um 4. Wenn der Zählerwert modulo the string length kleiner als 4 ist, dann wissen wir, dass wir drehen müssen:

char  counter  mod 6  compared to 4
 h       4       4          =
 e       8       2          <   => rotate
 l      12       0          <   => rotate
 l      16       4          =
 o      20       2          <   => rotate
 !      24       0          <   => rotate

Bildbeschreibung hier eingeben

Kommentierter und nicht Golf spielender Quellcode:

0                      % n
{%kshow                % n char1 char2
  = =                  % n
  4 add dup            % n' n'
  t length mod         % n' (n' mod t_length)
  4 lt                 % n' bool
  {-90 rotate}if       % n'
}                      % n kshowProc
% First 0 for moveto. We add it here to take 
% advantage of the surrounding self delimiting tokens.
0                      % n kshowProc 0
% We change the graphics state so that the drawn
% text is at a nice size and not off screen.
[0 3 -3 0 9 9]concat   % n kshowProc 0
0                      % n kshowProc 0 0
moveto                 % n kshowProc
/Courier 5 selectfont  % n kshowProc
t                      % n kshowProc text
kshow                  % n
Thomas W.
quelle
1

Python 2.x: 137

Ich bin neu im Code-Golfen und bin mir ziemlich sicher, dass dies verbessert werden kann ...

def s(t):c=len(t);w=1+c/4;h=(c-w-w)/2;u=w+h;n='\n';print t[:w]+n+n.join(map(((w-2)*' ').join,zip(t[:w+u-1:-1],t[w:u])))+n+t[w+u-1:u-1:-1]

Visueller Testcode:

from itertools import chain
from string import letters
for i in range(8,101,2):
    t = ''.join(chain(letters))[:i]
    print '%d: %s' % (i, t)
    s(t)
    print '-----'

Etwas von Interesse: Diese Lösung hängt von der ganzzahligen Mathematik ab. Wenn Sie nur symbolisch rechnen, werden Sie feststellen, h=(c-w-w)/2 => h=w-2dass bei jedem anderen Ergebnis zwei Zeichen links unten fehlen, wenn Sie dieses Ergebnis ersetzen.

Kojiro
quelle
1

K 84

{-1'(*r;((|r 3),\:(w-2)#" "),'r 1;|(r:(0,+\(w;h;w;h:_(l-2*w:-_-(1+(l:#x)%4))%2))_x)2);}

.

k){-1'(*r;((|r 3),\:(w-2)#" "),'r 1;|(r:(0,+\(w;h;w;h:_(l-2*w:-_-(1+(l:#x)%4))%2))_x)2);}"HelloWorld"
Hell
d  o
lroW

k){-1'(*r;((|r 3),\:(w-2)#" "),'r 1;|(r:(0,+\(w;h;w;h:_(l-2*w:-_-(1+(l:#x)%4))%2))_x)2);}"Hellooooooooooooooo Worlddddd!"
Hellooooo
!       o
d       o
d       o
d       o
d       o
d       o
lroW oooo
tmartin
quelle
1

Scala (135)

Das folgende Snippet setzt voraus, dass es xdie zu formatierende Zeichenfolge enthält und in die Scala REPL eingefügt werden soll:

val (h,w)=((x.size+3)/4,println(_:Any));val s=x.grouped(h)toSeq;w(s(0));for((l,r)<-s(1)zip(s(3)reverse))w(r+" "*(h-2)+l);w(s(2)reverse)

Wenn Sie Scala nicht installiert haben, können Sie es mit diesem Online-Scala-Interpreter schnell überprüfen: http://www.simplyscala.com/ . Fügen Sie einfach den folgenden Text ein und drücken Sie auswerten:

val x="HelloWorld"
val (h,w)=((x.size+3)/4,println(_:Any));val s=x.grouped(h)toSeq;w(s(0));for((l,r)<-s(1)zip(s(3)reverse))w(r+" "*(h-2)+l);w(s(2)reverse)
Régis Jean-Gilles
quelle
1

Python 3 (120)

s=input()
n=len(s)
h=n//4
q=(n+2)//4-1
p=print
p(s[:q+2])
for i in range(1,h):p(s[n-i]+' '*q+s[q+1+i])
p(s[n-h:q+h:-1])

Prüfung

Eingang:

abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz

Ausgabe:

abcdefghijklmn
z            o
y            p
x            q
w            r
v            s
u            t
t            u
s            v
r            w
q            x
p            y
o            z
nmlkjihgfedcba
Strahl
quelle
0

PHP (149)

Der zu druckende Text sollte sich in einer Variablen mit dem Namen befinden $x.

@$s=substr;echo$s($x,-$w=($l=strlen($x)/2)-$h=$i=$l-2>>1).'
';while($i--)echo$x[$l+$i].str_repeat(' ',$w-2).$x[$h-$i-1].'
';echo$s(strrev($x),$l,$w);
Jonathan
quelle
0

Python2.7 (99)

t=''.join(raw_input().split())
u=len(t)/2-1
print t[:u]+"\n"+t[-1]+" "*(u-2)+t[u]+"\n"+t[-2:u:-1]

Bearbeiten: Es verstößt anscheinend gegen die Regel, die maximale Fläche im Inneren einzuschließen.

sidi
quelle
0

JAVA - 320

public class A{
public static void main(String[] a){
String s=a[0];
int l=s.length(),h=l/2,f=h-1,i=0;       
for(i=0;i<f;i++)
System.out.print(s.charAt(i));
System.out.print("\n"+s.charAt(l-1));
for(i=0;i<f-2;i++)
System.out.print(" ");
System.out.println(s.charAt(h-1));
for(i=l-2;i>h-1;i--)
System.out.print(s.charAt(i));}}

Hinweis: - Die Eingabe erfolgt über die Befehlszeile

Eingabe: - HelloWorld

Ausgabe : -

Hell
d  o
lroW

Eingabe: - abcdefghijklmnopqrstuvwxyz

Ausgabe : -

abcdefghijkl
z          m
yxwvutsrqpon
Vivekanand SV
quelle
Bitte lesen Sie die Regeln genauer durch, insbesondere nr. 3.
vsz