2019 Day 9
authorBrett Parker <iDunno@sommitrealweird.co.uk>
Mon, 7 Dec 2020 18:11:34 +0000 (18:11 +0000)
committerBrett Parker <iDunno@sommitrealweird.co.uk>
Mon, 7 Dec 2020 18:11:34 +0000 (18:11 +0000)
day9/computer.sh [new file with mode: 0644]
day9/input.txt [new file with mode: 0644]
day9/run.sh [new file with mode: 0644]

diff --git a/day9/computer.sh b/day9/computer.sh
new file mode 100644 (file)
index 0000000..94bd8e0
--- /dev/null
@@ -0,0 +1,143 @@
+#!/bin/bash
+
+declare -a data
+
+get_value() {
+    local -n da=$1
+    local index=$2
+
+    if [ $index -lt 0 ]; then
+        echo "Index negative, give up!"
+        exit 2
+    fi
+
+    if ! [ ${da[$index]+a} ]; then
+        da[$index]=0
+    fi
+
+    echo "${da[$index]}"
+}
+
+get_param() {
+    local -n dap=$1
+    local pos=$2
+    local mode=$3
+    local relative_base=$4
+
+    loc=$(get_param_loc dap $pos $mode $relative_base)
+
+    get_value dap $loc
+}
+
+get_param_loc() {
+    local -n dapl=$1
+    local pos=$2
+    local mode=$3
+    local relative_base=$4
+
+    case $mode in
+        0)
+            get_value dapl $pos
+            ;;
+        1)
+            echo $pos
+            ;;
+        2)
+            move_by=$(get_value dapl $pos)
+            echo $((relative_base+$move_by))
+            ;;
+        *)
+            echo "Unknown parameter mode: $mode"
+            exit 2
+            ;;
+    esac
+}
+
+run_program() {
+    local -n od=$1
+    local relative_base=0
+    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
+        echo -n $'\r'"    "$'\r'$instruction >&2
+        case $instruction in
+            01|02)
+                # 01 - add, 02 multiply
+                symbol="+"
+                if [ $instruction == "02" ]; then
+                    symbol="*"
+                fi
+                val1=$(get_param data $((pos+1)) ${immediate[1]} $relative_base)
+                val2=$(get_param data $((pos+2)) ${immediate[2]} $relative_base)
+                res_loc=$(get_param_loc data $((pos+3)) ${immediate[3]} $relative_base)
+                data[$res_loc]=$(($val1 $symbol $val2))
+                ;;
+            03)
+                # 03 - read input
+                echo -n $'\r'"    "$'\r' >&2
+                read -p "input: " input
+                res_loc=$(get_param_loc data $((pos+1)) ${immediate[1]} $relative_base)
+                data[$res_loc]=$input
+                param_count=1
+                ;;
+            04)
+                # 04 - output
+                val=$(get_param data $((pos+1)) ${immediate[1]} $relative_base)
+                echo -n $'\r'"    "$'\r' >&2
+                echo $val
+                param_count=1
+                ;;
+            05|06)
+                # 05 - jump-if-true, 06 - jump-if-false
+                val=$(get_param data $((pos+1)) ${immediate[1]} $relative_base)
+                jumpto=$(get_param data $((pos+2)) ${immediate[2]} $relative_base)
+                param_count=2
+                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=$(get_param data $((pos+1)) ${immediate[1]} $relative_base)
+                val2=$(get_param data $((pos+2)) ${immediate[2]} $relative_base)
+                res_pos=$(get_param_loc data $((pos+3)) ${immediate[3]} $relative_base)
+                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
+                ;;
+            09)
+                # adjust relative base
+                param_count=1
+                val=$(get_param data $((pos+1)) ${immediate[1]} $relative_base)
+                relative_base=$((relative_base+$val))
+                ;;
+            99)
+                break
+                ;;
+            *)
+                echo "Invalid opcode: $instruction at position $pos"
+                exit 1
+                ;;
+        esac
+        pos=$(($pos+$param_count+1))
+    done
+    echo -n $'\r'"    "$'\r'
+}
+
diff --git a/day9/input.txt b/day9/input.txt
new file mode 100644 (file)
index 0000000..a4232d5
--- /dev/null
@@ -0,0 +1 @@
+1102,34463338,34463338,63,1007,63,34463338,63,1005,63,53,1101,0,3,1000,109,988,209,12,9,1000,209,6,209,3,203,0,1008,1000,1,63,1005,63,65,1008,1000,2,63,1005,63,904,1008,1000,0,63,1005,63,58,4,25,104,0,99,4,0,104,0,99,4,17,104,0,99,0,0,1102,1,29,1011,1102,1,27,1009,1101,23,0,1008,1101,0,25,1017,1102,1,36,1016,1101,0,31,1018,1102,35,1,1012,1101,28,0,1004,1101,779,0,1024,1102,403,1,1026,1101,0,33,1010,1102,37,1,1015,1101,32,0,1014,1101,0,752,1023,1101,0,30,1013,1102,21,1,1001,1102,1,1,1021,1102,1,34,1002,1102,400,1,1027,1101,0,22,1007,1102,1,567,1028,1101,558,0,1029,1102,26,1,1006,1102,39,1,1005,1102,1,0,1020,1101,0,38,1000,1101,0,755,1022,1102,1,770,1025,1102,1,24,1003,1102,20,1,1019,109,28,21107,40,41,-9,1005,1019,199,4,187,1106,0,203,1001,64,1,64,1002,64,2,64,109,-30,2107,38,7,63,1005,63,221,4,209,1105,1,225,1001,64,1,64,1002,64,2,64,109,-5,2102,1,8,63,1008,63,21,63,1005,63,251,4,231,1001,64,1,64,1106,0,251,1002,64,2,64,109,21,1207,-7,21,63,1005,63,267,1105,1,273,4,257,1001,64,1,64,1002,64,2,64,109,-1,1201,-7,0,63,1008,63,29,63,1005,63,293,1106,0,299,4,279,1001,64,1,64,1002,64,2,64,109,-4,1202,-3,1,63,1008,63,28,63,1005,63,319,1106,0,325,4,305,1001,64,1,64,1002,64,2,64,109,14,1206,-3,343,4,331,1001,64,1,64,1106,0,343,1002,64,2,64,109,-14,2108,21,-8,63,1005,63,361,4,349,1105,1,365,1001,64,1,64,1002,64,2,64,109,-9,1201,9,0,63,1008,63,27,63,1005,63,391,4,371,1001,64,1,64,1106,0,391,1002,64,2,64,109,27,2106,0,0,1106,0,409,4,397,1001,64,1,64,1002,64,2,64,109,-20,2101,0,0,63,1008,63,22,63,1005,63,431,4,415,1105,1,435,1001,64,1,64,1002,64,2,64,109,-7,1202,7,1,63,1008,63,22,63,1005,63,457,4,441,1105,1,461,1001,64,1,64,1002,64,2,64,109,8,1208,0,23,63,1005,63,479,4,467,1106,0,483,1001,64,1,64,1002,64,2,64,109,20,1205,-8,495,1105,1,501,4,489,1001,64,1,64,1002,64,2,64,109,-26,1208,4,28,63,1005,63,521,1001,64,1,64,1105,1,523,4,507,1002,64,2,64,109,15,21102,41,1,-2,1008,1015,41,63,1005,63,545,4,529,1106,0,549,1001,64,1,64,1002,64,2,64,109,18,2106,0,-7,4,555,1001,64,1,64,1106,0,567,1002,64,2,64,109,-30,1207,-3,35,63,1005,63,585,4,573,1105,1,589,1001,64,1,64,1002,64,2,64,109,14,1206,2,605,1001,64,1,64,1106,0,607,4,595,1002,64,2,64,109,-3,1205,5,621,4,613,1106,0,625,1001,64,1,64,1002,64,2,64,109,-5,21107,42,41,2,1005,1013,645,1001,64,1,64,1106,0,647,4,631,1002,64,2,64,109,-11,2108,42,5,63,1005,63,663,1106,0,669,4,653,1001,64,1,64,1002,64,2,64,109,4,21102,43,1,9,1008,1013,40,63,1005,63,693,1001,64,1,64,1106,0,695,4,675,1002,64,2,64,109,-1,2107,22,-2,63,1005,63,715,1001,64,1,64,1106,0,717,4,701,1002,64,2,64,109,7,21101,44,0,0,1008,1010,45,63,1005,63,741,1001,64,1,64,1106,0,743,4,723,1002,64,2,64,109,9,2105,1,4,1106,0,761,4,749,1001,64,1,64,1002,64,2,64,109,10,2105,1,-5,4,767,1001,64,1,64,1105,1,779,1002,64,2,64,109,-22,21108,45,43,10,1005,1017,799,1001,64,1,64,1105,1,801,4,785,1002,64,2,64,109,16,21101,46,0,-8,1008,1015,46,63,1005,63,827,4,807,1001,64,1,64,1105,1,827,1002,64,2,64,109,-7,2101,0,-7,63,1008,63,29,63,1005,63,851,1001,64,1,64,1106,0,853,4,833,1002,64,2,64,109,-5,2102,1,-3,63,1008,63,22,63,1005,63,877,1001,64,1,64,1106,0,879,4,859,1002,64,2,64,109,9,21108,47,47,-5,1005,1015,897,4,885,1105,1,901,1001,64,1,64,4,64,99,21102,27,1,1,21101,0,915,0,1105,1,922,21201,1,61784,1,204,1,99,109,3,1207,-2,3,63,1005,63,964,21201,-2,-1,1,21101,942,0,0,1105,1,922,22102,1,1,-1,21201,-2,-3,1,21102,1,957,0,1106,0,922,22201,1,-1,-2,1105,1,968,22101,0,-2,-2,109,-3,2105,1,0
diff --git a/day9/run.sh b/day9/run.sh
new file mode 100644 (file)
index 0000000..458d31d
--- /dev/null
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+set -u
+set -e
+
+. $(dirname $(readlink -f ${BASH_SOURCE}))/computer.sh
+
+#data=(109 1 204 -1 1001 100 1 100 1008 100 16 101 1006 101 0 99)
+#data=(1102 34915192 34915192 7 4 7 99 0)
+#data=(104 1125899906842624 99)
+exec 3<input.txt
+
+OLDIFS=$IFS
+IFS="," read -u 3 -a orig_data
+IFS=$OLDIFS
+
+run_program orig_data