Rettangolo di testo


13

Il tuo programma riceve un testo come input, lungo almeno 8 caratteri e sempre composto da un numero pari di caratteri. (non è necessario valutare la correttezza dell'input).

Il tuo obiettivo è quello di visualizzare quel testo come un rettangolo. Ad esempio, dato HelloWorldcome input, display

Hell
d  o
lroW

Regole:

  • Il testo gira in senso orario (posizione iniziale come preferisci)
  • Formerà un rettangolo chiuso, con i lati di 1 carattere di larghezza.
  • Il rettangolo dovrà comprendere la maggior parte dell'area all'interno. (solo per escludere la banale risposta della visualizzazione del testo in due righe)
  • Non vengono stampati altri caratteri oltre al testo stesso e agli spazi di riempimento e avanzamenti di riga necessari.

Come code-golf, vince il codice più corto.

Il vincitore viene selezionato non prima di 10 giorni dopo la prima risposta valida.

Risposte:


5

GolfScript, 56 53 40 38 caratteri

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

Puoi testare lo script online .


7

Binario PostScript 50, 113 ASCII

Questo utilizza un output grafico. Hexdump del programma usando token binari:

$ 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

Scarica per provarlo . Utilizzando Ghostscript, il testo da rendere può essere passato al programma come segue:

gs -st=helloworld textRect_binary.ps 

L'output grafico è simile al seguente:

output reso

Lo stesso codice che utilizza i token ASCII è simile al seguente:

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

La strategia è usare xyshowper definire dove ci muoviamo dopo aver mostrato ogni personaggio prima di mostrare il personaggio successivo. Stiamo iniziando nell'angolo in basso a sinistra, spostandoci in senso orario, cioè prima in alto, poi a destra, poi in basso e poi a sinistra. Muoviamo sempre 9 unità, quindi prima abbiamo un movimento relativo di 0 9, poi 9 0, poi 0 -9, poi -9 0. Possiamo passare da una coppia di questi numeri a quella successiva con la sequenzaexch neg .

Dobbiamo costruire un array per xyshowcontenere queste coppie di numeri, una coppia per ciascun personaggio. Questo significa, se abbiamohelloworld come stringa di esempio, che ha 10 caratteri, vogliamo salire due volte, quindi tre volte a destra, quindi due volte in basso e tre volte a sinistra. Otteniamo questi valori (due e tre) dividendo la lunghezza della corda per 8, una volta arrotondando al pavimento, una volta al soffitto.

Quindi, copiamo 0 9due volte, quindi passiamo alle relative coordinate x / y usandoexch neg , copiamo quelle tre volte e così via.

Questo codice commentato mostra cosa succede nello stack:

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

+1 bajeezus santo. Sono gravemente carente nella mia conoscenza del livello 2 e oltre.
Luser droog

Intendi xyshow? Felice di presentarti questo - qualche tempo fa mi hai fatto conoscere kshow, di cui non ero a conoscenza ;-).
Thomas W.

@luserdroog: A proposito: sono abbastanza orgoglioso che l'attuale voce di GolfScript abbia più del 10% di caratteri in più rispetto alla mia voce binaria, ma mi dà fastidio che la mia versione ASCII è a un carattere di distanza da un sorteggio con Ruby (in realtà, anche tre, perché il codice Ruby potrebbe essere ulteriormente approfondito). Hai idee per un'ulteriore ottimizzazione?
Thomas W.

@ThomasW. Ora la mia voce GolfScript è più corta del 24% rispetto al tuo binario ;-) E penso ancora che ci sia ancora la possibilità di accorciarlo ulteriormente di uno o due caratteri.
Howard,

@Howard: Argh !!! Qualcuno può mai battere GolfScript?
Thomas W.

7

Rubino 112 100

Sono nuovo di Ruby e questo è il mio primo codice golf. Ho attinto all'implementazione perl di memowe e ho provato a crearne una versione Ruby. Questo è 112 100 caratteri e presuppone che tu assegni una stringa a x. In attesa di vedere gli altri.

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

Modificato per implementare suggerimenti. Penso che siano 100 personaggi ora. Grazie ragazzi!


Bello! È possibile salvare due caratteri nella 5a riga (rimuovere gli spazi).
Thomas W.

Mi piace. Grazie. Sembra buono che le stringhe di Ruby siano accessibili come un array, ho dovuto costruirne uno da solo. :)
Memowe

È possibile sostituire x.lengthconx.size (Salva 2 caratteri)
annodare il

1
E altri 8 usando puts x[0..w=l/2-h=l/4].
Howard,

5

Perl (124 118 109 + 3 = 112)

Questo in precedenza era piuttosto semplice. Ha contato tutte le opzioni della riga di comando come 1 carattere ciascuna.

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

Esempio:

$ 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

Questo può essere compattato: (1) (@s-$h*2)/2 == @s/2-$h(2) $wpuò essere rappresentato come $w=(@s=split//)/2-($h=int@s/4);, risparmiando così due punti
amon

Aggiornato il codice.
ricorda il

Altre cose interessanti: (1) lo spazio è il valore predefinito dell'interpolazione dell'array var $"–saves 1 char. (2) - $w+$h == @s/2salva 1 carattere. (3) Se $wè più piccolo di uno, possiamo semplificare $"x($w-1). Per questo, $_deve essere aumentato di 1. Salva come 3 caratteri. (4) Il punto e virgola finale è überflüssig, risparmia 1 carattere. Questo porta al frammento di codice say@s[0..$w--];say$s[1-$_].$"x$w.$s[$w+$_]for+2..$h;say+reverse@s[@s/2..@s-$h](con alcuni +per divertimento, quindi non è rimasto un solo spazio).
amon

Eccellente golfizzazione, @amon, la modificheresti nel mio post per favore? In questo modo il mondo può vedere chi è stato. :)
Memowe

