2022 day 11, Bash speedup (40-50%)

This commit is contained in:
2022-12-20 17:29:47 +01:00
parent fe381ae7f0
commit 008599e79c
2 changed files with 43 additions and 56 deletions

View File

@@ -236,10 +236,10 @@ aoc-c: res=0
+++++++++++++++++ part 1 +++++++++++++++++ part 1
aoc.bash: res=54253 aoc.bash: res=54253
time: 0:00.06 real, 0.05 user, 0.00 sys time: 0:00.05 real, 0.04 user, 0.00 sys
context-switch: 7+1, page-faults: 0+273 context-switch: 1+1, page-faults: 0+268
+++++++++++++++++ part 2 +++++++++++++++++ part 2
aoc.bash: res=13119526120 aoc.bash: res=13119526120
time: 0:29.05 real, 26.71 user, 2.31 sys time: 0:16.49 real, 16.48 user, 0.00 sys
context-switch: 1292+1, page-faults: 0+272 context-switch: 106+1, page-faults: 0+270

View File

@@ -13,16 +13,16 @@
. common.bash . common.bash
declare -ai div ttrue tfalse inspect declare -ai div ttrue tfalse vis
declare -a items # (1 2) is "1 2" declare -a it # (1 2) is "1 2"
declare -a op1 op op2 declare -a op1 op op2
declare -i reduce=1 nmonkeys=0 divisor=3 declare -i lcm=1 monks=0 divisor=3
calc() { calc() {
local -n _res="$1" local -n _res="$1"
local -i _m1=0 _m2=0 _i local -i _m1=0 _m2=0 _i
for _i in "${inspect[@]}"; do # find the 2 biggest numbers for _i in "${vis[@]}"; do # find the 2 biggest numbers
if ((_i > _m1)); then if ((_i > _m1)); then
((_m2 = _m1, _m1 = _i)) ((_m2 = _m1, _m1 = _i))
elif ((_i > _m2)); then elif ((_i > _m2)); then
@@ -32,66 +32,53 @@ calc() {
(( _res = _m1 * _m2 )) (( _res = _m1 * _m2 ))
} }
inspect() {
local -i _part="$1" monkey="$2" item _tmp
local -i _op1=${op1[$monkey]} _op2=${op2[$monkey]}
local -a _items
read -ra _items <<< "${items[$monkey]}" # convert to array
for item in "${_items[@]}"; do
(( inspect[monkey]++ ))
[[ -v op1[$monkey] ]] || _op1=$item
[[ -v op2[$monkey] ]] || _op2=$item
if [[ "${op[$monkey]}" == "+" ]]; then
(( _tmp = _op1 + _op2 ))
else
(( _tmp = _op1 * _op2 ))
fi
(( _tmp /= divisor, _tmp %= reduce ))
if ! (( _tmp % div[monkey] )); then
items[${ttrue[$monkey]}]+=" $_tmp"
else
items[${tfalse[$monkey]}]+=" $_tmp"
fi
done
items[$monkey]=""
}
parse() { parse() {
local -i monkey=0 local -a _it
local -a _items
while read -r; do # ignore Monkey number while read -r; do # ignore Monkey number
#echo -n "monkey=$monkey " IFS=" :," read -ra _it # starting items
IFS=" :," read -ra _items # starting items it[$monks]="${_it[*]:2}"
IFS=" :=" read -r _ _ op1[$monks] op[$monks] op2[$monks]
items[$monkey]="${_items[*]:2}" [[ ${op[$monks]} == "+" ]] && unset "op[$monks]"
#echo -n "items[$monkey]=${items[$monkey]} " [[ ${op1[$monks]} == old ]] && unset "op1[$monks]"
IFS=" :=" read -r _ _ op1[$monkey] op[$monkey] op2[$monkey] # operator and operand [[ ${op2[$monks]} == old ]] && unset "op2[$monks]"
[[ ${op1[$monkey]} == old ]] && unset "op1[$monkey]" IFS=" :=" read -r _ _ _ div[$monks] # divisor
[[ ${op2[$monkey]} == old ]] && unset "op2[$monkey]" (( lcm *= div[monks] ))
#echo -n "op=${op[$monkey]} ops=${op1[$monkey]}/${op2[$monkey]} " read -r _ _ _ _ _ ttrue[$monks] # throw if true
IFS=" :=" read -r _ _ _ div[$monkey] # divisor read -r _ _ _ _ _ tfalse[$monks]
(( reduce *= div[monkey] ))
#echo -n "div=${div[$monkey]} "
read -r _ _ _ _ _ ttrue[$monkey] # throw if true
read -r _ _ _ _ _ tfalse[$monkey]
#echo "T=${ttrue[$monkey]} F=${tfalse[$monkey]}"
read -r read -r
(( monkey++ )) (( monks++ ))
#break
done done
} }
solve() { solve() {
local -i _loops=20 local -i _loops=20 round m _op1 _op2 i
(( part == 2 )) && (( _loops = 10000, divisor = 1 )) (( part == 2 )) && (( _loops = 10000, divisor = 1 ))
for ((round = 0; round < _loops; ++round)); do for ((round = 0; round < _loops; ++round)); do
for ((monkey = 0; monkey < ${#div[@]}; ++monkey)); do for ((m = 0; m < monks; ++m)); do
inspect "$part" "$monkey" _op1=${op1[$m]}
_op2=${op2[$m]}
# shellcheck disable=SC2068
for i in ${it[$m]}; do
(( vis[m]++ ))
[[ -v op1[$m] ]] || _op1=$i
[[ -v op2[$m] ]] || _op2=$i
if [[ -v op[$m] ]]; then
(( _tmp = (_op1 * _op2) / divisor % lcm ))
else
(( _tmp = (_op1 + _op2) / divisor % lcm ))
fi
if (( _tmp % div[m] )); then
it[${tfalse[$m]}]+=" $_tmp"
else
it[${ttrue[$m]}]+=" $_tmp"
fi
done
it[$m]=""
done done
done done
#printf "inspect=%s\n" "${inspect[*]}"
calc res calc res
} }