 Perl: the Markov chain saw PerlMonks

### Triangle Golf

by nashdj (Friar)
 on Apr 24, 2001 at 14:23 UTC ( #75004=CUFP: print w/replies, xml ) Need Help??

A friend of mine recently had an assignment where he had to split up a text file and print it out as a triangle. Of course this was in "c" and so, just because I could I had to see just how simple it would be in perl. The idea is to take a ctriangle.txt file like
```a a a a a a a a a
a a a a a a a a a
a a a a a a a a a
a a a a a a a a
and end up centered over 80 chars
```       a
a a
a a a
a a a a
a a a a a
a a a a a a
a a a a a a a
a a a a a a a
```          The
same
principle
applies to
any text file,
basically splitting
words only on spaces
or new lines
My best shot was 132 chars (\n inc). I especially like the new trick I learnt.
```/[
]+/
Which matches space/new line combinations.

Well this is the best I could do, after staring at it for half an hour it wasnt getting any shorter.

```open F,"ctriangle.txt";sub n{print
" "x(40-\$r/2)."\$x\n"};for(split/[
]+/,join'',<F>){\$c=\$r,n,\$x=''if(
\$r=length(\$x.=" \$_"))>\$c}n
- nashdj

Update:
With jeroenes idea, if I undef \$/ by assigning it undef from an unused variable (not pretty but we're talking size) its down to 128 chars.

```open F,"ctriangle.txt";sub n{print
" "x(40-\$r/2)."\$x\n"};\$/=\$w;\$_=<F>;
for(split){\$c=\$r,n,\$x=''if(
\$r=length(\$x.=" \$_"))>\$c}n

Replies are listed 'Best First'.
Re: Triangle Golf
by jeroenes (Priest) on Apr 24, 2001 at 15:53 UTC
```split /[
]+/, join '', <F>
You can also say: split /\s+/, join '', <F>
or
```undef \$/; \$_=<F>; split

Saves Just Another Character
"We are not alone"(FZ)

Re: Triangle Golf
by jmcnamara (Monsignor) on Apr 24, 2001 at 17:14 UTC

This was attempt to see if using format() would be shorter. It wasn't. It does use some of Perl's dustier artifacts however:
```#!/usr/bin/perl -wall -00n
use strict;

END{
@_=shift@F;
while(@F){
\$_=shift @F;
\$_.=' '.shift@F while(length\$_<=length\$_[-1]&&@F);
push@_,\$_
}
formline(('@'.('|'x80)."\n")x@_,@_);
print \$^A
}

Update: Using MeowChow's regex this can be reduced to 89 chars + 6 command line switches. I'm not proud of this:
```#!/usr/bin/perl -w -00nal
use strict;

END{
\$_="@F ";
@F=1;
formline'@'.('|'x80)."\n",\$&and@F=length\$&while/.{1,@F}.*? /g;
print\$^A
}

John.
--

Re: Triangle Golf
by xtrem (Novice) on Apr 24, 2001 at 19:32 UTC
116 with newlines (by wc)
```@ARGV="ctriangle.txt";
sub n{print\$"x(40-\$r/2)."\$x\n"}
for(map{split}<>){\$c=\$r,n,\$x=''if(\$r=length(\$x.=" \$_"))>\$c}n
Re: Triangle Golf
by MeowChow (Vicar) on Apr 24, 2001 at 22:29 UTC
```\$c=(@ARGV,\$/)='ctriangle.txt';\$_=<>.\$";y/
/ /s;print\$"x(40-(\$c=length\$&)/2),"\$&\n"while/.{1,\$c}.*? /g
102, including the newline ;)

update: changed two ' ' to \$", saving an additional two characters - liberally aped from jeroenes node :-)

update2: shuffled the \$/ assignment into the list assignment, saving another extra char.

