From c4d07ccc686ba834151431d1fbd3cf35fe2f3b06 Mon Sep 17 00:00:00 2001 From: Brett Parker <iDunno@sommitrealweird.co.uk> Date: Sun, 6 Dec 2020 17:23:35 +0000 Subject: [PATCH] First attempt --- day3/wires.sh | 235 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 235 insertions(+) create mode 100644 day3/wires.sh diff --git a/day3/wires.sh b/day3/wires.sh new file mode 100644 index 0000000..a28765a --- /dev/null +++ b/day3/wires.sh @@ -0,0 +1,235 @@ +#!/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 -- 2.39.5