Day 17 part 2, bash version (and retrofit to part 1)

This commit is contained in:
2021-01-16 18:42:21 +01:00
parent 0ea2309e02
commit 57384c9890
7 changed files with 267 additions and 52 deletions

View File

@@ -7,18 +7,22 @@ CMD=${0##*/}
declare -A life=()
declare -i x=-1 y=-1 z=-1 res=0
declare -i maxx maxy maxz
declare -i max
declare -i loops=6
function print_life() {
local -i x=0 y=0 z=0 foundx foundy
for ((z=0; z<maxz; ++z)); do
for ((z=0; z<max; ++z)); do
foundy=1
for ((y=0; y<maxy; ++y)); do
for ((y=0; y<max; ++y)); do
foundx=1
for ((x=0; x<maxx; ++x)); do
if [[ -v life[$x-$y-$z] ]]; then
for ((x=0; x<max; ++x)); do
if [[ -v life["$x-$y-$z"] ]]; then
#printf "%d-%d-%d:" $x $y $z
printf "%c" ${life["$x-$y-$z"]}
if [[ ${life[$x-$y-$z]} != "#" ]]; then
printf "error"
fi
printf "%c" "${life[$x-$y-$z]}"
foundx=1
else
printf "%c" "."
@@ -31,46 +35,43 @@ function print_life() {
}
function count_neighbors () {
local -i x=$1 y=$2 z=$3 x1 y1 z1 count=0
local str=""
function run_cycle () {
local -i x y z count=0 x1 y1 z1 v
local -A lifetmp=()
local -a values
for ((x1=x-1; x1<x+2; ++x1)); do
for ((y1=y-1; y1<y+2; ++y1)); do
for ((z1=z-1; z1<z+2; ++z1)); do
if ((x1!=x || y1!=y || z1!=z)); then
if [[ ${life[$x1-$y1-$z1]} == "#" ]]; then
((count++))
str="$str $x1-$y1-$z1"
for k in "${!life[@]}"; do
values=(${k//-/ })
x=${values[0]}
y=${values[1]}
z=${values[2]}
for ((x1=x-1; x1<x+2; ++x1)); do
for ((y1=y-1; y1<y+2; ++y1)); do
for ((z1=z-1; z1<z+2; ++z1)); do
if ((x1!=x || y1!=y || z1!=z)); then
((++lifetmp[$x1-$y1-$z1]))
fi
fi
done
done
done
done
#((count)) && printf "neighbours (%d, %d, %d)=%s\n" "$x" "$y" "$z" "$str" >&2
echo "$count"
}
function run_cycle () {
local -i x y z count=0
local -A lifetmp=()
for ((x=0; x<maxx; ++x)); do
for ((y=0; y<maxy; ++y)); do
for ((z=0; z<maxz; ++z)); do
count=$(count_neighbors "$x" "$y" "$z")
if [[ ${life[$x-$y-$z]} == "#" ]]; then
((count!=2 && count!=3)) && lifetmp[$x-$y-$z]="."
else
((count==3)) && lifetmp[$x-$y-$z]="#"
fi
done
done
# clean elements with no neighbors
for k in "${!life[@]}"; do
if [[ ! -v lifetmp[$k] ]]; then
unset "life[$k]"
fi
done
for k in "${!lifetmp[@]}"; do
life[$k]=${lifetmp[$k]}
v=${lifetmp[$k]}
if [[ -v life[$k] ]]; then
(( v!=2 && v!=3 )) && unset "life[$k]"
else
(( v==3 )) && life[$k]="#"
fi
done
}
@@ -86,23 +87,26 @@ function count_active () {
echo "$count"
}
x=6; y=6; z=6
x=$loops; y=$loops; z=$loops
while read -r line; do
if ((y==6)); then # 1st line
((maxx=6+${#line}+6+1))
((maxy=maxx))
((maxz=maxx))
if ((y==loops)); then # 1st line
((max=loops+${#line}+loops+1))
fi
for ((j=0; j<${#line}; ++j)); do
((curx=x+j))
life[$curx-$y-$z]=${line:j:1}
c=${line:j:1}
if [[ $c == "#" ]]; then
life[$curx-$y-$z]=$c
fi
done
((y++))
done
for ((i=0; i<6; ++i)); do
run_cycle
done
res=$(count_active)
#echo "================================="
res=${#life[@]}
printf "%s : res=%d\n" "$CMD" "$res"