]> git.sommitrealweird.co.uk Git - advent-of-code-2019.git/blob - day7/computer.sh
1486f2324b519e5d136c3ed495f3eb57cc9542f2
[advent-of-code-2019.git] / day7 / computer.sh
1 #!/bin/bash
2
3 declare -a data
4
5 run_program() {
6     local -n od=$1
7     data=("${od[@]}")
8     pos=0
9     declare -a immediate
10     while [ $pos -le ${#data[@]} ]; do
11         # first, printf the value to 5 digits
12         instruction=$(printf "%05d" ${data[$pos]})
13         for (( a=0; a<3; a++ )); do
14             immediate[$((3-a))]=${instruction:$a:1}
15         done
16         instruction=${instruction:3}
17         param_count=3
18         case $instruction in
19             01|02)
20                 # 01 - add, 02 multiply
21                 symbol="+"
22                 if [ $instruction == "02" ]; then
23                     symbol="*"
24                 fi
25                 val1=${data[$((pos+1))]}
26                 val2=${data[$((pos+2))]}
27                 res_loc=${data[$((pos+3))]}
28                 if [ ${immediate[1]} -eq 0 ]; then
29                     val1=${data[$val1]}
30                 fi
31                 if [ ${immediate[2]} -eq 0 ]; then
32                     val2=${data[$val2]}
33                 fi
34                 data[$res_loc]=$(($val1 $symbol $val2))
35                 ;;
36             03)
37                 # 03 - read input
38                 read -p "input: " input
39                 res_loc=${data[$((pos+1))]}
40                 data[$res_loc]=$input
41                 param_count=1
42                 ;;
43             04)
44                 # 04 - output
45                 if [ ${immediate[1]} -eq 1 ]; then
46                     echo ${data[$((pos+1))]}
47                 else
48                     res_loc=${data[$((pos+1))]}
49                     echo ${data[$res_loc]}
50                 fi
51                 param_count=1
52                 ;;
53             05|06)
54                 # 05 - jump-if-true, 06 - jump-if-false
55                 val=${data[$((pos+1))]}
56                 jumpto=${data[$((pos+2))]}
57                 param_count=2
58                 if [ ${immediate[1]} -eq 0 ]; then
59                     val=${data[$val]}
60                 fi
61                 if [ ${immediate[2]} -eq 0 ]; then
62                     jumpto=${data[$jumpto]}
63                 fi
64                 if ( [ $val -ne 0 ] && [ "$instruction" == "05" ] ) ||
65                     ( [ $val -eq 0 ] && [ "$instruction" == "06" ] ); then
66                     pos=$jumpto
67                     continue
68                 fi
69                 ;;
70             07|08)
71                 # 07 - is less than, 08 - is equal
72                 val1=${data[$((pos+1))]}
73                 val2=${data[$((pos+2))]}
74                 res_pos=${data[$((pos+3))]}
75                 if [ ${immediate[1]} -eq 0 ]; then
76                     val1=${data[$val1]}
77                 fi
78                 if [ ${immediate[2]} -eq 0 ]; then
79                     val2=${data[$val2]}
80                 fi
81                 data[$res_pos]=0
82                 if [ "$instruction" == "07" ]; then
83                     if [ $val1 -lt $val2 ]; then
84                         data[$res_pos]=1
85                     fi
86                 else
87                     if [ $val1 -eq $val2 ]; then
88                         data[$res_pos]=1
89                     fi
90                 fi
91                 ;;
92             99)
93                 break
94                 ;;
95             *)
96                 echo "Invalid opcode: $instruction at position $pos"
97                 exit 1
98         esac
99         pos=$(($pos+$param_count+1))
100     done
101 }
102