Most of part 2
[advent-of-code-2019.git] / day11 / robot.sh
diff --git a/day11/robot.sh b/day11/robot.sh
new file mode 100644 (file)
index 0000000..c5b5613
--- /dev/null
@@ -0,0 +1,149 @@
+#!/bin/bash
+
+set -u
+
+__robot_direction=u
+__robot_lowest_x=0
+__robot_lowest_y=0
+__robot_highest_x=0
+__robot_highest_y=0
+__robot_cur_x=0
+__robot_cur_y=0
+__robot_start_on_white=0
+declare -A __robot_grid
+declare -A __robot_painted
+
+reset_robot() {
+    __robot_direction=u
+    __robot_lowest_x=0
+    __robot_lowest_y=0
+    __robot_highest_x=0
+    __robot_highest_y=0
+    __robot_cur_x=0
+    __robot_cur_y=0
+    __robot_start_on_white=0
+    unset __robot_grid
+    unset __robot_painted
+    declare -g -A __robot_grid
+    declare -g -A __robot_painted
+}
+
+get_robot_paint_colour() {
+    get_paint_colour $__robot_cur_x $__robot_cur_y
+}
+
+get_paint_colour() {
+    x=$1
+    y=$2
+
+    if [ ${__robot_grid[$x,$y]+a} ]; then
+        echo ${__robot_grid[$x,$y]}
+    else
+        if [ $x -eq 0 ] && [ $y -eq 0 ] && [ $__start_on_white -eq 1 ]; then
+            echo 1
+        else
+            echo 0
+        fi
+    fi
+}
+
+set_robot_start_on_white() {
+    start=${1:-1}
+
+    __robot_start_on_white=$start
+}
+
+set_robot_paint_colour() {
+    paint_colour=$1
+
+    __robot_grid[$__robot_cur_x,$__robot_cur_y]=$paint_colour
+    if ! [ ${__robot_painted[$__robot_cur_x,$__robot_cur_y]+a} ]; then
+        __robot_painted[$__robot_cur_x,$__robot_cur_y]=1
+    fi
+}
+
+get_robot_paint_count() {
+    echo ${#__robot_painted[@]}
+}
+
+do_robot_move() {
+    direction=$1
+
+    case $direction in
+        0)
+            case $__robot_direction in
+                u)
+                    __robot_direction=l
+                    __robot_cur_x=$((__robot_cur_x - 1))
+                    ;;
+                l)
+                    __robot_direction=d
+                    __robot_cur_y=$((__robot_cur_y - 1))
+                    ;;
+                d)
+                    __robot_direction=r
+                    __robot_cur_x=$((__robot_cur_x + 1))
+                    ;;
+                r)
+                    __robot_direction=u
+                    __robot_cur_y=$((__robot_cur_y + 1))
+                    ;;
+            esac
+            ;;
+        1)
+            case $__robot_direction in
+                u)
+                    __robot_direction=r
+                    __robot_cur_x=$((__robot_cur_x + 1))
+                    ;;
+                r)
+                    __robot_direction=d
+                    __robot_cur_y=$((__robot_cur_y - 1))
+                    ;;
+                d)
+                    __robot_direction=l
+                    __robot_cur_x=$((__robot_cur_x - 1))
+                    ;;
+                l)
+                    __robot_direction=u
+                    __robot_cur_y=$((__robot_cur_y + 1))
+                    ;;
+            esac
+            ;;
+    esac
+
+    # adjust min/max
+    if [ $__robot_cur_x -lt $__robot_lowest_x ]; then
+        __robot_lowest_x=$__robot_cur_x
+    fi
+
+    if [ $__robot_cur_x -gt $__robot_highest_x ]; then
+        __robot_highest_x=$__robot_cur_x
+    fi
+
+    if [ $__robot_cur_y -lt $__robot_lowest_y ]; then
+        __robot_lowest_y=$__robot_cur_y
+    fi
+
+    if [ $__robot_cur_y -gt $__robot_highest_y ]; then
+        __robot_highest_y=$__robot_cur_y
+    fi
+}
+
+do_robot_paint_and_move() {
+    paint_colour=$1
+    direction=$2
+    set_robot_paint_colour $paint_colour
+    do_robot_move $direction
+}
+
+draw_panel() {
+    colours=("." "#")
+
+    for (( y=$__robot_lowest_y; y<=$__robot_highest_y; y++ )); do
+        for (( x=$__robot_lowest_x; x<=$__robot_highest_x; x++ )); do
+            echo -n ${colours[$(get_paint_colour $x $y)]}
+        done
+        echo
+    done
+}