--- symmetry.pl 2007/08/26 14:15:26 6 +++ symmetry.pl 2007/08/31 15:17:11 12 @@ -87,54 +87,15 @@ $visited[$pos]++; } -my ( $tr_x, $tr_y ); -my ( $bl_x, $bl_y ); - sub x_y { my $p = shift; - my $update = 0; - if ( ! defined( $p ) ) { - $p = $pos; - $update = 1; - } + $p ||= $pos; my $y = int($p / ($ll*2)); my $x = int(($p % $ll) / 2); - warn "??? x_y($p) $x,$y tr: $tr_x,$tr_y bl: $bl_x,$bl_y\n"; - - if ( $update ) { - -# $tr_x = $x if $x > $tr_x && $y == $tr_y; -# $tr_y = $y if $y < $tr_y && $x == $tr_x; - - if ( - $y < $tr_y - || - $y <= $tr_y && $x > $tr_x - ) { - ( $tr_x, $tr_y ) = ( $x, $y ); - warn "## UPDATED tr: $tr_x,$tr_y\n"; - } - - if ( - $x < $bl_x - || - $y > $bl_y - ) { - ( $bl_x, $bl_y ) = ( $x, $y ); - warn "## UPDATED bl: $bl_x,$bl_y\n"; - } - -# $bl_x = $x if $x < $bl_x; # && $y == $bl_y; -# $bl_y = $y if $y > $bl_y; # && $x == $bl_x; - - } - - warn "## x_y($p) -> $x,$y ", - $update ? " tr: $tr_x,$tr_y bl: $bl_x,$bl_y" : '', - "\n"; + warn "## x_y($p) -> $x,$y\n"; # return ($x,$y) if wantarray; return "$x,$y"; @@ -157,6 +118,9 @@ my $ok_path = qr/[\|\-]/; +my @corners; +my $corners_usage; + sub can_turn { my $try_step = shift; die "no step?" unless defined $try_step; @@ -172,8 +136,11 @@ $trace[ $turn_pos ] = $old; if ( $board[ $turn_pos ] =~ $ok_path ) { - warn "OK can_turn $try_step $step_name[$try_step] turn_pos = $turn_pos b($board[$turn_pos]) t($trace[$turn_pos])\n"; + my $xy = x_y($pos); + warn "OK can_turn $try_step $step_name[$try_step] turn_pos = $turn_pos b($board[$turn_pos]) t($trace[$turn_pos]) from $xy\n"; $step = $try_step; + push @corners, $xy; + $corners_usage->{$xy}++; return 1; } else { warn "NOPE can_turn $try_step $step_name[$try_step] turn_pos = $turn_pos b($board[$turn_pos]) t($trace[$turn_pos])\n"; @@ -199,19 +166,20 @@ @trace = ($unknown) x ( $#board + 1 ); @directions = (); + @corners = (); trace; my $len = 0; - ( $tr_x, $tr_y ) = ( $x,$y ); - ( $bl_x, $bl_y ) = ( $x,$y ); $step = 0; - if ( $visited[$pos] > 3 ) { - warn "*** shape from $x,$y pos: $pos iterated 4 times, skipping\n"; - return; - } + my $usage = $corners_usage->{"$x,$y"} || 0; - warn "<<< shape from $x,$y pos: $pos\n"; + warn "<<< shape from $x,$y [usage: $usage] pos: $pos\n"; + + if ( $usage > 4 ) { + warn "SKIPPED, usage > 4\n"; + return 0; + } while( 1 ) { @@ -232,8 +200,6 @@ } warn draw; - warn "## tr: $tr_x,$tr_y bl: $bl_x,$bl_y\n"; - if ( $debug ) { print "WAIT> press enter | ",show_directions; my $foo = ; } @@ -241,18 +207,14 @@ push @shapes_found, { x => $x, y => $y, len => $len, directions => show_directions }; - my $tr = "$tr_x,$tr_y"; - my $bl = "$bl_x,$bl_y"; + warn "### corners: ",join(' ', map { $_ . " [" . $corners_usage->{$_} . "]" } @corners),"\n"; + warn ">>> ended at $pos, line length: $len, directions traversed: ",show_directions,"\n"; - warn ">>> ended at $pos, line length: $len, directions traversed: ",show_directions," tr: $tr bl: $bl\n"; - - if ( ! grep( /\Q$tr\E/, @shapes_start ) && $tr_x < 8 ) { - warn "INFO: added $tr top-right\n"; - push @shapes_start, $tr; - } - if ( ! grep( /\Q$bl\E/, @shapes_start ) && $bl_y < 8 ) { - warn "INFO: added $bl bottom-left\n"; - push @shapes_start, $bl; + foreach my $c ( @corners ) { + if ( ! grep( /\Q$c\E/, @shapes_start ) ) { + warn "INFO: added corner $c as shape start\n"; + push @shapes_start, $c; + } } print "WAIT> press enter"; my $foo = ; @@ -261,11 +223,32 @@ } foreach my $start ( @shapes_start ) { - my $len = shape( split(/,/,$start) ); - warn "## $start has $len elements\n"; + my ($x,$y) = split(/,/,$start); + if ( $x < 8 && $y < 8 ) { + my $len = shape( split(/,/,$start) ); + warn "## $start has $len elements\n"; + } else { + warn "SKIPPED $start\n"; + } +} + +sub is_symmetric { + my $path = shift || die "no path?"; + + my $h = length($path)/2; + return 0 if int($h) != $h; + my ($l,$r) = ( substr($path,0,$h), substr($path,$h) ); + $r =~ tr/lrud/rldu/; +# warn "$l -- $r\n"; + return 0 unless $l eq $r; + return 1; } print ">>> RESULTS:\n"; foreach my $r ( @shapes_found ) { - printf "%2d,%-2d len: %-4d directions: %s\n", $r->{x}, $r->{y}, $r->{len}, $r->{directions}; + printf "%2d,%-2d len: %-4d directions: %s %s\n", + $r->{x}, $r->{y}, $r->{len}, + is_symmetric($r->{directions}) ? 'OK' : '!!', + $r->{directions}, + ; }