```   MeowChow
s aamecha.s a..a\u\$&owag.print```
Here's some variations on MeowChow's idea above:
a perfectly respactable program, about 140 chars (after the #!.../):
```#!/usr/local/bin/perl -ln0777

\$\ ='
';
\$c = 0;

s/^\s+//;
s/\s+/ /gs;

while ( s/(.{\$c,}?. |.+\$)// ) {

print " " x (40 - (\$c = 1 + length \$1) / 2), \$1
}
> triangle.pl a.txt w.txt
```                                      a
a a a
a a a a a
a a a a a a a
a a a a a a a a a
a a a a a a a a a a
The
same principle
applies to any text
file, basically splitting
words only on spaces or new lines

a one-liner, 74 chars (+6 extra flag chars):
```> perl -ln0777we '\$c=0;s/\s+/ /sg;print" "x(40-(\$c=length\$1)/2),\$1 whi
+le s/(.{\$c,}?. |.+\$)//' a.txt w.txt
a
a a
a a a
a a a a
a a a a a
a a a a a a
a a a a a a a
a a a a a a a
The
same principle
applies to any text
file, basically splitting
words only on spaces or new
lines

and pretty well golfed, 66 chars (+6 extra flag chars):
```> perl -ln0777e's/\s+/ /sg;print\$"x(40-(\$c=length\$&)/2),\$&while s/.{0\$
+c,}?. |.+\$//' a.txt w.txt
a
a a
a a a
a a a a
a a a a a
a a a a a a
a a a a a a a
a a a a a a a
The same principle
applies to any text file,
basically splitting words only
on spaces or new lines

> perl -ln0777e's/\s+/ /sg;print\$"x(40-(\$c=length\$&)/2),\$&while s/.{0\$
+c,}?. |.+\$//' w.txt a.txt

The
same principle
applies to any text
file, basically splitting
words only on spaces or new
lines
a a a a
a a a a a
a a a a a a
a a a a a a a
a a a a a a a a
a a a a a

p
Very nice paring down, I especially like the conversion from a greedy expression to the minimal one you use, in order to avoid defining \$c. Further reduction gives:
```perl -ln0e's/\s+/ /g;print\$"x(40-(\$c=length\$&)/2),\$&while/.{0\$c,}? |.*
+/g' ...
61 chars of code plus 3 modifier chars.
```   MeowChow
s aamecha.s a..a\u\$&owag.print```
Re: Triangle Golf
by japhy (Canon) on Apr 24, 2001 at 19:13 UTC
I offer, at 118 (not counting newlines):
```@ARGV='ctriangle.txt';sub n{print
" "x(40-\$r/2).\$x.\$\};\$/=\$w;\$_=<>;
(\$r=length(\$x.=" \$_"))>\$=and
\$==\$r,n,\$x=''for split;n

japhy -- Perl and Regex Hacker

The above didn't work for me. \$\ is undefined by default so the newline doesn't print and \$= is 60 by default so the tests fail. This is the best fix I could come up with, unfortunately with one extra character:

```@ARGV='ctriangle.txt';sub n{print
" "x(40-\$r/2)."\$x\n"};\$/=\$w;\$_=<>;
(\$r=length(\$x.=" \$_"))>\$/and
\$/=\$r,n,\$x=''for split;n;
I'm sorry. I posted the code without testing it. I had meant \$/ instead of \$\, but I see that wouldn't have worked. Sorry about that.

japhy -- Perl and Regex Hacker
Re: Triangle Golf
by jeroenes (Priest) on Apr 25, 2001 at 02:13 UTC
Works not on words, but 114 char:
```@ARGV="ctriangle.txt";
sub n{print\$"x(40-\$r),@b,\$/}
@a=map{split}<>;\$,=\$";while(\$r++<@a){@b=splice@a,0,\$r;n}\$r--,n
"We are not alone"(FZ)
Update: Most of this is just an adaption of the other code in this nice thread, including the \$". I like xterm's idea of map{split}<> very much I must say. But the '\$,' was my own creativity....

Create A New User
Node Status?
node history
Node Type: CUFP [id://75004]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (8)
As of 2020-01-26 02:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
The worst excuse I have ever heard is:

Results (110 votes). Check out past polls.

Notices?