1Math::PlanePath::UlamWaUrsbeurrtCoonn(t3r)ibuted Perl DoMcautmhe:n:tPaltainoenPath::UlamWarburton(3)
2
3
4
6 Math::PlanePath::UlamWarburton -- growth of a 2-D cellular automaton
7
9 use Math::PlanePath::UlamWarburton;
10 my $path = Math::PlanePath::UlamWarburton->new;
11 my ($x, $y) = $path->n_to_xy (123);
12
14 This is the pattern of a cellular automaton studied by Ulam and
15 Warburton, numbering cells by growth tree row and anti-clockwise within
16 the rows.
17
18 94 9
19 95 87 93 8
20 63 7
21 64 42 62 6
22 65 30 61 5
23 66 43 31 23 29 41 60 4
24 69 67 14 59 57 3
25 70 44 68 15 7 13 58 40 56 2
26 96 71 32 16 3 12 28 55 92 1
27 97 88 72 45 33 24 17 8 4 1 2 6 11 22 27 39 54 86 91 <- Y=0
28 98 73 34 18 5 10 26 53 90 -1
29 74 46 76 19 9 21 50 38 52 ... -2
30 75 77 20 85 51 -3
31 78 47 35 25 37 49 84 -4
32 79 36 83 -5
33 80 48 82 -6
34 81 -7
35 99 89 101 -8
36 100 -9
37
38 ^
39 -9 -8 -7 -6 -5 -4 -3 -2 -1 X=0 1 2 3 4 5 6 7 8 9
40
41 The growth rule is that a given cell grows up, down, left and right,
42 but only if the new cell has no neighbours (up, down, left or right).
43 So the initial cell "a" is N=1,
44
45 a initial depth=0 cell
46
47 The next row "b" cells are numbered N=2 to N=5 anti-clockwise from the
48 right,
49
50 b
51 b a b depth=1
52 b
53
54 Likewise the next row "c" cells N=6 to N=9. The "b" cells only grow
55 outwards as 4 "c"s since the other positions would have neighbours in
56 the existing "b"s.
57
58 c
59 b
60 c b a b c depth=2
61 b
62 c
63
64 The "d" cells are then N=10 to N=21, numbered following the previous
65 row "c" cell order and then anti-clockwise around each.
66
67 d
68 d c d
69 d b d
70 d c b a b c d depth=3
71 d b d
72 d c d
73 d
74
75 There's only 4 "e" cells since among the "d"s only the X,Y axes won't
76 have existing neighbours (the "b"s and "d"s).
77
78 e
79 d
80 d c d
81 d b d
82 e d c b a b c d e depth=4
83 d b d
84 d c d
85 d
86 e
87
88 In general the pattern always grows by 1 outward along the X and Y axes
89 and travels into the quarter planes between with a diamond shaped tree
90 pattern which fills 11 of 16 cells in each 4x4 square block.
91
92 Tree Row Ranges
93 Counting depth=0 as the N=1 at the origin and depth=1 as the next
94 N=2,3,4,5 generation, the number of cells in a row is
95
96 rowwidth(0) = 1
97 then
98 rowwidth(depth) = 4 * 3^((count_1_bits(depth) - 1)
99
100 So depth=1 has 4*3^0=4 cells, as does depth=2 at N=6,7,8,9. Then
101 depth=3 has 4*3^1=12 cells N=10 to N=21 because depth=3=0b11 has two
102 1-bits in binary. The N start and end for a row is the cumulative
103 total of those before it,
104
105 Ndepth(depth) = 1 + (rowwidth(0) + ... + rowwidth(depth-1))
106
107 Nend(depth) = rowwidth(0) + ... + rowwidth(depth)
108
109 For example depth 3 ends at N=(1+4+4)=9.
110
111 depth Ndepth rowwidth Nend
112 0 1 1 1
113 1 2 4 5
114 2 6 4 9
115 3 10 12 21
116 4 22 4 25
117 5 26 12 37
118 6 38 12 49
119 7 50 36 85
120 8 86 4 89
121 9 90 12 101
122
123 For a power-of-2 depth the Ndepth is
124
125 Ndepth(2^a) = 2 + 4*(4^a-1)/3
126
127 For example depth=4=2^2 starts at N=2+4*(4^2-1)/3=22, or depth=8=2^3
128 starts N=2+4*(4^3-1)/3=86.
129
130 Further bits in the depth value contribute powers-of-4 with a tripling
131 for each bit above. So if the depth number has bits a,b,c,d,etc in
132 descending order,
133
134 depth = 2^a + 2^b + 2^c + 2^d ... a>b>c>d...
135 Ndepth = 2 + 4*(-1
136 + 4^a
137 + 3 * 4^b
138 + 3^2 * 4^c
139 + 3^3 * 4^d + ... ) / 3
140
141 For example depth=6 = 2^2+2^1 is Ndepth = 2 + (1+4*(4^2-1)/3) + 4^(1+1)
142 = 38. Or depth=7 = 2^2+2^1+2^0 is Ndepth = 1 + (1+4*(4^2-1)/3) +
143 4^(1+1) + 3*4^(0+1) = 50.
144
145 Self-Similar Replication
146 The diamond shape depth=1 to depth=2^level-1 repeats three times. For
147 example an "a" part going to the right of the origin "O",
148
149 d
150 d d d
151 | a d c
152 --O a a a * c c c ...
153 | a b c
154 b b b
155 b
156
157 The 2x2 diamond shaped "a" repeats pointing up, down and right as "b",
158 "c" and "d". This resulting 4x4 diamond then likewise repeats up, down
159 and right. The same happens in the other quarters of the plane.
160
161 The points in the path here are numbered by tree rows rather than in
162 this sort of replication, but the replication helps to see the
163 structure of the pattern.
164
165 Half Plane
166 Option "parts => '2'" confines the pattern to the upper half plane
167 "Y>=0",
168
169 parts => "2"
170
171 28 6
172 21 5
173 29 22 16 20 27 4
174 11 3
175 30 12 6 10 26 2
176 23 13 3 9 19 1
177 31 24 17 14 7 4 1 2 5 8 15 18 25 <- Y=0
178 --------------------------------------
179 -6 -5 -4 -3 -2 -1 X=0 1 2 3 4 5 6
180
181 Points are still numbered anti-clockwise around so X axis
182 N=1,2,5,8,15,etc is the first of row depth=X. X negative axis
183 N=1,4,7,14,etc is the last of row depth=-X. For depth=0 point N=1 is
184 both the first and last of that row.
185
186 Within a row a line from point N to N+1 is always a 45-degree angle.
187 This is true of each 3 direct children, but also across groups of
188 children by symmetry. For this parts=2 the lines from the last of one
189 row to the first of the next are horizontal, making an attractive
190 pattern of diagonals and then across to the next row horizontally. For
191 parts=4 or parts=1 the last to first lines are at various different
192 slopes and so upsets the pattern.
193
194 One Quadrant
195 Option "parts => '1'" confines the pattern to the first quadrant,
196
197 parts => "1" to depth=14
198
199 14 | 73
200 13 | 63
201 12 | 53 62 72
202 11 | 49
203 10 | 39 48 71
204 9 | 35 47 61
205 8 | 31 34 38 46 52 60 70
206 7 | 29 45 59
207 6 | 19 28 69 67
208 5 | 15 27 57
209 4 | 11 14 18 26 68 58 51 56 66
210 3 | 9 25 23 43
211 2 | 5 8 24 17 22 44 37 42 65
212 1 | 3 7 13 21 33 41 55
213 Y=0 | 1 2 4 6 10 12 16 20 30 32 36 40 50 54 64
214 +-----------------------------------------------
215 X=0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
216
217 X axis N=1,2,4,6,10,etc is the first of each row X=depth. Y axis
218 N=1,3,5,9,11,etc is the last similarly Y=depth.
219
220 In this arrangement horizontal arms have even N and vertical arms have
221 odd N. For example the vertical at X=8 N=30,33,37,etc has N odd from
222 N=33 up and when it turns to horizontal at N=42 or N=56 it switches to
223 N even. The children of N=66 are not shown but the verticals from
224 there are N=79 below and N=81 above and so switch to odd again.
225
226 This odd/even pattern is true of N=2 horizontal and N=3 vertical and
227 thereafter is true due to each row having an even number of points and
228 the self-similar replications in the pattern,
229
230 |\ replication
231 | \ block 0 to 1 and 3
232 |3 \ and block 0 block 2 less sides
233 |----
234 |\ 2|\
235 | \ | \
236 |0 \|1 \
237 ---------
238
239 Block 0 is the base and is replicated as block 1 and in reverse as
240 block 3. Block 2 is a further copy of block 0, but the two halves of
241 block 0 rotated inward 90 degrees, so the X axis of block 0 becomes the
242 vertical of block 2, and the Y axis of block 0 the horizontal of block
243 2. Those axis parts are dropped since they're already covered by block
244 1 and 3 and dropping them flips the odd/even parity to match the
245 vertical/horizontal flip due to the 90-degree rotation.
246
247 Octant
248 Option "parts => 'octant'" confines the pattern to the first eighth of
249 the plane 0<=Y<=X.
250
251 parts => "octant"
252
253 7 | 47 ...
254 6 | 48 36 46
255 5 | 49 31 45
256 4 | 50 37 32 27 30 35 44
257 3 | 14 51 24 43 41
258 2 | 15 10 13 25 20 23 42 34 40
259 1 | 5 8 12 18 22 29 39
260 Y=0 | 1 2 3 4 6 7 9 11 16 17 19 21 26 28 33 38
261 +-------------------------------------------------
262 X=0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
263
264 In this arrangement N=1,2,3,4,6,7,etc on the X axis is the first N of
265 each row ("tree_depth_to_n()").
266
267 Upper Octant
268 Option "parts => 'octant_up'" confines the pattern to the upper octant
269 0<=X<=Y of the first quadrant.
270
271 parts => "octant_up"
272
273 8 | 16 17 19 22 26 29 34 42
274 7 | 15 21 28 41
275 6 | 10 14 38 33 40
276 5 | 8 13 39
277 4 | 6 7 9 12
278 3 | 5 11
279 2 | 3 4
280 1 | 2
281 Y=0 | 1
282 +--------------------------
283 X=0 1 2 3 4 5 6 7
284
285 In this arrangement N=1,2,3,5,6,8,etc on the Y axis the last N of each
286 row ("tree_depth_to_n_end()").
287
288 N Start
289 The default is to number points starting N=1 as shown above. An
290 optional "n_start" can give a different start, in the same pattern.
291 For example to start at 0,
292
293 n_start => 0
294
295 29 5
296 30 22 28 4
297 13 3
298 14 6 12 2
299 31 15 2 11 27 1
300 32 23 16 7 3 0 1 5 10 21 26 <- Y=0
301 33 17 4 9 25 -1
302 18 8 20 37 -2
303 19 -3
304 34 24 36 -4
305 35 -5
306
307 ^
308 -5 -4 -3 -2 -1 X=0 1 2 3 4 5
309
311 See "FUNCTIONS" in Math::PlanePath for behaviour common to all path
312 classes.
313
314 "$path = Math::PlanePath::UlamWarburton->new ()"
315 "$path = Math::PlanePath::UlamWarburton->new (parts => $str, n_start =>
316 $n)"
317 Create and return a new path object. The "parts" option (a string)
318 can be
319
320 "4" the default
321 "2"
322 "1"
323
324 Tree Methods
325 "@n_children = $path->tree_n_children($n)"
326 Return the children of $n, or an empty list if $n has no children
327 (including when "$n < 1", ie. before the start of the path).
328
329 The children are the cells turned on adjacent to $n at the next
330 row. The way points are numbered means that when there's multiple
331 children they're consecutive N values, for example at N=6 the
332 children are 10,11,12.
333
334 Tree Descriptive Methods
335 "@nums = $path->tree_num_children_list()"
336 Return a list of the possible number of children in $path. This is
337 the set of possible return values from "tree_n_num_children()".
338 The possible children varies with the "parts",
339
340 parts tree_num_children_list()
341 ----- ------------------------
342 4 0, 1, 3, 4 (the default)
343 2 0, 1, 2, 3
344 1 0, 1, 2, 3
345
346 parts=4 has 4 children at the origin N=0 and thereafter either 0, 1
347 or 3.
348
349 parts=2 and parts=1 can have 2 children on the boundaries where the
350 3rd child is chopped off, otherwise 0, 1 or 3.
351
352 "$n_parent = $path->tree_n_parent($n)"
353 Return the parent node of $n, or "undef" if "$n <= 1" (the start of
354 the path).
355
356 Level Methods
357 "($n_lo, $n_hi) = $path->level_to_n_range($level)"
358 Return "$n_lo = $n_start" and
359
360 parts $n_hi
361 ----- -----
362 4 $n_start + (16*4**$level - 4) / 3
363 2 $n_start + ( 8*4**$level - 5) / 3 + 2*2**$level
364 1 $n_start + ( 4*4**$level - 4) / 3 + 2*2**$level
365
366 $n_hi is "tree_depth_to_n_end(2**($level+1) - 1".
367
369 This cellular automaton is in Sloane's Online Encyclopedia of Integer
370 Sequences as
371
372 <http://oeis.org/A147582> (etc)
373
374 parts=4
375 A147562 total cells to depth, being tree_depth_to_n() n_start=0
376 A147582 added cells at depth
377
378 parts=2
379 A183060 total cells to depth=n in half plane
380 A183061 added cells at depth=n
381
382 parts=1
383 A151922 total cells to depth=n in quadrant
384 A079314 added cells at depth=n
385
386 The A147582 new cells sequence starts from n=1, so takes the innermost
387 N=1 single cell as row n=1, then N=2,3,4,5 as row n=2 with 5 cells,
388 etc. This makes the formula a binary 1-bits count on n-1 rather than
389 on N the way rowwidth() above is expressed.
390
391 The 1-bits-count power 3^(count_1_bits(depth)) part of the rowwidth()
392 is also separately in A048883, and as n-1 in A147610.
393
395 Math::PlanePath, Math::PlanePath::UlamWarburtonQuarter,
396 Math::PlanePath::LCornerTree, Math::PlanePath::CellularRule
397
398 Math::PlanePath::SierpinskiTriangle (a similar binary 1s-count related
399 calculation)
400
402 <http://user42.tuxfamily.org/math-planepath/index.html>
403
405 Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 Kevin Ryde
406
407 This file is part of Math-PlanePath.
408
409 Math-PlanePath is free software; you can redistribute it and/or modify
410 it under the terms of the GNU General Public License as published by
411 the Free Software Foundation; either version 3, or (at your option) any
412 later version.
413
414 Math-PlanePath is distributed in the hope that it will be useful, but
415 WITHOUT ANY WARRANTY; without even the implied warranty of
416 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
417 General Public License for more details.
418
419 You should have received a copy of the GNU General Public License along
420 with Math-PlanePath. If not, see <http://www.gnu.org/licenses/>.
421
422
423
424perl v5.32.0 2020-07-28 Math::PlanePath::UlamWarburton(3)