Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

How i won a golf set from reg.ru

1,312 views

Published on

Perl programming language "golf" competition. Lightning (5min) talk.

Published in: Technology
  • There are animations in there so download to see them.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

How i won a golf set from reg.ru

  1. 1. How I won a golf set from reg.ru at YAPC::EU 2013 Brian McCauley (nobull) Discussion at http://perlmonks.org/?node_id=1049290
  2. 2. Who am I • Just Another Perl Hacker ™ • I am the one Matt Trout warned you about • Don’t to much Perl in my $dayjob • Still come to YAPC::EU for the community
  3. 3. Perl Golf • Solve a defined problem • Minimal number of characters • No points for best practice • No points for runtime efficiency • No points for originality • No points for obfuscation
  4. 4. The reg.ru challenge • Based on the ancient game of Go • 2 players • Square grid • Place black/white stones • Capture opponent’s stones by surrounding
  5. 5. The reg.ru challenge • 9 x 9 game-state on STDIN • Enumerate capturing moves on STDOUT 1 2 3 4 5 6 7 8 9 1 ¶ 2 x ¶ 3 b w b ¶ 4 b w w b ¶ 5 b b ¶ 6 ¶ 7 x x ¶ 8 w b b w ¶ 9 w b b w w ¶ 2 4¶ 7 9¶
  6. 6. My solution • 205 characters (excluding #!perl) #!perl $b=++$/x11 .<>;for$i(9..99){if(($x=$b)=~s/^(.{$i}) /$1x/s){while($x=~/w/g){$_="$`W$'";1while s/w((?<=W.{10})|(?<=W.)|(?=.{9}W|W))/W/s;/W((?<= .{10})|(?<= .)|(?=.{9} | ))/s||$i=~/./+(print"$& $'n")+last}}}
  7. 7. $b=++$/x11 .<>;$b = ++$/ x 11 . <>; Read in the board • Set $/ to a character that won’t appear • Slurp STDIN including “n” – (1,9) not adjacent (2,1) etc. – Each row 10 characters • Padding so cell (3,5) is in linear position 35 etc. $/=''; $b = '11111111111' . <STDIN>;
  8. 8. Consider each vacant space • Consider, in turn, a copy board with “x” in each empty cell (“ ”) • Record location of “x” in $i for $i ( 9 .. 99 ) { if( ($x = $b) =~ s/^(.{$i}) /$1x/s ) { # Do stuff with $x } } for my $i ( 11 .. 99 ) { if( ( my $x = $b) =~ s/^(.{$i}) /$1x/s ) { # Do stuff with $x } }
  9. 9. Consider each white stone • Consider, in turn, a copy board with one “w” highlighted as “W” • Don’t need index this time while( $x =~ /w/g ) { $_ = "$`W$'"; # Do stuff with $_ } }
  10. 10. Flood fill white stones • Replace “w” adjacent “W” with “W” • Repeat until no more 1 while s/w((?<=W.{10})|(?<=W.)|(?=.{9}W|W))/W/s; while ( # Repeat until fails s/ w # Find 'w' ((?<=W.{10}) | # with a 'W' above (?<=W.) | # or a 'W' to left (?=W) | # or a 'W' to right (?=.{9}W) ) # or a 'W' below /W/xgs # Replace with 'W' ) { }
  11. 11. See if we’ve captured • Find highlighted white stone (“W”) adjacent an empty cell (“ ”). • If none then we’ve captured some stones. /W((?<= .{10})|(?<= .)|(?=.{9} | ))/s || print "Hoorah! We captured some tiles"; unless(/W((?<= .{10})|(?<= .)|(?=.{9} | ))/) { print "Hoorah! We captured some tiles"; }
  12. 12. Output the move • Print the row and column derived from $i . • Padding means these are div and mod 10 • Exit the “consider each white stone” loop. • Row & col are also 1st and 2nd characters. $i=~/./ + ( print "$& $'n" ) + last print int($i/10)," ",$i%10,"n"; last;
  13. 13. All together now #!perl $b = ++$/ x 11 . <>; for $i ( 9 .. 99 ) { if( ( $x = $b ) =~ s/^(.{$i}) /$1x/s ) { while( $x =~ /w/g ) { $_ = "$`W$'"; 1 while s/w((?<=W.{10})|(?<=W.)|(?=.{9}W|W))/W/s; /W((?<= .{10})|(?<= .)|(?=.{9} | ))/ || $i=~/./ + (print "$& $'n") + last } } }
  14. 14. TIMTOWDI #!perl @g=( d..n, map /./gs, <> ); sub n { my($i,$r)=@_; map{ $_=1 and $r=n($i+1)+n($i-1)+ n($i+10)+n($i-10)==1 if /w/; $_=$r=1 and $0=$i if/ / } $g[$i]; $r } map{ $0=~/./ + print "$& $'n" if $g[$_] eq 'w' && n $_ } 0 .. 99
  15. 15. Bonus post-YAPC slide • Now 175! (stole ideas Sergei and Timur) #!perl -ln0 map { $i=$-[0]+11; { map { 1 while s/w((?<=W.{10})|(?<=W.)|(?=.{9}W|W))/W/s; /W((?<= .{10})|(?<= .)|(?=.{9} | ))/s || $i=~/./ + print("$& $'") + last } "$`W$'" while/w/g } } "$`x$'" while/ /g

×