Rectangle de texte

13

Votre programme reçoit un texte en entrée, d'au moins 8 caractères et toujours composé d'un nombre pair de caractères. (pas besoin d'évaluer l'exactitude de la saisie).

Votre objectif est d'afficher ce texte sous forme de rectangle. Par exemple, donné HelloWorlden entrée, afficher

Hell
d  o
lroW

Règles:

  • Le texte tourne dans le sens horaire (position de départ comme vous le souhaitez)
  • Il formera un rectangle fermé, les côtés de 1 caractère de large.
  • Le rectangle devra englober la plus grande surface à l'intérieur. (juste pour exclure la réponse triviale d'afficher le texte sur deux lignes)
  • Aucun autre caractère n'est imprimé à part le texte lui-même et les espaces de remplissage et les sauts de ligne nécessaires.

En tant que code-golf, le code le plus court gagne.

Le gagnant est sélectionné au plus tard 10 jours après la première réponse valide.

vsz
la source

Réponses:

5

GolfScript, 56 53 40 38 caractères

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

Vous pouvez tester le script en ligne .

Howard
la source
7

PostScript 50 binaire, 113 ASCII

Cela utilise une sortie graphique. Hexdump du programme à l'aide de jetons binaires:

$ 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

Téléchargez pour l'essayer . À l'aide de Ghostscript, le texte à rendre peut être transmis au programme comme suit:

gs -st=helloworld textRect_binary.ps 

La sortie graphique ressemble à ceci:

rendered output

Le même code utilisant des jetons ASCII ressemble à ceci:

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 stratégie est d'utiliser xyshowpour définir où nous nous déplaçons après avoir montré chaque personnage avant de montrer le personnage suivant. Nous commençons dans le coin inférieur gauche, nous allons dans le sens des aiguilles d'une montre, c'est-à-dire d'abord vers le haut, puis à droite, puis vers le bas puis à gauche. Nous déplaçons toujours 9 unités, nous avons donc d'abord un mouvement relatif de 0 9, puis 9 0, ensuite 0 -9, ensuite -9 0. On peut passer d'une paire de ces nombres à l'autre avec la séquence exch neg.

Nous devons construire un tableau pour xyshowcontenir ces paires de nombres, une paire pour chaque caractère. Cela signifie que si nous avons helloworldcomme chaîne d'exemple, qui a 10 caractères, nous voulons monter deux fois, puis trois fois à droite, puis deux fois à gauche et trois fois à gauche. Nous obtenons ces valeurs (deux et trois) en divisant la longueur de la chaîne par 8, une fois arrondie au sol, une fois au plafond.

Donc, nous copions 0 9deux fois, puis passons aux coordonnées x / y relatives en utilisant exch neg, copions ces trois fois et ainsi de suite.

Ce code commenté montre ce qui se passe sur la pile:

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.
la source
+1 sainte bajeezus. Je suis gravement déficient dans ma connaissance du niveau 2 et au-delà.
luser droog
Tu veux dire xyshow? Heureux de vous présenter celui-ci - il y a quelque temps, vous m'avez présenté kshow, dont je n'étais pas vraiment au courant ;-).
Thomas
@luserdroog: BTW: Je suis assez fier que l'entrée GolfScript actuelle ait plus de 10% de caractères de plus que mon entrée binaire, mais cela me dérange que ma version ASCII soit à un caractère d'un tirage avec Ruby (en fait, même trois, parce que le code Ruby pourrait être joué plus loin). Avez-vous des idées pour une optimisation supplémentaire?
Thomas
@ThomasW. Maintenant, mon entrée GolfScript est 24% plus courte que votre binaire ;-) Et je pense toujours qu'il est encore possible de la raccourcir encore plus d'un ou deux caractères.
Howard
@Howard: Argh !!! Quelqu'un peut-il jamais battre GolfScript?
Thomas
7

Ruby 112 100

Je suis nouveau à Ruby et c'est mon premier golf à code. J'ai puisé dans l'implémentation de perl de memowe et essayé d'en faire une version Ruby. Il s'agit de 112 100 caractères et suppose que vous affectez une chaîne à x. Au plaisir de voir les autres.

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

Modifié pour implémenter les suggestions. Je pense que c'est maintenant 100 caractères. Merci les gars!

jzig
la source
Agréable! Vous pouvez enregistrer deux caractères dans la 5ème ligne (supprimer les espaces).
Thomas W.19
Je l'aime. Merci. Il semble bon que les chaînes Ruby soient accessibles comme un tableau, j'ai dû en créer une moi-même. :)
memowe
Vous pouvez remplacer x.lengthpar x.size(Enregistre 2 caractères)
knut
1
Et 8 de plus en utilisant puts x[0..w=l/2-h=l/4].
Howard
5

Perl (124 118 109 + 3 = 112)

C'était autrefois assez simple. Compter toutes les options de ligne de commande comme 1 caractère chacune.

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

Exemple:

