From 3f5b282883a08346689c46eab89dfe50442560b9 Mon Sep 17 00:00:00 2001 From: Bruno Raoult Date: Tue, 13 Dec 2022 19:33:29 +0100 Subject: [PATCH] 2022 day 9 Bash: reduce code by 40%, increase speed by 40% --- 2022/RESULTS.txt | 8 ++-- 2022/day09/aoc.bash | 96 ++++++++++++++------------------------------- 2 files changed, 33 insertions(+), 71 deletions(-) diff --git a/2022/RESULTS.txt b/2022/RESULTS.txt index 96b8dda..01c9bc7 100644 --- a/2022/RESULTS.txt +++ b/2022/RESULTS.txt @@ -180,10 +180,10 @@ aoc-c: res=672280 +++++++++++++++++ part 1 aoc.bash: res=5619 - time: 0:01.24 real, 1.23 user, 0.01 sys - context-switch: 75+2, page-faults: 1+430 + time: 0:00.69 real, 0.69 user, 0.00 sys + context-switch: 38+1, page-faults: 0+430 +++++++++++++++++ part 2 aoc.bash: res=2376 - time: 0:05.61 real, 5.59 user, 0.01 sys - context-switch: 329+1, page-faults: 0+345 + time: 0:03.25 real, 3.24 user, 0.00 sys + context-switch: 46+1, page-faults: 0+340 diff --git a/2022/day09/aoc.bash b/2022/day09/aoc.bash index d318ad8..45c9471 100755 --- a/2022/day09/aoc.bash +++ b/2022/day09/aoc.bash @@ -17,84 +17,46 @@ declare -a h{0..10} # h0 is head declare -A visited=() # keep count of visited declare -i last=1 # tail (last knot) -add_pos() { - local -n queue="$1" - visited["${queue[0]}"/"${queue[1]}"]=1 -} - -direction() { - local -n _dx="$1" _dy="$2" - local dir="$3" - (( _dx=0, _dy=0 )) - case "$dir" in - L) _dx=-1 ;; - R) _dx=1 ;; - U) _dy=1 ;; - D) _dy=-1 ;; - esac -} - -do_tail() { - local -n _h="$1" _t="$2" - local -i dx dy sx sy - - (( dx = _h[0] - _t[0], dy = _h[1] - _t[1] )) - (( sx = dx > 0? 1: -1 )) - (( sy = dy > 0? 1: -1 )) - if (( sx * dx > 1 || sy * dy > 1)); then - (( dx > 0 )) && (( _t[0]++ )) - (( dx < 0 )) && (( _t[0]-- )) - (( dy > 0 )) && (( _t[1]++ )) - (( dy < 0 )) && (( _t[1]-- )) - fi -} - -move_t() { - local -i _n - - for (( _n = 0; _n < last; ++_n )); do - do_tail "h$_n" "h$((_n + 1))" - done - add_pos "h$last" - return -} - -move_h() { +move() { local -i _dx="$1" _dy="$2" _m="$3" _i _n - for ((_i = 0; _i < _m; ++_i)); do - (( h0[0] += _dx, h0[1] += _dy )) - move_t + local -i __dx __dy __sx __sy + local -n _l="h$last" + + for ((_i = 0; _i < _m; ++_i)); do # for each move + (( h0[0] += _dx, h0[1] += _dy )) # head move + for (( _n = 0; _n < last; ++_n )); do # for each other node + local -n _h="h$_n" _t="h$((_n+1))" + (( __dx = _h[0] - _t[0], __dy = _h[1] - _t[1] )) + (( __sx = __dx? __dx > 0? 1: -1 : 0 )) + (( __sy = __dy? __dy > 0? 1: -1 : 0 )) + if (( __sx * __dx > 1 || __sy * __dy > 1)); then + (( _t[0] += __sx )) + (( _t[1] += __sy )) + fi + done + visited["${_l[0]}"/"${_l[1]}"]=1 done } parse() { local dir moves dx dy - (( last = $1 == 1? 1: 9 )) + + (( $1 == 2)) && last=9 while read -r dir moves; do - direction dx dy "$dir" - move_h "$dx" "$dy" "$moves" + dx=0 + dy=0 + case "$dir" in + L) dx=-1 ;; + R) dx=1 ;; + U) dy=1 ;; + D) dy=-1 ;; + esac + move "$dx" "$dy" "$moves" done } -part1() { - local -n _t="h$last" - res=${#visited[@]} -} - -part2() { - local -n _t="h$last" - res=${#visited[@]} -} - - solve() { - local part="$1" - add_pos "h$last" - if ((part == 1)); then - part1 - else - part2 - fi + res=${#visited[@]} } main "$@"