Rename days to 2 digits always
[advent-of-code-2019.git] / day03 / wires_2.sh
diff --git a/day03/wires_2.sh b/day03/wires_2.sh
new file mode 100644 (file)
index 0000000..1e86e0c
--- /dev/null
@@ -0,0 +1,114 @@
+#!/bin/bash
+
+set -u
+set -e
+
+# these wires should give 6
+#wire_1=(R8 U5 L5 D3)
+#wire_2=(U7 R6 D4 L4)
+
+# these wires should get 159
+#wire_1=(R75 D30 R83 U83 L12 D49 R71 U7 L72)
+#wire_2=(U62 R66 U55 R34 D71 R55 D58 R83)
+
+# these wires should get 135
+#wire_1=(R98 U47 R26 D63 R33 U87 L62 D20 R33 U53 R51)
+#wire_2=(U98 R91 D20 R16 D67 R40 U7 R15 U6 R7)
+
+# read in data from file instead
+exec 3<input.txt
+IFS="," read -u 3 -a wire_1
+IFS="," read -u 3 -a wire_2
+
+trace_wire() {
+    local -n w=$1
+    local -n b=$2
+    local -n c=$3
+    local -n w1cost=$4
+    wire_number=$5
+    cur_vert=0
+    cur_horz=0
+    moved=0
+    last_replace_char="-"
+    cost=0
+
+    for operation in "${w[@]}"; do
+        direction=${operation:0:1}
+        amount=${operation:1}
+        case $direction in
+            U)
+                operator=+
+                ;;
+            D)
+                operator=-
+                ;;
+            L)
+                operator=-
+                ;;
+            R)
+                operator=+
+                ;;
+        esac
+
+        case $direction in
+            U|D)
+                for (( moved=1; moved <= $amount; moved++ )); do
+                    cur_vert=$((cur_vert${operator}1))
+                    cost=$((cost+1))
+                    if [ $wire_number -eq 1 ]; then
+                        if ! [ ${w1cost[$cur_horz,$cur_vert]+a} ]; then
+                            w1cost[$cur_horz,$cur_vert]=$cost
+                        fi
+                    fi
+                    if [ ${b[$cur_horz,$cur_vert]+a} ] && [ $wire_number -eq 2 ]; then
+                        if [ ${b[$cur_horz,$cur_vert]} -eq 1 ]; then
+                            cross_wires[$cur_horz,$cur_vert]=$((${w1cost[$cur_horz,$cur_vert]}+$cost))
+                            b[$cur_horz,$cur_vert]=3
+                        fi
+                        continue
+                    fi
+                    b[$cur_horz,$cur_vert]=$wire_number
+                done
+                ;;
+            L|R)
+                for (( moved=1; moved <= $amount; moved++ )); do
+                    cur_horz=$((cur_horz${operator}1))
+                    cost=$((cost+1))
+                    if [ $wire_number -eq 1 ]; then
+                        if ! [ ${w1cost[$cur_horz,$cur_vert]+a} ]; then
+                            w1cost[$cur_horz,$cur_vert]=$cost
+                        fi
+                    fi
+                    if [ ${b[$cur_horz,$cur_vert]+a} ] && [ $wire_number -eq 2 ]; then
+                        if [ ${b[$cur_horz,$cur_vert]} -eq 1 ]; then
+                            cross_wires[$cur_horz,$cur_vert]=$((${w1cost[$cur_horz,$cur_vert]}+$cost))
+                            b[$cur_horz,$cur_vert]=3
+                        fi
+                        continue
+                    fi
+                    b[$cur_horz,$cur_vert]=$wire_number
+                done
+                ;;
+        esac
+    done
+}
+
+declare -A board
+declare -A cross_wires
+declare -A wire_1_cost
+echo "Tracing first wire"
+trace_wire wire_1 board cross_wires wire_1_cost 1
+echo "Tracing second wire"
+trace_wire wire_2 board cross_wires wire_1_cost 2
+
+echo "Wires cross at:"
+min_cost=-1
+for cross in "${!cross_wires[@]}"; do
+    echo "  $cross ${cross_wires[$cross]}"
+    cost=${cross_wires[$cross]}
+    if [ $min_cost -lt 0 ] || [ $min_cost -gt $cost ]; then
+        min_cost=$cost
+    fi
+done
+
+echo Min cost: $min_cost