X-Git-Url: https://git.sommitrealweird.co.uk/advent-of-code-2019.git/blobdiff_plain/8d19ec771c083ce8bbfff9b075d42f15ad704831..24a0a2360eb2e4b4332ce45ba5888e72f970428a:/day07/computer.sh?ds=inline diff --git a/day07/computer.sh b/day07/computer.sh new file mode 100644 index 0000000..1486f23 --- /dev/null +++ b/day07/computer.sh @@ -0,0 +1,102 @@ +#!/bin/bash + +declare -a data + +run_program() { + local -n od=$1 + data=("${od[@]}") + pos=0 + declare -a immediate + while [ $pos -le ${#data[@]} ]; do + # first, printf the value to 5 digits + instruction=$(printf "%05d" ${data[$pos]}) + for (( a=0; a<3; a++ )); do + immediate[$((3-a))]=${instruction:$a:1} + done + instruction=${instruction:3} + param_count=3 + case $instruction in + 01|02) + # 01 - add, 02 multiply + symbol="+" + if [ $instruction == "02" ]; then + symbol="*" + fi + val1=${data[$((pos+1))]} + val2=${data[$((pos+2))]} + res_loc=${data[$((pos+3))]} + if [ ${immediate[1]} -eq 0 ]; then + val1=${data[$val1]} + fi + if [ ${immediate[2]} -eq 0 ]; then + val2=${data[$val2]} + fi + data[$res_loc]=$(($val1 $symbol $val2)) + ;; + 03) + # 03 - read input + read -p "input: " input + res_loc=${data[$((pos+1))]} + data[$res_loc]=$input + param_count=1 + ;; + 04) + # 04 - output + if [ ${immediate[1]} -eq 1 ]; then + echo ${data[$((pos+1))]} + else + res_loc=${data[$((pos+1))]} + echo ${data[$res_loc]} + fi + param_count=1 + ;; + 05|06) + # 05 - jump-if-true, 06 - jump-if-false + val=${data[$((pos+1))]} + jumpto=${data[$((pos+2))]} + param_count=2 + if [ ${immediate[1]} -eq 0 ]; then + val=${data[$val]} + fi + if [ ${immediate[2]} -eq 0 ]; then + jumpto=${data[$jumpto]} + fi + if ( [ $val -ne 0 ] && [ "$instruction" == "05" ] ) || + ( [ $val -eq 0 ] && [ "$instruction" == "06" ] ); then + pos=$jumpto + continue + fi + ;; + 07|08) + # 07 - is less than, 08 - is equal + val1=${data[$((pos+1))]} + val2=${data[$((pos+2))]} + res_pos=${data[$((pos+3))]} + if [ ${immediate[1]} -eq 0 ]; then + val1=${data[$val1]} + fi + if [ ${immediate[2]} -eq 0 ]; then + val2=${data[$val2]} + fi + data[$res_pos]=0 + if [ "$instruction" == "07" ]; then + if [ $val1 -lt $val2 ]; then + data[$res_pos]=1 + fi + else + if [ $val1 -eq $val2 ]; then + data[$res_pos]=1 + fi + fi + ;; + 99) + break + ;; + *) + echo "Invalid opcode: $instruction at position $pos" + exit 1 + esac + pos=$(($pos+$param_count+1)) + done +} +