1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
# Day Seventeen: Conway Cubes
import std/os, std/sets, std/enumerate
let input: string = paramStr(1)
type Coord = tuple[x,y,z,w: int]
# Coordinate system: 0,0 is at the top left
var dimension: HashSet[Coord]
for y, line in enumerate(lines(input)):
for x, cube in line:
if cube == '#':
dimension.incl((x,y,0,0))
# stdout.write(x, ",", y, " ")
# stdout.write(cube)
# stdout.write('\n')
# echo(dimension)
## Return a tuple describing a dimension's largest axes
func maximum(dim: HashSet[Coord]): tuple[x,y,z,w: int] =
result = (0,0,0,0)
for cube in dim:
if abs(cube.x) > result.x: result.x = abs(cube.x)
if abs(cube.y) > result.y: result.y = abs(cube.y)
if abs(cube.z) > result.z: result.z = abs(cube.z)
if abs(cube.w) > result.w: result.w = abs(cube.w)
## Return the number of cubes neighboring an arbitary point in space
func neighbors(cube: Coord, dim: HashSet[Coord]): int =
result = 0
for x in -1 .. 1:
for y in -1 .. 1:
for z in -1 .. 1:
for w in -1 .. 1:
if ((cube.x+x, cube.y+y, cube.z+z, cube.w+w) in dim) and ((x,y,z,w) != (0,0,0,0)):
inc(result)
## Run one cycle of a pocket dimension
func cycle(dim: HashSet[Coord]): HashSet[Coord] =
let max = maximum(dim)
for x in -max.x-1 .. max.x+1:
for y in -max.y-1 .. max.y+1:
for z in -max.z-1 .. max.z+1:
for w in -max.w-1 .. max.w+1:
let coord = (x,y,z,w)
if coord in dim:
if coord.neighbors(dim) == 2 or coord.neighbors(dim) == 3:
result.incl(coord)
if coord notin dim:
if coord.neighbors(dim) == 3:
result.incl(coord)
func cycle(dim: HashSet[Coord], reps: int): HashSet[Coord] =
result = dim
for i in 1 .. reps:
result = cycle(result)
## Visualize output
proc echo(dim: HashSet[Coord]) =
let max = maximum(dim)
for w in -max.w .. max.w:
for z in -max.z .. max.z:
stdout.write("z=", z, ", ", "w=", w, '\n')
for y in -max.y .. max.y:
for x in -max.x .. max.x:
if (x,y,z,w) == (0,0,0,0):
stdout.write('0')
elif (x,y,z,w) in dim:
stdout.write('#')
else:
stdout.write('.')
stdout.write('\n')
stdout.write('\n')
echo len(dimension.cycle(6))
|