$ 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
la source
Cela peut être compacté: (1) (@s-$h*2)/2 == @s/2-$h(2) $wpeut être représenté comme $w=(@s=split//)/2-($h=int@s/4);, sauvant ainsi deux points - virgules
amon
Mise à jour du code.
memowe
Autre chose intéressante: (1) l'espace est la valeur par défaut de l'interpolation de tableau var $"–saves 1 char. (2) $w+$h == @s/2–enregistre 1 caractère. (3) Si $west plus petit de un, nous pouvons simplifier $"x($w-1). Pour cela, le $_doit être augmenté de 1. Enregistre comme 3 caractères. (4) Le dernier point-virgule est überflüssig, enregistre 1 car. Cela conduit au fragment de code say@s[0..$w--];say$s[1-$_].$"x$w.$s[$w+$_]for+2..$h;say+reverse@s[@s/2..@s-$h](avec quelques-uns +pour le plaisir, donc il n'y a plus un seul espace).
amon
Excellente golfification, @amon, voudriez-vous l'éditer dans mon message s'il vous plaît? De cette façon, le monde peut voir qui l'a fait. :)
memowe
5

Brainfuck - 194 187

+>,[>+[>+<-],]
>-->++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>[-]>[-]>[<<+<<+>>>>-]<<<<
[[<]>+[>]<-]<[<]>-
[>.[-]<[>+<-]>-]>[>]
++++++++++.<.[-]
>[>+++>>+<<<-]>++>--[<.>-]<<<<[<]>.[-]>[>]>>>>.
<<<<<[.<]
captncraig
la source
Bien essayé, mais cela ne fonctionne pas. La ligne du bas est dans la mauvaise direction, contrairement à la règle 1, et elle n'a qu'une hauteur fixe, contrairement à la règle 3.
vsz
Je ne sais pas pourquoi j'ai inversé la dernière ligne. Je l'avais totalement à l'esprit de la bonne façon pendant que je l'écrivais. Le correctif enregistre en fait 7 commandes. Je me suis contenté de la hauteur fixe, mais ce n'est pas le cas trivial de 2 lignes dont vous avez parlé. Peut-être que je ferai mieux à l'avenir.
captncraig
4

Mathematica 156 199 344

Éditer : Il s'agit d'une réécriture majeure du code précédent. Il fonctionne essentiellement de la même manière, mais prend maintenant en entrée une chaîne de longueur <120 caractères et dimensionne automatiquement le carré.

Il pourrait encore être un peu joué au golf, mais ne descendra pas à la taille des versions antérieures et plus bogues.

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

Exemples

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
la source
Hé, un tableau de cordes? C'est vraiment plier les règles, n'est-ce pas?
Thomas
@ThomasW. Les commentaires dans la réponse indiquent que ce n'est pas une solution finale.
kojiro
Ah, je vois! Je me demande si je devrais relever le défi et essayer quelque chose de similaire en PostScript ...
Thomas W.
J'aime à quoi ça ressemble maintenant!
Thomas W.21
@ Thomas W. Merci. Obtenir le bon format pour une large gamme de longueurs de chaîne coûte beaucoup d'octets.
DavidC
2

Perl + Regexes: 104 (101 + 3)

(code de comptage + interrupteurs)

Voici une solution utilisant de jolies Regexes et un peu de 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'

Cela ne fonctionnera correctement que sur un ligne d'entrée.

Inspiré par memowe, mais essentiellement sans tableau.

amon
la source
Désolé pour la question stupide: comment puis-je essayer cela? Je colle votre code sur la ligne de commande, puis tape quelque chose, appuyez sur Entrée et quelque chose sort. Mais ce n'est pas une boîte. Qu'est-ce que je fais mal?
Thomas
@ThomasW. Cela semble fonctionner pour moi, pour un nombre pair arbitraire de caractères. Le code ci-dessus est garanti pour fonctionner sous bash et perl version 5.12+. La saisie est acceptée via STDIN et seule la première ligne est traitée correctement. Je ne sais pas comment citer correctement le code pour cmd.exe.
amon
1
Ah, c'était probablement mon erreur. J'ai probablement utilisé une chaîne de longueur impaire. Cela fonctionne: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)

Ceci est inspiré par la solution Mathematica de mec .

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

Avec Ghostscript, appelez cela comme

gs -st=hello! boxtext.ps

Il produit une sortie comme.

Hello_Code_Golf_World!

Janvier février mars avril mai juin juillet

Il utilise kshow pour afficher les glyphes un par un. Après avoir montré suffisamment de glyphes pour un côté, tout est tourné de -90 degrés avant de continuer avec les glyphes restants.

Pour savoir quand suffisamment de glyphes ont été affichés sur le côté, nous incrémentons un compteur de 4 chaque fois qu'un glyphe est affiché. Si la valeur du compteur modulo la longueur de la chaîne est inférieure à 4, alors nous savons que nous devons tourner:

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

entrez la description de l'image ici

Code source commenté et non golfé:

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.
la source
1

Python 2.x: 137

Je suis nouveau dans le code du golf et je suis sûr que cela peut être amélioré…

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]

Code de test visuel:

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

Quelque chose d'intérêt: Cette solution dépend des mathématiques entières. Si vous faites simplement le calcul symboliquement, vous le trouverez h=(c-w-w)/2 => h=w-2, mais si vous remplacez ce résultat, tous les autres résultats manqueront deux caractères en bas à gauche.

kojiro
la source
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
la source
1

Scala (135)

L'extrait suivant suppose que xcontient la chaîne à formater et doit être collé dans le 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)

Si vous n'avez pas installé scala, vous pouvez le vérifier rapidement en utilisant cet interpréteur Scala en ligne: http://www.simplyscala.com/ . Collez simplement le texte suivant et appuyez sur Évaluer:

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

Tester

contribution:

abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz

production:

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
Rayon
la source
0

PHP (149)

Le texte à imprimer doit être dans une variable nommée $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
la source
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]

Edit: Il viole apparemment la règle de la zone maximale à l'intérieur.

sidi
la source
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));}}

Remarque: - L' entrée provient de la ligne de commande

Entrée: - HelloWorld

Production : -

Hell
d  o
lroW

Entrée: - abcdefghijklmnopqrstuvwxyz

Production : -

abcdefghijkl
z          m
yxwvutsrqpon
Vivekanand SV
la source
Veuillez lire les règles plus attentivement, en particulier nr. 3.
vsz