/[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

Contents of /symmetry.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 11 - (show annotations)
Fri Aug 31 14:28:27 2007 UTC (11 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 5090 byte(s)
better output if directions are symmetric
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 my $debug = shift @ARGV || 0;
30
31 my @board = map { split(//) } split(/\n/, $board);
32 my @trace;
33 my @visited = (' ') x ($#board + 1);
34
35 # line length
36 my $ll = 8 * 2 + 1;
37
38 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 # path traversed
49 my @directions;
50
51 my @shapes_found;
52
53 my @shapes_start = ( '0,0' ); #( qw/0,0 1,0 0,3/ );
54
55 sub draw {
56 my $o = 0;
57 my $out = "\n " . join('',
58 ('0 1 2 3 4 5 6 7 8 | ') x 3
59 ) . "\n";
60 while ( $o < $#board ) {
61 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 $out .= join('', @board[ $o .. $o + $ll - 1 ]);
71 $out .= " $l ";
72 $out .= join('', @trace[ $o .. $o + $ll - 1 ]);
73 $out .= " $l ";
74 $out .= join('', @visited[ $o .. $o + $ll - 1 ]);
75 $out .= " $l\n";
76 $o += $ll;
77 }
78
79 $out .= "\n";
80
81 return $out;
82 }
83
84 sub trace {
85 warn "## trace $pos\n";
86 $trace[ $pos ] = $board[ $pos ];
87 $visited[$pos]++;
88 }
89
90 sub x_y {
91 my $p = shift;
92
93 $p ||= $pos;
94
95 my $y = int($p / ($ll*2));
96 my $x = int(($p % $ll) / 2);
97
98 warn "## x_y($p) -> $x,$y\n";
99
100 # return ($x,$y) if wantarray;
101 return "$x,$y";
102 }
103
104 sub move {
105 $pos += $move_by[ $step ];
106 trace;
107 $pos += $move_by[ $step ];
108 trace;
109 push @directions, $step;
110 warn "move $step $step_name[$step] to ", x_y, "\n";
111 }
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 my @corners;
122 my $corners_usage;
123
124 sub can_turn {
125 my $try_step = shift;
126 die "no step?" unless defined $try_step;
127
128 $try_step %= 4;
129
130 my $turn_pos = $pos + $move_by[$try_step];
131
132 my $old = $trace[ $turn_pos ];
133 $trace[ $turn_pos ] = '?';
134 $trace[ $pos ] = '*';
135 warn "TEST ", x_y($turn_pos), "\n",draw;
136 $trace[ $turn_pos ] = $old;
137
138 if ( $board[ $turn_pos ] =~ $ok_path ) {
139 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 $step = $try_step;
142 push @corners, $xy;
143 $corners_usage->{$xy}++;
144 return 1;
145 } else {
146 warn "NOPE can_turn $try_step $step_name[$try_step] turn_pos = $turn_pos b($board[$turn_pos]) t($trace[$turn_pos])\n";
147 return 0;
148 }
149 }
150
151 sub show_directions {
152 return
153 join('',
154 map {
155 substr($step_name[$_],0,1)
156 } @directions
157 )
158 ;
159 }
160
161 sub shape {
162
163 my ($x,$y) = @_;
164
165 $pos = $y * $ll * 2 + $x * 2;
166
167 @trace = ($unknown) x ( $#board + 1 );
168 @directions = ();
169 @corners = ();
170 trace;
171
172 my $len = 0;
173 $step = 0;
174
175 my $usage = $corners_usage->{"$x,$y"} || 0;
176
177 warn "<<< shape from $x,$y [usage: $usage] pos: $pos\n";
178
179 if ( $usage > 4 ) {
180 warn "SKIPPED, usage > 4\n";
181 return;
182 }
183
184 while( 1 ) {
185
186 my $next_pos = $pos + $move_by[ $step ];
187 warn "# pos: $pos next_pos: $next_pos step: $step $step_name[$step] trace: ",show_directions,"\n";
188
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 warn draw;
202
203 if ( $debug ) {
204 print "WAIT> press enter | ",show_directions; my $foo = <STDIN>;
205 }
206 }
207
208 push @shapes_found, { x => $x, y => $y, len => $len, directions => show_directions };
209
210 warn "### corners: ",join(' ', map { $_ . " [" . $corners_usage->{$_} . "]" } @corners),"\n";
211 warn ">>> ended at $pos, line length: $len, directions traversed: ",show_directions,"\n";
212
213 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 }
219
220 print "WAIT> press enter"; my $foo = <STDIN>;
221
222 return $len;
223 }
224
225 foreach my $start ( @shapes_start ) {
226 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 }
234
235 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 print ">>> RESULTS:\n";
248 foreach my $r ( @shapes_found ) {
249 printf "%2d,%-2d len: %-4d directions: %s %s\n",
250 $r->{x}, $r->{y}, $r->{len},
251 is_symmetric($r->{directions}) ? 'OK' : '!!',
252 $r->{directions},
253 ;
254 }

Properties

Name Value
svn:executable

  ViewVC Help
Powered by ViewVC 1.1.26