Day 3 2019
[advent-of-code-2019.git] / day3 / wires_2.sh
1 #!/bin/bash
2
3 set -u
4 set -e
5
6 # these wires should give 6
7 #wire_1=(R8 U5 L5 D3)
8 #wire_2=(U7 R6 D4 L4)
9
10 # these wires should get 159
11 #wire_1=(R75 D30 R83 U83 L12 D49 R71 U7 L72)
12 #wire_2=(U62 R66 U55 R34 D71 R55 D58 R83)
13
14 # these wires should get 135
15 #wire_1=(R98 U47 R26 D63 R33 U87 L62 D20 R33 U53 R51)
16 #wire_2=(U98 R91 D20 R16 D67 R40 U7 R15 U6 R7)
17
18 # read in data from file instead
19 exec 3<input.txt
20 IFS="," read -u 3 -a wire_1
21 IFS="," read -u 3 -a wire_2
22
23 trace_wire() {
24     local -n w=$1
25     local -n b=$2
26     local -n c=$3
27     local -n w1cost=$4
28     wire_number=$5
29     cur_vert=0
30     cur_horz=0
31     moved=0
32     last_replace_char="-"
33     cost=0
34
35     for operation in "${w[@]}"; do
36         direction=${operation:0:1}
37         amount=${operation:1}
38         case $direction in
39             U)
40                 operator=+
41                 ;;
42             D)
43                 operator=-
44                 ;;
45             L)
46                 operator=-
47                 ;;
48             R)
49                 operator=+
50                 ;;
51         esac
52
53         case $direction in
54             U|D)
55                 for (( moved=1; moved <= $amount; moved++ )); do
56                     cur_vert=$((cur_vert${operator}1))
57                     cost=$((cost+1))
58                     if [ $wire_number -eq 1 ]; then
59                         if ! [ ${w1cost[$cur_horz,$cur_vert]+a} ]; then
60                             w1cost[$cur_horz,$cur_vert]=$cost
61                         fi
62                     fi
63                     if [ ${b[$cur_horz,$cur_vert]+a} ] && [ $wire_number -eq 2 ]; then
64                         if [ ${b[$cur_horz,$cur_vert]} -eq 1 ]; then
65                             cross_wires[$cur_horz,$cur_vert]=$((${w1cost[$cur_horz,$cur_vert]}+$cost))
66                             b[$cur_horz,$cur_vert]=3
67                         fi
68                         continue
69                     fi
70                     b[$cur_horz,$cur_vert]=$wire_number
71                 done
72                 ;;
73             L|R)
74                 for (( moved=1; moved <= $amount; moved++ )); do
75                     cur_horz=$((cur_horz${operator}1))
76                     cost=$((cost+1))
77                     if [ $wire_number -eq 1 ]; then
78                         if ! [ ${w1cost[$cur_horz,$cur_vert]+a} ]; then
79                             w1cost[$cur_horz,$cur_vert]=$cost
80                         fi
81                     fi
82                     if [ ${b[$cur_horz,$cur_vert]+a} ] && [ $wire_number -eq 2 ]; then
83                         if [ ${b[$cur_horz,$cur_vert]} -eq 1 ]; then
84                             cross_wires[$cur_horz,$cur_vert]=$((${w1cost[$cur_horz,$cur_vert]}+$cost))
85                             b[$cur_horz,$cur_vert]=3
86                         fi
87                         continue
88                     fi
89                     b[$cur_horz,$cur_vert]=$wire_number
90                 done
91                 ;;
92         esac
93     done
94 }
95
96 declare -A board
97 declare -A cross_wires
98 declare -A wire_1_cost
99 echo "Tracing first wire"
100 trace_wire wire_1 board cross_wires wire_1_cost 1
101 echo "Tracing second wire"
102 trace_wire wire_2 board cross_wires wire_1_cost 2
103
104 echo "Wires cross at:"
105 min_cost=-1
106 for cross in "${!cross_wires[@]}"; do
107     echo "  $cross ${cross_wires[$cross]}"
108     cost=${cross_wires[$cross]}
109     if [ $min_cost -lt 0 ] || [ $min_cost -gt $cost ]; then
110         min_cost=$cost
111     fi
112 done
113
114 echo Min cost: $min_cost