Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic

(Golf) Mandelbrot Fractal

by {NULE} (Hermit)
on May 08, 2002 at 15:28 UTC ( #165069=perlmeditation: print w/replies, xml ) Need Help??

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!

__END__ Output should be this: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++ ++ +++++++++++ +++++++++++++++++++++++++++++++++++ +++++++ ++++++++++++++++++++++++++++++++++++ +++++++ +++++++++++++++++++++++++++++++++++ ++++++++ ++++++++++++++++++++++++++++++++++ +++++++ +++++++++++++++++++++++++++++++++ +++++ +++++++++++++++++++++++++++++++++ ++++++ +++++++++++++++++++++++ + +++++ ++++++ +++++++++++++++++++++++ ++ ++++++ ++++++++++++++++++++++ + ++++++ ++++++++++++++++++++++ + ++++++ ++++++++++++++++++++ + + +++++++ ++++++ ++++++++ ++++++++++++++++++++ + + +++++++ ++++++++++++++++++++++ + ++++++ ++++++++++++++++++++++ + ++++++ +++++++++++++++++++++++ ++ ++++++ +++++++++++++++++++++++ + +++++ ++++++ +++++++++++++++++++++++++++++++++ ++++++ +++++++++++++++++++++++++++++++++ +++++ ++++++++++++++++++++++++++++++++++ +++++++ +++++++++++++++++++++++++++++++++++ ++++++++ ++++++++++++++++++++++++++++++++++++ +++++++ +++++++++++++++++++++++++++++++++++ +++++++ ++++++++++++++++++++++++++++++++++++ ++ +++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Replies are listed 'Best First'.
Re: (Golf) Mandelbrot Fractal
by japhy (Canon) on May 08, 2002 at 16:30 UTC
    I cut it down to 153:
    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:??;

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

        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 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.
      149 baby!
      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"

        In a wild attempt to redeem myself I get 142:

        UPDATE:Removed single line version cause it screws up some peoples screen layout.

        Or a little better formatted
        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.

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

        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.
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$/}


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,

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://165069]
Approved by broquaint
Front-paged by johannz
[1nickt]: ugh, I stuck my head in the bass bin for 30 seconds on a dare at Ted Nugent at Hammersmith Odeon. Yes, I am 40% deaf now.
[johngg]: My daughter is incredibly jealous of my wife who got to see The Clash at Brixton many years ago. They went to see The Vaccines there recently.
[1nickt]: But the bands are even louder! I saw Spearhead (Michael Franti) at an outdoor show and had to walk a mile away to not feel pain in my chest! Babies were crying ... I asked the sound engineer why it was necessary to have the bass so loud and he laughed...
[Discipulus]: but the best i attended live was Mano Negra Patchanka at Forte Prenestino .. in 1990
[Corion]: Hmmm - Mano Negra or at least Manu Chao seem to put on a good live show. At least the one live CD I have from Manu Chao sounds good ;)
Discipulus feels the same jealousity of the johngg's daughter
[1nickt]: choroba I agree
[choroba]: Playing in a punk rock band for 20 years... my hearing is quite bad
[Corion]: I still have hopes to turn my godson and his two siblings into a punk band ;)
[Corion]: Their older sister just started piano but has been interested in drumming, which she should be able to start with 8 years or so)

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (12)
As of 2017-03-24 12:19 GMT
Find Nodes?
    Voting Booth?
    Should Pluto Get Its Planethood Back?

    Results (301 votes). Check out past polls.