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