#!/usr/bin/perl sub r{int rand pop}$|++;@g=map{[map{' '}0..$=]}0..25;my$j=pop||2+r(3); +@f=map{my$ k=my$n=$b++;my$z=1;my$x=r$=;my($q,$v,$e)=my@l=(0,0,0,0);my$h=r(9);$w={ +i=>sub{$k= r($j) while($k==$n or!$f[$k]);my$o=$f[$k];$h+=($e?-1:1);if($h<1){$e=0; +$k=$n}if($ h>6){$e=1}if(!$z){my$u=($x<$$o{x}->()?1:-1);$u*=(($e>1)?-1:1);$q=$e?($ +u*(r(7))): 0;if($e>1){$q||=4}if($e and(r(7)>3)){$v=r(6)}}my$t=($$o{z}->()cmp$z)+1 +;$t=0 if($ x==$$o{x}->());my$s=(($x<$$o{x}->())?1:0);for(0,2){$l[$_+$s]+=($t cmp$ +l[$_+$s])} for(0,2){$l[$_+($s?0:1)]=0}if($z){$v-=2}$x+=$q;$z+=$v;$z=0 if$z<0;if($ +x<2){$x=2; $q*=-1 if $q<0}if($x>$=-2){$x=$=-2;$q*=-1 if $q>0}if ((abs($x-($$o{x}- +>()))+1)*( 1+abs($z+1-($$o{z}->())))<9){r(2)?($$o{c}->($n) or $e=1):${$f[$n]}{c}- +>($k);}},d =>sub{$g[20-$z][$x]="O";$g[21-$z][$x]="+";$g[22-$z][$x]="|";for(0..1){ +my@c=($_?( '/','-',"\\"):("\\",'-','/'));$g[21-$z][$x+($_?1:-1)]=$l[$_]?'-':$c[2] +;$g[22-$z- $l[$_]][$x+($_?2:-2)]=$c[2-$l[$_]];$g[23-$z][$x+($_?1:-1)]=$l[2+$_]>1? +'-':$c[2]; $g[24-$z-($l[2+$_]>1?1:0)][$x+($_?2:-2)]=$c[$l[2+$_]>1?1:2];}},z=>sub{ +$z},x=>sub {$x},n=>sub{$n=pop},c=>sub{$h=0;$e=2;$k=pop;$q=0;if(!r(7)){splice@f,$n +,1;for(@f) {$$_{n}->($h++)}}}}}1..$j;while(1){++$iter;if(@f==1){exit 0}for$m(@f){ +$$m{i}->() ;$$m{d}->()}print$/x$=;for $a(1..25){print$/,"|",@{$g[$a]},"|";@{$g[$a +]}=map{' ' }0..$=;}sleep 1}#Optional command-line argument selects how many ninja + stickmen.

My joke generator got a complaint about getting lost in all the map transforms, so in an effort to make my code easier to follow (ahem) I have limited myself to only four occurrances of map in this little project, instead using the trinary operator, a lot of conditionals and comparisons, and far too many variables for such a short program. Enjoy :-)

Oh, you can take out the sleep 1 for hyper speed, if desired, which is useful if you want to use the command-line argument to specify large numbers of fighters. 500 ninjas take too long to duke it out with the sleep statement in.

$;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b->()}} split//,".rekcah lreP rehtona tsuJ";$\=$ ;->();print$/

