Good day, monks,
A friend of mine sent me a link to a discussion of obfuscating code in C. In this particular discussion the programmer attacked a simple terminal application which produced a Mandelbrot fractal. It's a rather impressive bit of C coding (to a less than adept C coder), but I thought it would be fun to attack in Perl. (Note: I can't get the C code to compile on gcc, but I didn't try very hard.)
The C code example is 189 characters (my count with removed whitespace). I consider this more a golf than obfuscation since obfuscation implies a deliberate attempt to mislead the reader. The intent here was merely to make it as small as possible, and in the process it became difficult to read.
My code in Perl is 164 characters (less the shebang and newlines). This is my first official golf, so I'm sure someone out there will outdo me. I'd love to see it, and it might be fun to let the author of the C article see what madness we come up with.
#! /usr/bin/perl
for(0..39){$i=-1+$_*.05;for(0..59){$r=$j=-2.3+$_*.05;
$z=$i;$b=" ";for(0..255){$m=$r*$r;$n=$z*$z;if($m+$n>4)
{$b="+";last}$z=2*$r*$z+$i;$r=$m-$n+$j}print$b}print"\n"}
This outputs a 60 column by 40 row graph of ' ' and '+' which gives a decent presentation of the Mandelbrot fractal. Read the original article for more information. It was tested on Solaris 2.8 with Perl 5.005_3 and 5.6.1, but should run anywhere.
Good luck!
{NULE}
--
http://www.nule.org
__END__
Output should be this:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++
++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++
++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++
++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++ ++ +++++++++++
+++++++++++++++++++++++++++++++++++ +++++++
++++++++++++++++++++++++++++++++++++ +++++++
+++++++++++++++++++++++++++++++++++ ++++++++
++++++++++++++++++++++++++++++++++ +++++++
+++++++++++++++++++++++++++++++++ +++++
+++++++++++++++++++++++++++++++++ ++++++
+++++++++++++++++++++++ + +++++ ++++++
+++++++++++++++++++++++ ++ ++++++
++++++++++++++++++++++ + ++++++
++++++++++++++++++++++ + ++++++
++++++++++++++++++++ + + +++++++
++++++ ++++++++
++++++++++++++++++++ + + +++++++
++++++++++++++++++++++ + ++++++
++++++++++++++++++++++ + ++++++
+++++++++++++++++++++++ ++ ++++++
+++++++++++++++++++++++ + +++++ ++++++
+++++++++++++++++++++++++++++++++ ++++++
+++++++++++++++++++++++++++++++++ +++++
++++++++++++++++++++++++++++++++++ +++++++
+++++++++++++++++++++++++++++++++++ ++++++++
++++++++++++++++++++++++++++++++++++ +++++++
+++++++++++++++++++++++++++++++++++ +++++++
++++++++++++++++++++++++++++++++++++ ++ +++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++
++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++
++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Re: (Golf) Mandelbrot Fractal
by japhy (Canon) on May 08, 2002 at 16:30 UTC
|
map{$i=$_*.05-1;map{$r=$j=$_*.05-2.3;$z=$i;$b=$";for
(a..iv){$m=$r*$r;$n=$z*$z;$b="+",last if$m+$n>4;$z
=2*$r*$z+$i;$r=$m-$n+$j}print$b}0..59;print$/}0..39
I think the for(a..iv) trick is a nice stroke-shaver.
_____________________________________________________
Jeff[japhy]Pinyan:
Perl,
regex,
and perl
hacker, who'd like a job (NYC-area)
s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??; | [reply] [d/l] |
|
I'm sure there's more to come off, but I've worked it down to the following. Which seems to come in at 148 strokes using.
-l map{$i=$_*.05-1;print map{$r=$j=$_*.05-2.3;$z=$i;$b=$";map{$m=$r*$r
+;$n=$z*$z;$b='+'if$m+$n>4;$z=2*$r*$z+$i;$r=$m-$n+$j}a..iv;$b}0..59}0.
+.39
| [reply] [d/l] |
|
Application of YuckFoo's and my strategies
gets us 134.
There is an ever so slight change in the output
due to the fudge factor introduced by YuckFoo's
test change, switch back to the ()+() for 136 and
no change in output.
perl -l
map{$i=$_/20-1;print map{$r=$j=$_/20-2.3;$z=$i;$b=$";map{$b='+'if
$m=$r*$r,($n=$z*$z)>4;$z=2*$r*$z+$i;$r=$m-$n+$j}a..z;$b}0..59}0..39
--
perl -pew "s/\b;([mnst])/'$1/g"
| [reply] [d/l] |
|
And, sticking with the principle that we must iterate as many times as the original and that the output must look the same I've stolen a few ideas from other code and come up with
-l map{$i=$_/20-1;print map{$r=$;=$_/20;$z=$i;$b=$";($m=$r*$r)+($n=$z*
+$z)>4?$b='+':($z=2*$r*$z+$i,$r=$m-$n+$;)for a..iv;$b}-46..13}0..39
Which wc tells me is 136 chars long (counting 3 for "-l\n" in the same fashion as the perl.golf crowd). Having tried all the shorter solutions I've seen so far in this thread, I've not found one that actually works, but this one does. | [reply] [d/l] |
|
|
map{$i=$_*.05-1;map{$r=$j=$_*.05-2.3;$z=$i;$b=$";for(a..iv){$m=$r*$r;$
+n=$z*$z;
$m+$n>4?$b="+":($z=2*$r*$z+$i,$r=$m-$n+$j)}print$b}0..59;print$/}0..39
148 for a tie
map{$i=$_*.05-1;map{$r=$j=$_*.05-2.3;$z=$i;$b=$";for(a..iv){($m=$r*$r)
++
($n=$z*$z)>4?$b="+":($z=2*$r*$z+$i,$r=$m-$n+$j)}print$b}0..59;print$/}
+0..39
Meanwhile, in the chatterbox...
demerphq $i=$_*.05-1; could be written as $i=$_/2-1; couldnt it?
belg4mit no, it's not .5
belg4mit although /20 works ;-)
146! @ Wed May 8 14:42:11 EDT 2002
map{$i=$_/20-1;map{$r=$j=$_/20-2.3;$z=$i;$b=$";for(a..iv){($m=$r*$r)+
($n=$z*$z)>4?$b="+":($z=2*$r*$z+$i,$r=$m-$n+$j)}print$b}0..59;print$/}
+0..39
--
perl -pew "s/\b;([mnst])/'$1/g"
| [reply] [d/l] [select] |
|
map{$i=$_/20-1;map{$r=$j=$_/20-2.3;$z=$i;$b=$";($m=$r*$r)+($n=$z*$z)>4
+?
$b="+":($z=2*$r*$z+$i,$r=$m-$n+$j)for a..iv;print$b}0..59;print$/}0..3
+9
Yves / DeMerphq
---
Writing a good benchmark isnt as easy as it might look. | [reply] [d/l] |
|
|
Re: (Golf) Mandelbrot Fractal
by {NULE} (Hermit) on May 08, 2002 at 16:07 UTC
|
This probably isn't fair without some clearer code to start with. This is based off the authors original C code.
#! /usr/local/bin/perl -w
use strict;
my $fVRR = -2.3;
my $fVRI = -1.0;
my $fMaL = 0.05;
for (my $i = 0; $i < 40; $i++)
{
my $fCI = $fVRI + $i * $fMaL;
for (my $j = 0; $j < 60; $j++)
{
my $fCR = $fVRR + $j * $fMaL;
my $fZR = $fCR;
my $fZI = $fCI;
my $bI = 1;
for (0..255)
{
my $fZRS = $fZR * $fZR;
my $fZIS = $fZI * $fZI;
if ($fZRS + $fZIS > 4)
{
$bI = 0;
last;
}
$fZI = 2 * $fZR * $fZI + $fCI;
$fZR = $fZRS - $fZIS + $fCR;
}
print $bI?" ":"+";
}
print "\n";
}
{NULE}
--
http://www.nule.org | [reply] [d/l] |
Re: (Golf) Mandelbrot Fractal
by tadman (Prior) on May 08, 2002 at 21:19 UTC
|
Based on some musings in a deeper thread, a slight modification brings it to 131:
map{$i=$_/20-1;map{$r=$j=$_/20-2.3;$z=$i;($m=$r*$r,$n=$z*$z,$z=2*$r*$z+$i,$r=$m-$n+$j)for a..z;print$m<4?$":"+"}0..59;print$/}0..39
Update: With a bit of hackery then at 130:
map{$i=$_/20-1;map{$r=$j=$_/20-2.3;$z=$i;($n=$z*$z,$z=2*$r*$z+$i,$r=($m=$r*$r)-$n+$j)for a..z;print$m<4?$":"+"}0..59;print$/}0..39
As a note, using 'X' instead of '+' would save 2 characters.
If a slight readjustment of the newlines isn't invalid, you get 126:
print map{$i=$_/20-1;$/,map{$r=$j=$_/20-2.3;$z=$i;($n=$z*$z,$z=2*$r*$z+$i,$r=($m=$r*$r)-$n+$j)for a..z;$m<4?$":"+"}0..59}0..39
| [reply] [d/l] [select] |
|
-l map{$i=$_/20-1;print map{$r=$;=$_/20-2.3;$z=$i;$n=$z*$z,$m=$r*$r,$z
+=2*$r*$z+$i,$r=$m-$n+$;for a..z;$m<4?$":"+"}0..59}0..39
/s
Update: 123
-l map{$i=$_/20,print map{$r=$;=$_/20;$z=$i;$n=$z*$z,$m=$r*$r,$z=2*$r*
+$z+$i,$r=$m-$n+$;for a..z;$m<4?$":"+"}-46..13}-20..19
| [reply] [d/l] [select] |
|
With some bending of the rules(?), we get a little more detail, and 117 chars
perl -Mconstant=Z,20 -l
map{$i=$_/Z,print map{$r=$;=$_/Z;$z=$i;$n=$z*$z,$m=$r*$r,$z=2*$r*$z+$i
+,$r=$m-$n+$;for a..z;$m<4?$":"+"}-46..Z}-19..Z
116 @ Wed May 8 19:50:10 EDT 2002
map{$i=$_/Z,print map{$r=$;=$_/Z;$z=$i;$n=$z*$z,$z=2*$r*$z+$i,$r=($m=$
+r*$r)-$n+$;for a..z;$m<4?$":"+"}-46..Z}-19..Z
BTW, I like the use of $; :-)
UPDATE: Changed outside range from -20..Z to -19..Z to eliminate extra lines of +.
--
perl -pew "s/\b;([mnst])/'$1/g"
| [reply] [d/l] [select] |
|
|
|
That use of $; is very clever, as it parses correctly and allows you to omit the brackets for the for. Combining this with other modifications yields 122 chars of obfuscated goodness:
print map{$i=$_/20;$/,map{$r=$;=$_/20;$z=$i;$n=$z*$z,$z=2*$r*$z+$i,$r=($m=$r*$r)-$n+$;for a..z;$m<4?$":"+"}-46..13}-20..19
Further savings if you choose 'X' instead of '+':
print map{$i=$_/20;$/,map{$r=$;=$_/20;$z=$i;$n=$z*$z,$z=2*$r*$z+$i,$r=($m=$r*$r)-$n+$;for a..z;$m<4?$":X}-46..13}-20..19
Here is the original C code, just for comparison, at 182 characters:
void main(){double O,x,o,I,l,i;char _;for(l=-1;l<1;l+=.05,putc
;i<.7;i+=.05,putchar(_?'?':':'),O=i,x=l,o=I=(_=1)--)for(;++_&&
);x=2*O*x+l,O=o-I+i);}
C allows for shorter variable names, and Perl still comes out ahead. Crazy.
| [reply] [d/l] [select] |
|
|
Re: (Golf) Mandelbrot Fractal
by YuckFoo (Abbot) on May 08, 2002 at 21:08 UTC
|
Just because I spent way too much time and managed to get
under 150, to 147
for($x=-1;$x<1;$x+=.05){for($y=-2.3;$y<.7;$y+=.05){$i=$y;$j=$x;$k=99;
while($j<4&&--$k){($i,$j)=($i*$i-$j*$j+$y,2*$i*$j+$x)}print$k?'+':' '}
+print$/}
BogeyFoo | [reply] [d/l] |
Re: (Golf) Mandelbrot Fractal
by {NULE} (Hermit) on May 10, 2002 at 12:57 UTC
|
Hi again, my good monks,
I'm pleased by the enthusiastic response to this post. The
author of the original article was forwarded this node, although
I'm not aware if he has commented on it. It looks like we could
get down to about the mid 130's without changing the algorithm
at all, and the low 120's with minor changes that are still in
the spirit of thing. (Sorry belg4mit, that constant thing is
cheating. {g})
I learned plenty too, which is the whole reason for golfing.
I'm kicking myself for not seeing the dumb optimizations in the
simple mathematics (being a mathematician by training, you'd
think I would have spotted that - but I was too focused on
improving the Perl and didn't think about the algorithm enough).
Anyway, thanks for all the responses,
{NULE}
--
http://www.nule.org
| [reply] |
|
|