Day 5 2019
[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                 symbol="+"
27                 if [ $instruction == "02" ]; then
28                     symbol="*"
29                 fi
30                 val1=${data[$((pos+1))]}
31                 val2=${data[$((pos+2))]}
32                 if [ ${immediate[1]} -eq 0 ]; then
33                     val1=${data[$loc1]}
34                 fi
35                 if [ ${immediate[2]} -eq 0 ]; then
36                     val2=${data[$loc2]}
37                 fi
38                 data[$res_loc]=$(($val1 $symbol $val2))
39                 ;;
40             03)
41                 read -p "input: " input
42                 res_loc=${data[$((pos+1))]}
43                 data[$res_loc]=$input
44                 param_count=1
45                 ;;
46             04)
47                 if [ ${immediate[1]} -eq 1 ]; then
48                     echo ${data[$((pos+1))]}
49                 else
50                     res_loc=${data[$((pos+1))]}
51                     echo ${data[$res_loc]}
52                 fi
53                 param_count=1
54                 ;;
55             05|06)
56                 val=${data[$((pos+1))]}
57                 jumpto=${data[$((pos+2))]}
58                 param_count=2
59                 if [ ${immediate[1]} -eq 0 ]; then
60                     val=${data[$val]}
61                 fi
62                 if [ ${immediate[2]} -eq 0 ]; then
63                     jumpto=${data[$jumpto]}
64                 fi
65                 if ( [ $val -ne 0 ] && [ "$instruction" == "05" ] ) ||
66                     ( [ $val -eq 0 ] && [ "$instruction" == "06" ] ); then
67                     pos=$jumpto
68                     continue
69                 fi
70                 ;;
71             07)
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                 if [ $val1 -lt $val2 ]; then
82                     data[$res_pos]=1
83                 else
84                     data[$res_pos]=0
85                 fi
86                 ;;
87             08)
88                 val1=${data[$((pos+1))]}
89                 val2=${data[$((pos+2))]}
90                 res_pos=${data[$((pos+3))]}
91                 if [ ${immediate[1]} -eq 0 ]; then
92                     val1=${data[$val1]}
93                 fi
94                 if [ ${immediate[2]} -eq 0 ]; then
95                     val2=${data[$val2]}
96                 fi
97                 if [ $val1 -eq $val2 ]; then
98                     data[$res_pos]=1
99                 else
100                     data[$res_pos]=0
101                 fi
102                 ;;
103             99)
104                 break
105                 ;;
106             *)
107                 echo "Invalid opcode: $instruction at position $pos"
108                 exit 1
109         esac
110         pos=$(($pos+$param_count+1))
111     done
112 }
113
114 echo "Part 1:"
115 run_program