# AoC Day 17 – Conway Cubes

This is a solution to Advent of Code 2020 day 17, written in Raku.

### Part One

Starting with your given initial configuration, simulate six cycles. How many cubes are left in the active state after the sixth cycle?

#### Raku

I thought about solving this task using native arrays, but indices would need to be offset to accommodate negative coordinates. Instead I used a map of the active cubes, using the coordinates joined together as the keys. The result is a bit messy, alternating between joined and split coordinates. Given that I had to join and split anyway, the solution could have been a little cleaner if I had used Sets instead of Hashes.

  my @input = '17-input.txt'.IO.lines>>.comb;
my $iterations = 6; my %cubes = @input.kv.map( ->$y, @row {
@row.kv.map(
-> $x,$state {
if $state eq '#' { my @value =$x, $y, 0; @value.join(':') => @value } }); }).flat; for ^$iterations {
my @neighbours = %cubes.values.map(
-> $cube-coords { my @relative-coords = ([X] (0, 1, -1) xx 3).skip; @relative-coords.map( ->$rel { $cube-coords >>+>>$rel }
)
}
).flat;
my $neighbour-counts = @neighbours.map(*.join(':')).Bag; my %active =$neighbour-counts.kv.grep(
-> $k,$v {
$v == 3 or$v == 2 && %cubes{$k} } ).flat; %cubes = %active.keys.map( ->$k { $k =>$k.split(':').Array });
}

say "Part One";
say %cubes.elems;
Part One
401


### Part Two

Starting with your given initial configuration, simulate six cycles in a 4-dimensional space. How many cubes are left in the active state after the sixth cycle?

#### Raku

The solution for part two required me to refactor so that I could paramaterise the number of dimensions. The resulting solution for both parts is shown below.

  my @input = '17-input.txt'.IO.lines>>.comb;
my $iterations = 6; sub run(@start,$dimensions) {
my %cubes = @start.kv.map(
-> $y, @row { @row.kv.map( ->$x, $state { if$state eq '#' {
my @value = $x,$y, |(0 xx $dimensions - 2); @value.join(':') => @value } }); }).flat; for ^$iterations {
my @neighbours = %cubes.values.map(
-> $cube-coords { my @relative-coords = ([X] (0, 1, -1) xx$dimensions).skip;
@relative-coords.map(
-> $rel {$cube-coords >>+>> $rel } ) } ).flat; my$neighbour-counts = @neighbours.map(*.join(':')).Bag;
my %active = $neighbour-counts.kv.grep( ->$k, $v {$v == 3 or $v == 2 && %cubes{$k}
}
).flat;
%cubes = %active.keys.map( -> $k {$k => \$k.split(':').Array });
}

return %cubes.elems;
}

say "Part One";
say run(@input, 3);
say "Part Two";
say run(@input, 4);
Part One
401
Part Two
2224


### Review

Of the solutions shared on Reddit, I like 0rac1e's Raku solution the most. Their solution is similar to mine but much more elegant, making use of Tuple as an immutable key. I didn't know about Tuple, written by Elizabeth Mattijsen, which is a really useful module in the ecosystem.