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

18
OUTPUT
View File

@@ -381,3 +381,21 @@ ex2.bash : res=650080463519
ex2-c : res=650080463519
time: 0:00.00 real, 0.00 user, 0.00 sys
context-switch: 0+1, page-faults: 0+71
=========================================
================= day17 =================
=========================================
+++++++++++++++++ ex1
ex1-v1.bash : res=263
time: 1:25.64 real, 61.31 user, 30.44 sys
context-switch: 5732+166356, page-faults: 0+7279275
ex1.bash : res=263
time: 0:00.40 real, 0.40 user, 0.00 sys
context-switch: 41+1, page-faults: 0+315
+++++++++++++++++ ex2
ex2.bash : res=1680
time: 0:07.88 real, 7.87 user, 0.00 sys
context-switch: 815+1, page-faults: 0+2637

View File

@@ -16,11 +16,12 @@ output:
compile: ex1-c ex2-c
ex1:
@$(TIME) ex1-v1.bash < $(INPUT) 2>&1
@$(TIME) ex1.bash < $(INPUT) 2>&1
@#$(TIME) ex1-c 2020 < $(INPUT) 2>&1
ex2:
@#$(TIME) ex2.bash < $(INPUT) 2>&1
@$(TIME) ex2.bash < $(INPUT) 2>&1
@#$(TIME) ex1-c 30000000 < $(INPUT) 2>&1
clean:

View File

@@ -1,4 +1,11 @@
ex1.bash : res=263
time: 1:24.06 real, 60.13 user, 30.29 sys
context-switch: 5369+166373, page-faults: 0+7362621
ex1-v1.bash : res=263
time: 1:25.64 real, 61.31 user, 30.44 sys
context-switch: 5732+166356, page-faults: 0+7279275
ex1.bash : res=263
time: 0:00.40 real, 0.40 user, 0.00 sys
context-switch: 41+1, page-faults: 0+315
ex2.bash : res=1680
time: 0:07.88 real, 7.87 user, 0.00 sys
context-switch: 815+1, page-faults: 0+2637

View File

@@ -145,8 +145,6 @@ After the full six-cycle boot process completes, 112 cubes are left in the activ
Starting with your given initial configuration, simulate six cycles. How many cubes are left in the active state after the sixth cycle?
Your puzzle answer was 263.
The first half of this puzzle is complete! It provides one gold star: *
--- Part Two ---
For some reason, your simulated results don't match what the experimental energy source engineers expected. Apparently, the pocket dimension actually has four spatial dimensions, not three.
@@ -398,8 +396,12 @@ After the full six-cycle boot process completes, 848 cubes are left in the activ
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?
Answer:
Your puzzle answer was 1680.
Although it hasn't changed, you can still get your puzzle input.
Both parts of this puzzle are complete! They provide two gold stars: **
At this point, you should return to your Advent calendar and try another puzzle.
If you still want to see it, you can get your puzzle input.
You can also [Share] this puzzle.

109
day17/ex1-v1.bash Executable file
View File

@@ -0,0 +1,109 @@
#!/bin/bash
#
# ex1.bash: Advent2020 game, day 17/game 1.
CMD=${0##*/}
#shopt -s extglob
declare -A life=()
declare -i x=-1 y=-1 z=-1 res=0
declare -i maxx maxy maxz
function print_life() {
local -i x=0 y=0 z=0 foundx foundy
for ((z=0; z<maxz; ++z)); do
foundy=1
for ((y=0; y<maxy; ++y)); do
foundx=1
for ((x=0; x<maxx; ++x)); do
if [[ -v life[$x-$y-$z] ]]; then
#printf "%d-%d-%d:" $x $y $z
printf "%c" ${life["$x-$y-$z"]}
foundx=1
else
printf "%c" "."
fi
done
((foundx==1)) && foundy=1 && printf "\n"
done
((foundy==1)) && printf "z=%d\n\n" "$z"
done
}
function count_neighbors () {
local -i x=$1 y=$2 z=$3 x1 y1 z1 count=0
local str=""
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"
fi
fi
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
done
for k in "${!lifetmp[@]}"; do
life[$k]=${lifetmp[$k]}
done
}
function count_active () {
local k
local -i count=0
for k in "${!life[@]}"; do
if [[ ${life[$k]} == "#" ]]; then
((count++))
fi
done
echo "$count"
}
x=6; y=6; z=6
while read -r line; do
if ((y==6)); then # 1st line
((maxx=6+${#line}+6+1))
((maxy=maxx))
((maxz=maxx))
fi
for ((j=0; j<${#line}; ++j)); do
((curx=x+j))
life[$curx-$y-$z]=${line:j:1}
done
((y++))
done
for ((i=0; i<6; ++i)); do
run_cycle
done
res=$(count_active)
printf "%s : res=%d\n" "$CMD" "$res"
exit 0

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 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
if [[ ${life[$x1-$y1-$z1]} == "#" ]]; then
((count++))
str="$str $x1-$y1-$z1"
fi
((++lifetmp[$x1-$y1-$z1]))
fi
done
done
done
#((count)) && printf "neighbours (%d, %d, %d)=%s\n" "$x" "$y" "$z" "$str" >&2
echo "$count"
}
done
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]="#"
# clean elements with no neighbors
for k in "${!life[@]}"; do
if [[ ! -v lifetmp[$k] ]]; then
unset "life[$k]"
fi
done
done
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"

74
day17/ex2.bash Executable file
View File

@@ -0,0 +1,74 @@
#!/bin/bash
#
# ex1.bash: Advent2020 game, day 17/game 1.
CMD=${0##*/}
#shopt -s extglob
declare -A life=()
declare -i x=-1 y=-1 z=-1 w=-1 res=0
declare -i loops=6
function run_cycle () {
local -i x y z w x1 y1 z1 w1 v
local -A lifetmp=()
local -a values
for k in "${!life[@]}"; do
# shellcheck disable=SC2206
values=(${k//-/ })
x=${values[0]}
y=${values[1]}
z=${values[2]}
w=${values[3]}
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
for ((w1=w-1; w1<w+2; ++w1)); do
if ((x1!=x || y1!=y || z1!=z || w1!=w)); then
((++lifetmp[$x1-$y1-$z1-$w1]))
fi
done
done
done
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
v=${lifetmp[$k]}
if [[ -v life[$k] ]]; then
(( v!=2 && v!=3 )) && unset "life[$k]"
else
(( v==3 )) && life[$k]="#"
fi
done
}
x=$loops; y=$loops; z=$loops; w=$loops
while read -r line; do
for ((j=0; j<${#line}; ++j)); do
((curx=x+j))
c=${line:j:1}
if [[ $c == "#" ]]; then
life[$curx-$y-$z-$w]=$c
fi
done
((y++))
done
for ((i=0; i<6; ++i)); do
run_cycle
done
res=${#life[@]}
printf "%s : res=%d\n" "$CMD" "$res"
exit 0