Day 11 - part 2 and output, and some notes
[advent-of-code-2019.git] / day11 / robot.sh
1 #!/bin/bash
2
3 set -u
4
5 __robot_direction=u
6 __robot_lowest_x=0
7 __robot_lowest_y=0
8 __robot_highest_x=0
9 __robot_highest_y=0
10 __robot_cur_x=0
11 __robot_cur_y=0
12 __robot_start_on_white=0
13 declare -A __robot_grid
14 declare -A __robot_painted
15
16 reset_robot() {
17     __robot_direction=u
18     __robot_lowest_x=0
19     __robot_lowest_y=0
20     __robot_highest_x=0
21     __robot_highest_y=0
22     __robot_cur_x=0
23     __robot_cur_y=0
24     __robot_start_on_white=0
25     unset __robot_grid
26     unset __robot_painted
27     declare -g -A __robot_grid
28     declare -g -A __robot_painted
29 }
30
31 get_robot_paint_colour() {
32     get_paint_colour $__robot_cur_x $__robot_cur_y
33 }
34
35 get_paint_colour() {
36     x=$1
37     y=$2
38
39     if [ ${__robot_grid[$x,$y]+a} ]; then
40         echo ${__robot_grid[$x,$y]}
41     else
42         if [ $x -eq 0 ] && [ $y -eq 0 ] && [ $__robot_start_on_white -eq 1 ]; then
43             echo 1
44         else
45             echo 0
46         fi
47     fi
48 }
49
50 set_robot_start_on_white() {
51     start=${1:-1}
52
53     __robot_start_on_white=$start
54 }
55
56 set_robot_paint_colour() {
57     paint_colour=$1
58
59     __robot_grid[$__robot_cur_x,$__robot_cur_y]=$paint_colour
60     if ! [ ${__robot_painted[$__robot_cur_x,$__robot_cur_y]+a} ]; then
61         __robot_painted[$__robot_cur_x,$__robot_cur_y]=1
62     fi
63 }
64
65 get_robot_paint_count() {
66     echo ${#__robot_painted[@]}
67 }
68
69 do_robot_move() {
70     direction=$1
71
72     case $direction in
73         0)
74             case $__robot_direction in
75                 u)
76                     __robot_direction=l
77                     __robot_cur_x=$((__robot_cur_x - 1))
78                     ;;
79                 l)
80                     __robot_direction=d
81                     __robot_cur_y=$((__robot_cur_y - 1))
82                     ;;
83                 d)
84                     __robot_direction=r
85                     __robot_cur_x=$((__robot_cur_x + 1))
86                     ;;
87                 r)
88                     __robot_direction=u
89                     __robot_cur_y=$((__robot_cur_y + 1))
90                     ;;
91             esac
92             ;;
93         1)
94             case $__robot_direction in
95                 u)
96                     __robot_direction=r
97                     __robot_cur_x=$((__robot_cur_x + 1))
98                     ;;
99                 r)
100                     __robot_direction=d
101                     __robot_cur_y=$((__robot_cur_y - 1))
102                     ;;
103                 d)
104                     __robot_direction=l
105                     __robot_cur_x=$((__robot_cur_x - 1))
106                     ;;
107                 l)
108                     __robot_direction=u
109                     __robot_cur_y=$((__robot_cur_y + 1))
110                     ;;
111             esac
112             ;;
113     esac
114
115     # adjust min/max
116     if [ $__robot_cur_x -lt $__robot_lowest_x ]; then
117         __robot_lowest_x=$__robot_cur_x
118     fi
119
120     if [ $__robot_cur_x -gt $__robot_highest_x ]; then
121         __robot_highest_x=$__robot_cur_x
122     fi
123
124     if [ $__robot_cur_y -lt $__robot_lowest_y ]; then
125         __robot_lowest_y=$__robot_cur_y
126     fi
127
128     if [ $__robot_cur_y -gt $__robot_highest_y ]; then
129         __robot_highest_y=$__robot_cur_y
130     fi
131 }
132
133 do_robot_paint_and_move() {
134     paint_colour=$1
135     direction=$2
136     set_robot_paint_colour $paint_colour
137     do_robot_move $direction
138 }
139
140 draw_panel() {
141     colours=("." "#")
142
143     # we draw upside down, in effect, starting from the bottom and going to
144     # the top, so when outputting, we should switch that round
145     for (( y=$__robot_highest_y; y>=$__robot_lowest_y; y-- )); do
146         for (( x=$__robot_lowest_x; x<=$__robot_highest_x; x++ )); do
147             echo -n ${colours[$(get_paint_colour $x $y)]}
148         done
149         echo
150     done
151 }