Replies are listed 'Best First'.
Re: Goofy leaping ninja stickmen
by davido (Cardinal) on Oct 07, 2003 at 21:18 UTC
    Great obfu. Funky!

    Just as a matter of curiosity I tore into it and made a few modifications:

    • Pushed everything that is to be printed into an array so that the script could get away with only one print, with less processing inside the print function, for a little better (maybe?) output efficiency.
    • Changed sleep 1 to select, with a timeout of .2 sec., for smoother action without loss of synchronization.
    • Golfed it down as much as I could without changing logic, flow, or behavior. Saved 82 keystrokes.
    • Reformatted script for seventeen full lines and one partial, plus the shebang.

    Here's the result:

    #!/usr/bin/perl sub r{int rand pop}++$|;@g=map{[map{' '}0..$=]}0..25;my$j=pop||2+r 3; @f=map{my$k=my$n=$b++;my$z=1;my$x=r$=;;my($q,$v,$e)=my@l=(0x4);my$h=r 9;$w={i=>sub{$k=r$j while$k==$n or!$f[$k];my$o=$f[$k];$h+=$e?-1:1;if( $h<1){$e=0;$k=$n}$e=$h>6?1:$e;if(!$z){my$u=$x<$$o{x}()?1:-1;$u*=$e>1? -1:1;$q=$e?$u*r 7:0;$q||=4if$e>1;$v=r 6 if($e&&r(7)>3)}my$t=($$o{z}() cmp$z)+1;$t=0if$x==$$o{x}();my$s=$x<$$o{x}()?1:0;for(0,2){$l[$_+$s]+= $t cmp$l[$_+$s]}for(0,2){$l[$_+($s?0:1)]=0}$v-=2if$z;$x+=$q;$z+=$v;$z =0if$z<0;if($x<2){$x=2;$q*=-1if$q<0}if($x>$=-2){$x=$=-2;$q*=-1if$q>0} if((abs($x-$$o{x}())+1)*(1+abs($z+1-$$o{z}()))<9){r 2?$$o{c}($n)||($e =1):${$f[$n]}{c}($k)}},d=>sub{$g[20-$z][$x]='O';$g[21-$z][$x]='+';$g[ 22-$z][$x]='|';for(0,1){my@c=$_?qw!/ - \\!:qw!\\ - /!;$g[21-$z][$x+($ _?1:-1)]=$l[$_]?'-':$c[2];$g[22-$z-$l[$_]][$x+($_?2:-2)]=$c[2-$l[$_]] ;$g[23-$z][$x+($_?1:-1)]=$l[2+$_]>1?'-':$c[2];$g[24-$z-($l[2+$_]>1?1: 0)][$x+($_?2:-2)]=$c[$l[2+$_]>1?1:2]}},z=>sub{$z},x=>sub{$x},n=>sub{$ n=pop},c=>sub{$h=0;$e=2;$k=pop;$q=0;if(!r(7)){splice@f,$n,1;$$_{n}($h ++)for@f;}}}}1..$j;while(1){exit if@f==1;for$m(@f){$$m{i}();$$m{d}()} my@n;for$a(1..25){push@n,join'',"$/|",@{$g[$a]},'|';@{$g[$a]}=map{' ' }0..$=}print$/x$=,@n;select$c,$c,$c,.2}
    Loved the obfu. Good job! Wading through the maps and logic was quite a challenge. Especially the outtermost map, with a hashtable of subs inside.... ugg, what a mess! That's not a bad thing, in the context of a fantastic obfu. Keep it up!


    "If I had my life to do over again, I'd be a plumber." -- Albert Einstein

      ++ for pointing out that select can be used this way; I had thought it had to do with filehandles, and had not realised this use for it.

      As for the rest of your improvements... well, I'll have to look at those when I have more time.

      update: I've looked at them now, and they all seem pretty straightforward; you just did a more thorough job of golfing than I.

      $;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b->()}} split//,".rekcah lreP rehtona tsuJ";$\=$ ;->();print$/
Explanation of Goofy leaping ninja stickmen
by jonadab (Parson) on Oct 14, 2003 at 16:37 UTC

    Well, I figured someone else would deobfuscate this, but since nobody else has, here's an explantion for posterity. First off, there are really very few clever or sneaky "tricks" in this one to hide what's going on, other than removing the comments and renaming the variables tersely; most of it's just straightforward dense logic and a little golf...

    $;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b->()}} split//,".rekcah lreP rehtona tsuJ";$\=$ ;->();print$/
      tell me how to create stickmen and print them out
Re: Goofy leaping ninja stickmen
by Notromda (Pilgrim) on Oct 14, 2003 at 14:58 UTC
    Ouch. Not going to fall for it this time... I have too much work to do.... must resist....

    Another amazing obfu. ++

A reply falls below the community's threshold of quality. You may see it by logging in.