day18/2 bash
This commit is contained in:
@@ -8,7 +8,7 @@ export PATH := .:$(PATH)
|
|||||||
|
|
||||||
.PHONY: clean all compile deploy ex1 ex2
|
.PHONY: clean all compile deploy ex1 ex2
|
||||||
|
|
||||||
all: ex1
|
all: ex1 ex2
|
||||||
|
|
||||||
output:
|
output:
|
||||||
@$(MAKE) --no-print-directory all 2>&1 > OUTPUT
|
@$(MAKE) --no-print-directory all 2>&1 > OUTPUT
|
||||||
|
@@ -1,4 +1,8 @@
|
|||||||
ex1.bash : res=650217205854
|
ex1.bash : res=650217205854
|
||||||
time: 0:01.73 real, 1.73 user, 0.00 sys
|
time: 0:01.76 real, 1.74 user, 0.01 sys
|
||||||
context-switch: 6+1, page-faults: 0+189
|
context-switch: 5+1, page-faults: 0+188
|
||||||
|
|
||||||
|
ex2.bash : res=20394514442037
|
||||||
|
time: 0:01.54 real, 1.53 user, 0.01 sys
|
||||||
|
context-switch: 42+1, page-faults: 0+196
|
||||||
|
|
||||||
|
@@ -36,8 +36,6 @@ Here are a few more examples:
|
|||||||
Before you can help with the homework, you need to understand it yourself. Evaluate the expression on each line of the homework; what is the sum of the resulting values?
|
Before you can help with the homework, you need to understand it yourself. Evaluate the expression on each line of the homework; what is the sum of the resulting values?
|
||||||
|
|
||||||
Your puzzle answer was 650217205854.
|
Your puzzle answer was 650217205854.
|
||||||
|
|
||||||
The first half of this puzzle is complete! It provides one gold star: *
|
|
||||||
--- Part Two ---
|
--- Part Two ---
|
||||||
|
|
||||||
You manage to answer the child's questions and they finish part 1 of their homework, but get stuck when they reach the next section: advanced math.
|
You manage to answer the child's questions and they finish part 1 of their homework, but get stuck when they reach the next section: advanced math.
|
||||||
@@ -63,8 +61,6 @@ Here are the other examples from above:
|
|||||||
|
|
||||||
What do you get if you add up the results of evaluating the homework problems using these new rules?
|
What do you get if you add up the results of evaluating the homework problems using these new rules?
|
||||||
|
|
||||||
Answer:
|
Your puzzle answer was 20394514442037.
|
||||||
|
|
||||||
Although it hasn't changed, you can still get your puzzle input.
|
Both parts of this puzzle are complete! They provide two gold stars: **
|
||||||
|
|
||||||
You can also [Share] this puzzle.
|
|
||||||
|
168
day18/ex2.bash
Executable file
168
day18/ex2.bash
Executable file
@@ -0,0 +1,168 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# ex2.bash: Advent2020 game, day 18/game 2.
|
||||||
|
|
||||||
|
CMD=${0##*/}
|
||||||
|
set -o noglob
|
||||||
|
|
||||||
|
# shellcheck disable=2034
|
||||||
|
declare -a STACK=()
|
||||||
|
declare -a LINE=()
|
||||||
|
|
||||||
|
function enqueue() {
|
||||||
|
local -n stack="$1"
|
||||||
|
local var="$2"
|
||||||
|
stack=("$var" "${stack[@]}")
|
||||||
|
}
|
||||||
|
function dequeue() {
|
||||||
|
# shellcheck disable=2178
|
||||||
|
local -n stack="$1"
|
||||||
|
local -n var="$2"
|
||||||
|
local last=$((${#stack[@]} - 1))
|
||||||
|
var=${stack[$last]}
|
||||||
|
unset 'stack[$last]'
|
||||||
|
stack=( "${stack[@]}" ) # pack
|
||||||
|
}
|
||||||
|
function getqueue() {
|
||||||
|
# shellcheck disable=2178
|
||||||
|
local -n stack="$1"
|
||||||
|
local -n var="$2"
|
||||||
|
local pos="$3"
|
||||||
|
|
||||||
|
var=${stack[$pos]}
|
||||||
|
unset 'stack[$pos]'
|
||||||
|
#stack=( "${stack[@]}" ) # DO NOT pack !
|
||||||
|
}
|
||||||
|
function setqueue() {
|
||||||
|
local -n stack="$1"
|
||||||
|
local val="$2"
|
||||||
|
local pos="$3"
|
||||||
|
|
||||||
|
stack[$pos]="$val"
|
||||||
|
}
|
||||||
|
function print_stack() {
|
||||||
|
# shellcheck disable=2178
|
||||||
|
local -n stack="$1"
|
||||||
|
local k
|
||||||
|
printf "stack [%s:%d]: " "$1" "${#stack[@]}"
|
||||||
|
for k in "${!stack[@]}"; do
|
||||||
|
printf "%s:%s " "$k" "${stack[$k]}"
|
||||||
|
done
|
||||||
|
printf "\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
function eval_plus() {
|
||||||
|
local -n lvalop="$1" loptop="$2"
|
||||||
|
local -i v v1 v2 pos last="${#loptop[@]}"
|
||||||
|
|
||||||
|
for ((pos=0; pos<last; ++pos)); do
|
||||||
|
if [[ "${loptop[$pos]}" == '+' ]]; then
|
||||||
|
getqueue lvalop v1 "$pos"
|
||||||
|
getqueue lvalop v2 "$((pos+1))"
|
||||||
|
getqueue loptop op "$pos"
|
||||||
|
# shellcheck disable=SC1102
|
||||||
|
v=$((v1 + v2))
|
||||||
|
setqueue lvalop "$v" $((pos+1))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
lvalop=("${lvalop[@]}") # pack arrays
|
||||||
|
loptop=("${loptop[@]}")
|
||||||
|
}
|
||||||
|
|
||||||
|
function eval_op() {
|
||||||
|
# shellcheck disable=2034,2178
|
||||||
|
local -n lvalop="$1" loptop="$2"
|
||||||
|
# shellcheck disable=2034
|
||||||
|
local v v1 v2 op res=-1
|
||||||
|
while ((${#lvalop[@]} > 1)); do
|
||||||
|
dequeue lvalop v1
|
||||||
|
dequeue lvalop v2
|
||||||
|
dequeue loptop op
|
||||||
|
# shellcheck disable=SC1102
|
||||||
|
v=$((v1 "$op" v2))
|
||||||
|
enqueue lvalop "$v"
|
||||||
|
((res++))
|
||||||
|
done
|
||||||
|
return "$res"
|
||||||
|
}
|
||||||
|
|
||||||
|
function find_paren() {
|
||||||
|
local -n expr_="$1"
|
||||||
|
local -n var_="$2"
|
||||||
|
local -i i
|
||||||
|
local k val
|
||||||
|
var_=-1
|
||||||
|
for k in "${!expr_[@]}"; do
|
||||||
|
val=${expr_[$k]}
|
||||||
|
[[ $val == '(' ]] && i="$k"
|
||||||
|
if [[ $val == ')' ]]; then
|
||||||
|
# shellcheck disable=SC2034
|
||||||
|
var_="$i"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
function eval_expr() {
|
||||||
|
local -i cur="$2" val len=${#LINE[@]}
|
||||||
|
local op
|
||||||
|
# shellcheck disable=SC2034
|
||||||
|
local -a lstack=() lop=() LINE_=()
|
||||||
|
|
||||||
|
while ((cur < len)); do
|
||||||
|
symbol=${LINE[$cur]}
|
||||||
|
case "$symbol" in
|
||||||
|
[0-9]*)
|
||||||
|
enqueue lstack "${LINE[$cur]}"
|
||||||
|
unset 'LINE[$cur]'
|
||||||
|
;;
|
||||||
|
\))
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
[\+\*]*)
|
||||||
|
enqueue lop "${LINE[$cur]}"
|
||||||
|
unset 'LINE[$cur]'
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
((cur++))
|
||||||
|
done
|
||||||
|
eval_plus lstack lop
|
||||||
|
eval_op lstack lop
|
||||||
|
|
||||||
|
dequeue lstack val
|
||||||
|
LINE[$cur]="$val"
|
||||||
|
LINE=("${LINE[@]}") # pack
|
||||||
|
}
|
||||||
|
|
||||||
|
declare -i res=0 paren=0
|
||||||
|
|
||||||
|
while read -r line; do
|
||||||
|
# cleanup input line, force split around operators and parens
|
||||||
|
line=${line//\*/ * }
|
||||||
|
line=${line//+/ + }
|
||||||
|
line=${line//-/ - }
|
||||||
|
line=${line//\// \/ }
|
||||||
|
line=${line//\(/ \( }
|
||||||
|
line=${line//\)/ \) }
|
||||||
|
read -ra LINE <<< "$line"
|
||||||
|
paren=0
|
||||||
|
while ((${#LINE[@]} > 1 && paren >= 0)); do
|
||||||
|
find_paren LINE paren
|
||||||
|
if (( paren >= 0 )); then
|
||||||
|
unset 'LINE[$paren]'
|
||||||
|
LINE=("${LINE[@]}") # pack
|
||||||
|
eval_expr STACK "$paren"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if ((${#LINE[@]} > 1)); then
|
||||||
|
eval_expr STACK 0
|
||||||
|
fi
|
||||||
|
((res+=LINE[0]))
|
||||||
|
done
|
||||||
|
|
||||||
|
printf "%s : res=%d\n" "$CMD" "$res"
|
||||||
|
|
||||||
|
exit 0
|
Reference in New Issue
Block a user