/[symmetry-circle]/symmetry.pl
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /symmetry.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 12 - (hide annotations)
Fri Aug 31 15:17:11 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 5092 byte(s)
fix shape to return 0 if shape is skipped fixing warning
1 dpavlin 1 #!/usr/bin/perl -w
2    
3     # symmetry.pl
4     #
5     # 08/26/07 02:40:37 CEST Dobrica Pavlinusic <dpavlin@rot13.org>
6    
7     use strict;
8    
9     my $board = << '_BOARD_';
10     +-+-+-+-+-+-+-+-+
11     | | |o| | |
12     + + +-+ +-+ |
13     |o| | o | o |
14     + + +-+ +-+ |
15     | | o | | |
16     +-+-+ +-+-+-+-+
17     | | |o| |
18     +-+ + +-+-+ +-+
19     | |o| |o|o|o|o|
20     + + +-+-+-+-+ +-+
21     |o| | | |
22     + +-+-+-+-+-+-+-+
23     | | o |
24     +-+-+-+-+-+-+-+-+
25     | o | o |
26     +-+-+-+-+-+-+-+-+
27     _BOARD_
28    
29 dpavlin 4 my $debug = shift @ARGV || 0;
30    
31 dpavlin 1 my @board = map { split(//) } split(/\n/, $board);
32 dpavlin 3 my @trace;
33 dpavlin 6 my @visited = (' ') x ($#board + 1);
34 dpavlin 1
35     # line length
36     my $ll = 8 * 2 + 1;
37    
38 dpavlin 3 my @step_name = ( qw/right down left up/ );
39     my @move_by = ( 1, $ll, -1, -$ll );
40     my $step = 0; # right
41    
42     # offset 0, top-left corner
43     my $pos = 0;
44    
45     # unknown trace position
46     my $unknown = ' ';
47    
48 dpavlin 4 # path traversed
49     my @directions;
50    
51 dpavlin 5 my @shapes_found;
52 dpavlin 4
53 dpavlin 5 my @shapes_start = ( '0,0' ); #( qw/0,0 1,0 0,3/ );
54    
55 dpavlin 1 sub draw {
56     my $o = 0;
57 dpavlin 6 my $out = "\n " . join('',
58     ('0 1 2 3 4 5 6 7 8 | ') x 3
59     ) . "\n";
60 dpavlin 1 while ( $o < $#board ) {
61 dpavlin 6 my $l = '|';
62     if ( $o % ($ll*2) == 0) {
63     my $y = int($o / ($ll*2));
64     $out .= "$y ";
65     $l = $y;
66     } else {
67     $out .= " ";
68     }
69    
70 dpavlin 3 $out .= join('', @board[ $o .. $o + $ll - 1 ]);
71 dpavlin 6 $out .= " $l ";
72 dpavlin 3 $out .= join('', @trace[ $o .. $o + $ll - 1 ]);
73 dpavlin 6 $out .= " $l ";
74     $out .= join('', @visited[ $o .. $o + $ll - 1 ]);
75     $out .= " $l\n";
76 dpavlin 1 $o += $ll;
77     }
78 dpavlin 6
79     $out .= "\n";
80    
81 dpavlin 1 return $out;
82     }
83    
84     sub trace {
85 dpavlin 3 warn "## trace $pos\n";
86 dpavlin 1 $trace[ $pos ] = $board[ $pos ];
87 dpavlin 6 $visited[$pos]++;
88 dpavlin 1 }
89    
90 dpavlin 6 sub x_y {
91     my $p = shift;
92 dpavlin 5
93 dpavlin 7 $p ||= $pos;
94 dpavlin 5
95 dpavlin 6 my $y = int($p / ($ll*2));
96     my $x = int(($p % $ll) / 2);
97 dpavlin 5
98 dpavlin 7 warn "## x_y($p) -> $x,$y\n";
99 dpavlin 5
100 dpavlin 6 # return ($x,$y) if wantarray;
101 dpavlin 5 return "$x,$y";
102     }
103    
104 dpavlin 1 sub move {
105     $pos += $move_by[ $step ];
106     trace;
107     $pos += $move_by[ $step ];
108     trace;
109 dpavlin 4 push @directions, $step;
110 dpavlin 6 warn "move $step $step_name[$step] to ", x_y, "\n";
111 dpavlin 1 }
112    
113     sub follow {
114     $step = shift;
115     $step %= 4;
116     warn "follow $step $step_name[$step]\n";
117     }
118    
119     my $ok_path = qr/[\|\-]/;
120    
121 dpavlin 7 my @corners;
122 dpavlin 9 my $corners_usage;
123 dpavlin 7
124 dpavlin 1 sub can_turn {
125 dpavlin 2 my $try_step = shift;
126     die "no step?" unless defined $try_step;
127 dpavlin 1
128 dpavlin 2 $try_step %= 4;
129 dpavlin 1
130 dpavlin 2 my $turn_pos = $pos + $move_by[$try_step];
131    
132 dpavlin 1 my $old = $trace[ $turn_pos ];
133     $trace[ $turn_pos ] = '?';
134 dpavlin 6 $trace[ $pos ] = '*';
135     warn "TEST ", x_y($turn_pos), "\n",draw;
136 dpavlin 1 $trace[ $turn_pos ] = $old;
137    
138     if ( $board[ $turn_pos ] =~ $ok_path ) {
139 dpavlin 8 my $xy = x_y($pos);
140     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";
141 dpavlin 2 $step = $try_step;
142 dpavlin 7 push @corners, $xy;
143 dpavlin 9 $corners_usage->{$xy}++;
144 dpavlin 1 return 1;
145     } else {
146 dpavlin 5 warn "NOPE can_turn $try_step $step_name[$try_step] turn_pos = $turn_pos b($board[$turn_pos]) t($trace[$turn_pos])\n";
147 dpavlin 1 return 0;
148     }
149     }
150    
151 dpavlin 4 sub show_directions {
152     return
153     join('',
154     map {
155     substr($step_name[$_],0,1)
156     } @directions
157     )
158     ;
159     }
160    
161 dpavlin 3 sub shape {
162 dpavlin 1
163 dpavlin 3 my ($x,$y) = @_;
164 dpavlin 1
165 dpavlin 3 $pos = $y * $ll * 2 + $x * 2;
166    
167     @trace = ($unknown) x ( $#board + 1 );
168 dpavlin 4 @directions = ();
169 dpavlin 7 @corners = ();
170 dpavlin 3 trace;
171    
172     my $len = 0;
173 dpavlin 6 $step = 0;
174 dpavlin 3
175 dpavlin 9 my $usage = $corners_usage->{"$x,$y"} || 0;
176 dpavlin 6
177 dpavlin 9 warn "<<< shape from $x,$y [usage: $usage] pos: $pos\n";
178    
179     if ( $usage > 4 ) {
180     warn "SKIPPED, usage > 4\n";
181 dpavlin 12 return 0;
182 dpavlin 9 }
183    
184 dpavlin 3 while( 1 ) {
185    
186     my $next_pos = $pos + $move_by[ $step ];
187 dpavlin 4 warn "# pos: $pos next_pos: $next_pos step: $step $step_name[$step] trace: ",show_directions,"\n";
188 dpavlin 3
189     if ( $trace[ $next_pos ] ne $unknown ) {
190     warn "position $next_pos re-visited, exiting\n";
191     last;
192     } elsif ( $board[ $next_pos ] =~ $ok_path ) {
193     warn "OK next_pos = $next_pos b($board[$next_pos]) t($trace[$next_pos])\n";
194     move;
195     $len++;
196     can_turn( $step + 1 );
197     } else {
198     warn "find line continuation from $step $step_name[$step]...\n";
199     can_turn( $step - 1 ) || can_turn( $step + 1 ) || die "can't find new direction";
200     }
201 dpavlin 6 warn draw;
202 dpavlin 3
203 dpavlin 4 if ( $debug ) {
204     print "WAIT> press enter | ",show_directions; my $foo = <STDIN>;
205     }
206 dpavlin 1 }
207    
208 dpavlin 5 push @shapes_found, { x => $x, y => $y, len => $len, directions => show_directions };
209 dpavlin 4
210 dpavlin 9 warn "### corners: ",join(' ', map { $_ . " [" . $corners_usage->{$_} . "]" } @corners),"\n";
211 dpavlin 7 warn ">>> ended at $pos, line length: $len, directions traversed: ",show_directions,"\n";
212 dpavlin 5
213 dpavlin 7 foreach my $c ( @corners ) {
214     if ( ! grep( /\Q$c\E/, @shapes_start ) ) {
215     warn "INFO: added corner $c as shape start\n";
216     push @shapes_start, $c;
217     }
218 dpavlin 5 }
219    
220 dpavlin 4 print "WAIT> press enter"; my $foo = <STDIN>;
221    
222 dpavlin 3 return $len;
223 dpavlin 1 }
224    
225 dpavlin 5 foreach my $start ( @shapes_start ) {
226 dpavlin 7 my ($x,$y) = split(/,/,$start);
227     if ( $x < 8 && $y < 8 ) {
228     my $len = shape( split(/,/,$start) );
229     warn "## $start has $len elements\n";
230     } else {
231     warn "SKIPPED $start\n";
232     }
233 dpavlin 3 }
234 dpavlin 4
235 dpavlin 10 sub is_symmetric {
236     my $path = shift || die "no path?";
237    
238     my $h = length($path)/2;
239     return 0 if int($h) != $h;
240     my ($l,$r) = ( substr($path,0,$h), substr($path,$h) );
241     $r =~ tr/lrud/rldu/;
242     # warn "$l -- $r\n";
243     return 0 unless $l eq $r;
244     return 1;
245     }
246    
247 dpavlin 4 print ">>> RESULTS:\n";
248 dpavlin 5 foreach my $r ( @shapes_found ) {
249 dpavlin 10 printf "%2d,%-2d len: %-4d directions: %s %s\n",
250 dpavlin 11 $r->{x}, $r->{y}, $r->{len},
251     is_symmetric($r->{directions}) ? 'OK' : '!!',
252     $r->{directions},
253     ;
254 dpavlin 4 }

Properties

Name Value
svn:executable

  ViewVC Help
Powered by ViewVC 1.1.26