5

Brainfuck - 194 187

+>,[>+[>+<-],]
>-->++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>[-]>[-]>[<<+<<+>>>>-]<<<<
[[<]>+[>]<-]<[<]>-
[>.[-]<[>+<-]>-]>[>]
++++++++++.<.[-]
>[>+++>>+<<<-]>++>--[<.>-]<<<<[<]>.[-]>[>]>>>>.
<<<<<[.<]

Bel tentativo, ma non funziona. La linea di fondo è nella direzione sbagliata, contrariamente alla regola 1, e ha solo un'altezza fissa, contrariamente alla regola 3.
vsz

Non sono sicuro del motivo per cui ho lanciato l'ultima riga. L'ho pensato perfettamente nel modo corretto in cui lo stavo scrivendo. La correzione in realtà salva 7 comandi. Ho fatto il poliziotto sulla cosa ad altezza fissa, ma non è il banale caso a 2 righe di cui hai parlato. Forse lo farò meglio in futuro.
captncraig,

4

Mathematica 156 199 344

Modifica : questa è una riscrittura importante del codice precedente. Funziona essenzialmente allo stesso modo, ma ora accetta come input una stringa di lunghezza <120 caratteri e ridimensiona automaticamente il quadrato.

Potrebbe ancora essere giocato a golf un po ', ma non si ridurrà alle dimensioni delle versioni precedenti e più robuste.

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

Esempi

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


Ehi, una serie di stringhe? Questo sta davvero piegando le regole, vero?
Thomas W.

@ThomasW. I commenti nella risposta indicano che non è una soluzione finale.
Kojiro,

Ah, capisco! Mi chiedo se dovrei accettare la sfida e provare qualcosa di simile in PostScript ...
Thomas W.

Mi piace come appare adesso!
Thomas W.

@Thomas W. Grazie. Far apparire il formato giusto per una vasta gamma di lunghezze di stringa costa molti byte.
DavidC,

2

Perl + Regexes: 104 (101 + 3)

(codice di conteggio + interruttori)

Ecco una soluzione che utilizza i bei Regex e un po 'di 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'

Questo funzionerà correttamente solo su uno linea di ingresso.

Ispirato da memowe, ma essenzialmente senza array.


Ci scusiamo per la domanda stupida: come posso provarlo? Sto incollando il tuo codice sulla riga di comando, quindi digito qualcosa, premi Invio e qualcosa esce. Ma non è una scatola. Che cosa sto facendo di sbagliato?
Thomas W.

@ThomasW. Sembra funzionare per me, per un numero pari arbitrario di caratteri. Il codice sopra è garantito per funzionare con bash e perl versione 5.12+. L'immissione viene accettata tramite STDIN e solo la prima riga viene elaborata correttamente. Non so come citare correttamente il codice per cmd.exe.
amon

1
Ah, probabilmente è stato un mio errore. Probabilmente ho usato una stringa di lunghezza dispari. Funziona così: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)

Questo si ispira alla soluzione Mathematica di 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

Con Ghostscript chiama questo come

gs -st=hello! boxtext.ps

Produce un output simile.

Hello_Code_Golf_World!

Gennaio febbraio marzo Aprile Maggio Giugno Luglio

Utilizza kshow per mostrare i glifi uno per uno. Dopo che sono stati mostrati abbastanza glifi per un lato, tutto viene ruotato di -90 gradi prima di continuare con i glifi rimanenti.

Per sapere quando sono stati mostrati abbastanza glifi sul lato, incrementiamo un contatore di 4 ogni volta che viene mostrato un glifo. Se il valore del contatore modulo la lunghezza della stringa è inferiore a 4, allora sappiamo che dobbiamo ruotare:

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

inserisci qui la descrizione dell'immagine

Codice sorgente commentato e non golfato:

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

1

Python 2.x: 137

Sono nuovo nel golf del codice e sono abbastanza sicuro che questo possa essere migliorato ...

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]

Codice test visivo:

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

Qualcosa di interessante: questa soluzione dipende dalla matematica dei numeri interi. Se fai semplicemente la matematica simbolicamente, lo scoprirai h=(c-w-w)/2 => h=w-2, ma se sostituisci quel risultato ad ogni altro risultato mancheranno due caratteri in basso a sinistra.


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

1

Scala (135)

Il frammento seguente presuppone che xcontenga la stringa da formattare e deve essere incollato nello scala REPL:

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)

Se non hai installato scala, puoi controllarlo rapidamente usando questo interprete Scala online: http://www.simplyscala.com/ . Basta incollare il seguente testo e premere valutazione:

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)

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

Test

ingresso:

abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz

produzione:

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

0

PHP (149)

Il testo da stampare dovrebbe essere in una variabile denominata $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);

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]

Modifica: apparentemente viola la regola di comprendere l'area massima all'interno.


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

Nota: - L' input viene prelevato dalla riga di comando

Input: - HelloWorld

Produzione : -

Hell
d  o
lroW

Input: - abcdefghijklmnopqrstuvwxyz

Produzione : -

abcdefghijkl
z          m
yxwvutsrqpon

Si prega di leggere le regole più attentamente, in particolare il n. 3.
vsz
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.