Day 5
[advent-of-code-2021.git] / day05 / vents.sh
diff --git a/day05/vents.sh b/day05/vents.sh
new file mode 100755 (executable)
index 0000000..5d4eecf
--- /dev/null
@@ -0,0 +1,175 @@
+#!/bin/bash
+
+set -e
+set -u
+
+filename="${1:-example.txt}"
+
+exec 3<"$filename"
+
+declare -a lines
+
+max_x=0
+max_y=0
+x1=0
+y1=0
+x2=0
+y2=0
+
+declare -a grid
+
+get_coords() {
+    coords_line="$1"
+    local -n lx1=$2
+    local -n ly1=$3
+    local -n lx2=$4
+    local -n ly2=$5
+
+    local first_x_y=${coords_line% -> *}
+    local second_x_y=${coords_line#* -> }
+    lx1=${first_x_y%,*}
+    ly1=${first_x_y#*,}
+    lx2=${second_x_y%,*}
+    ly2=${second_x_y#*,}
+}
+
+generate_grid() {
+    local max_x=$1
+    local max_y=$2
+    local -n grid_arr=$3
+
+    for (( i=0; i<$max_y; i++ )); do
+        for (( j=0; j<$max_x; j++ )); do
+            grid_arr+=(0)
+        done
+    done
+}
+
+display_grid() {
+    local max_x=$1
+    local -n grid_arr=$2
+
+    local cur_pos=0
+
+    while (( $cur_pos < ${#grid_arr[@]} )); do
+        case ${grid_arr[$cur_pos]} in
+            0)
+                echo -n .
+                ;;
+            *)
+                echo -n ${grid_arr[$cur_pos]}
+                ;;
+        esac
+        ((cur_pos+=1))
+        if [ $((cur_pos % ($max_x))) -eq 0 ] && [ $cur_pos -gt 0 ]; then
+            echo
+        fi
+    done
+}
+
+get_intersections() {
+    local -n grid_arr=$1
+    local count=0
+
+    for num in "${grid_arr[@]}"; do
+        if [ $num -gt 1 ]; then
+            ((count+=1))
+        fi
+    done
+
+    echo $count
+}
+
+while read -u3 line; do
+    lines+=("$line")
+    get_coords "$line" x1 y1 x2 y2
+    if [ $x1 -gt $max_x ]; then
+        max_x=$x1
+    fi
+    if [ $x2 -gt $max_x ]; then
+        max_x=$x2
+    fi
+    if [ $y1 -gt $max_y ]; then
+        max_y=$y1
+    fi
+    if [ $y2 -gt $max_y ]; then
+        max_y=$y2
+    fi
+done
+
+# because we're 0 based, max_x and max_y want 1 added to make the maths work
+((max_x+=1))
+((max_y+=1))
+
+echo "Size of box: $max_x, $max_y"
+
+generate_grid $max_x $max_y grid
+
+for coords in "${lines[@]}"; do
+    get_coords "$coords" x1 y1 x2 y2
+    if [ $x1 -eq $x2 ] || [ $y1 -eq $y2 ]; then
+        if [ $x1 -eq $x2 ]; then
+            # we're working on a vertical line
+            if [ $y1 -gt $y2 ]; then
+                ytemp=$y1
+                y1=$y2
+                y2=$ytemp
+            fi
+            for (( i=$y1; i<=$y2; i+=1 )); do
+                cur_pos=$(($x1 + ($max_x * $i)))
+                ((grid[$cur_pos]+=1))
+            done
+        elif [ $y1 -eq $y2 ]; then
+            direction=1
+            # we're working on a horizonal line
+            if [ $x1 -gt $x2 ]; then
+                xtemp=$x1
+                x1=$x2
+                x2=$xtemp
+            fi
+            for (( i=$x1; i<=$x2; i+=1 )); do
+                cur_pos=$(($i + ($max_x * $y1)))
+                ((grid[$cur_pos]+=1))
+            done
+        fi
+    fi
+done
+
+#display_grid $max_x grid
+
+intersection_count=$(get_intersections grid)
+
+echo "Intersections (h+v): $intersection_count"
+
+# do the diagonals
+for coords in "${lines[@]}"; do
+    get_coords "$coords" x1 y1 x2 y2
+    if [ $x1 -ne $x2 ] && [ $y1 -ne $y2 ]; then
+        # we've got a diagonal line, woo
+        if [ $y1 -gt $y2 ]; then
+            # swap everything
+            temp=$y1
+            y1=$y2
+            y2=$temp
+            temp=$x1
+            x1=$x2
+            x2=$temp
+        fi
+        cur_x=$x1
+        for (( i=$y1; i<=$y2; i++ )); do
+            cur_pos=$((cur_x + ($max_x * i)))
+            ((grid[$cur_pos]+=1))
+            if [ $x1 -gt $x2 ]; then
+                ((cur_x-=1)) || cur_x=0
+            else
+                ((cur_x+=1))
+            fi
+        done
+    fi
+done
+
+#display_grid $max_x grid
+
+intersection_count=$(get_intersections grid)
+
+echo "Intersections (h+v+d): $intersection_count"