+++ /dev/null
-#!/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
-
-get_min_max() {
- local -n wire=$1
- horz_min=0
- horz_max=0
- vert_min=0
- vert_max=0
- cur_horz=0
- cur_vert=0
- for instruction in "${wire[@]}"; do
- direction=${instruction:0:1}
- amount=${instruction:1}
- case $direction in
- U)
- cur_vert=$((cur_vert+$amount))
- if [ $cur_vert -gt $vert_max ]; then
- vert_max=$cur_vert
- fi
- ;;
- D)
- cur_vert=$((cur_vert-$amount))
- if [ $cur_vert -lt $vert_min ]; then
- vert_min=$cur_vert
- fi
- ;;
- R)
- cur_horz=$((cur_horz+$amount))
- if [ $cur_horz -gt $horz_max ]; then
- horz_max=$cur_horz
- fi
- ;;
- L)
- cur_horz=$((cur_horz-$amount))
- if [ $cur_horz -lt $horz_min ]; then
- horz_min=$cur_horz
- fi
- ;;
- esac
- done
-
- echo "$horz_min,$horz_max,$vert_min,$vert_max"
-}
-
-trace_wire() {
- local -n w=$1
- local -n b=$2
- local -n c=$3
- min_left=$4
- cur_vert=0
- cur_horz=0
- moved=0
- last_replace_char="-"
-
- 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)
- last_replace_char="|"
- offset=$((0-$min_left))
- offset=$((offset+$cur_horz))
- for (( moved=1; moved <= $amount; moved++ )); do
- cur_vert=$((cur_vert${operator}1))
- cur_line=${b[$cur_vert]}
- cur_char=${cur_line:$offset:1}
- replace_char="|"
- if [ $cur_char = "-" ] || [ $cur_char = "|" ]; then
- replace_char="X"
- c+=($cur_horz,$cur_vert)
- fi
- if [ $moved -eq $amount ]; then
- replace_char="+"
- fi
- if [ $cur_vert -eq 0 ] && [ $cur_horz -eq 0 ]; then
- replace_char='o'
- fi
- new_line="${cur_line:0:$((offset))}${replace_char}${cur_line:$((offset+1))}"
- b[$cur_vert]=$new_line
- done
- ;;
- L|R)
- last_replace_char="-"
- # this could change multiple characters in the line
- for (( moved=1; moved <= $amount; moved++ )); do
- cur_horz=$((cur_horz${operator}1))
- offset=$((0-$min_left))
- offset=$((offset+$cur_horz))
- cur_line=${b[$cur_vert]}
- cur_char=${cur_line:$offset:1}
- replace_char="-"
- if [ $cur_char = "-" ] || [ $cur_char = "|" ]; then
- replace_char="X"
- c+=($cur_horz,$cur_vert)
- fi
- if [ $moved -eq $amount ]; then
- replace_char="+"
- fi
- if [ $cur_vert -eq 0 ] && [ $cur_horz -eq 0 ]; then
- replace_char='o'
- fi
- new_line="${cur_line:0:$((offset))}${replace_char}${cur_line:$((offset+1))}"
- b[$cur_vert]=$new_line
- done
- ;;
- esac
- done
-
- cur_line=${b[$cur_vert]}
- offset=$((0-$min_left))
- offset=$((offset+$cur_horz))
- if [ ${cur_line:$offset:1} != 'X' ]; then
- new_line="${cur_line:0:$((offset))}${last_replace_char}${cur_line:$((offset+1))}"
- b[$cur_vert]=$new_line
- fi
- echo
-}
-
-make_board() {
- local -n mm=$1
- local -n b=$2
-
- min_horz=${mm[0]}
- if [ $min_horz -gt 0 ]; then
- min_horz=0
- fi
-
- min_vert=${mm[2]}
- if [ $min_vert -gt 0 ]; then
- min_vert=0
- fi
-
- max_horz=${mm[1]}
- total_horz=$(($max_horz - $min_horz))
-
- max_vert=${mm[3]}
-
- cur_vert=${min_vert}
- blank_string=$(printf ".%.0s" $(eval echo '{0..'$total_horz'}'))
- while [[ $cur_vert -le ${max_vert} ]]; do
- if [[ $cur_vert -eq 0 ]]; then
- offset=$((0-${mm[0]}))
- line="${blank_string:0:$offset}o${blank_string:$((offset+1))}"
- b[$cur_vert]=$line
- else
- b[$cur_vert]=$blank_string
- fi
- cur_vert=$((cur_vert+1))
- done
-}
-
-echo "Getting board boundaries"
-IFS="," read -a min_max < <(get_min_max wire_1)
-IFS="," read -a min_max_2 < <(get_min_max wire_2)
-
-# do the minimums first
-for pos in 0 2; do
- if [ ${min_max[$pos]} -gt ${min_max_2[$pos]} ]; then
- min_max[$pos]=${min_max_2[$pos]}
- fi
-done
-
-# now the maximums
-for pos in 1 3; do
- if [ ${min_max[$pos]} -lt ${min_max_2[$pos]} ]; then
- min_max[$pos]=${min_max_2[$pos]}
- fi
-done
-
-echo " ${min_max[@]}"
-
-# we now know exactly how big the grid is, which is handy, as we'll use it to do offsets
-declare -A board
-declare -a cross_wires
-echo "Building board"
-make_board min_max board
-echo "Tracing first wire"
-trace_wire wire_1 board cross_wires ${min_max[0]}
-echo "Tracing second wire"
-trace_wire wire_2 board cross_wires ${min_max[0]}
-
-for (( a=${min_max[3]}; a>=${min_max[2]}; a-- )); do
- echo ${board[$a]}
-done
-
-echo "Wires cross at:"
-min_distance=-1
-for cross in "${cross_wires[@]}"; do
- echo " $cross"
- horz=${cross%,*}
- horz=${horz//-/}
- vert=${cross#*,}
- vert=${vert//-/}
- distance=$((horz+$vert))
- if [ $min_distance -lt 0 ] || [ $min_distance -gt $distance ]; then
- min_distance=$distance
- fi
-done
-
-echo Min distance: $min_distance