From 6db27abe8665a8a34ce1590cfe1a667bf843d7ad Mon Sep 17 00:00:00 2001 From: Brett Parker Date: Tue, 8 Dec 2020 09:25:33 +0000 Subject: [PATCH] Most of part 2 --- day11/computer.sh | 144 ++++++++++++++++++++++++++++++++++++++++++++ day11/input.txt | 1 + day11/robot.sh | 149 ++++++++++++++++++++++++++++++++++++++++++++++ day11/run.sh | 34 +++++++++++ day11/run2.sh | 35 +++++++++++ 5 files changed, 363 insertions(+) create mode 100644 day11/computer.sh create mode 100644 day11/input.txt create mode 100644 day11/robot.sh create mode 100755 day11/run.sh create mode 100755 day11/run2.sh diff --git a/day11/computer.sh b/day11/computer.sh new file mode 100644 index 0000000..b8fa4cf --- /dev/null +++ b/day11/computer.sh @@ -0,0 +1,144 @@ +#!/bin/bash + +declare -a data + +get_value() { + local -n da=$1 + local index=$2 + + if [ $index -lt 0 ]; then + echo "Index negative, give up!" + exit 2 + fi + + if ! [ ${da[$index]+a} ]; then + da[$index]=0 + fi + + echo "${da[$index]}" +} + +get_param() { + local -n dap=$1 + local pos=$2 + local mode=$3 + local relative_base=$4 + + loc=$(get_param_loc dap $pos $mode $relative_base) + + get_value dap $loc +} + +get_param_loc() { + local -n dapl=$1 + local pos=$2 + local mode=$3 + local relative_base=$4 + + case $mode in + 0) + get_value dapl $pos + ;; + 1) + echo $pos + ;; + 2) + move_by=$(get_value dapl $pos) + echo $((relative_base+$move_by)) + ;; + *) + echo "Unknown parameter mode: $mode" + exit 2 + ;; + esac +} + +run_program() { + local -n od=$1 + local relative_base=0 + data=("${od[@]}") + pos=0 + declare -a immediate + while [ $pos -le ${#data[@]} ]; do + # first, printf the value to 5 digits + instruction=$(printf "%05d" ${data[$pos]}) + for (( a=0; a<3; a++ )); do + immediate[$((3-a))]=${instruction:$a:1} + done + instruction=${instruction:3} + param_count=3 + echo -n $'\r'" "$'\r'$instruction >&2 + case $instruction in + 01|02) + # 01 - add, 02 multiply + symbol="+" + if [ $instruction == "02" ]; then + symbol="*" + fi + val1=$(get_param data $((pos+1)) ${immediate[1]} $relative_base) + val2=$(get_param data $((pos+2)) ${immediate[2]} $relative_base) + res_loc=$(get_param_loc data $((pos+3)) ${immediate[3]} $relative_base) + data[$res_loc]=$(($val1 $symbol $val2)) + ;; + 03) + # 03 - read input + echo -n $'\r'" "$'\r' >&2 + read -p "input: " input + res_loc=$(get_param_loc data $((pos+1)) ${immediate[1]} $relative_base) + data[$res_loc]=$input + param_count=1 + ;; + 04) + # 04 - output + val=$(get_param data $((pos+1)) ${immediate[1]} $relative_base) + echo -n $'\r'" "$'\r' >&2 + echo $val + param_count=1 + ;; + 05|06) + # 05 - jump-if-true, 06 - jump-if-false + val=$(get_param data $((pos+1)) ${immediate[1]} $relative_base) + jumpto=$(get_param data $((pos+2)) ${immediate[2]} $relative_base) + param_count=2 + if ( [ $val -ne 0 ] && [ "$instruction" == "05" ] ) || + ( [ $val -eq 0 ] && [ "$instruction" == "06" ] ); then + pos=$jumpto + continue + fi + ;; + 07|08) + # 07 - is less than, 08 - is equal + val1=$(get_param data $((pos+1)) ${immediate[1]} $relative_base) + val2=$(get_param data $((pos+2)) ${immediate[2]} $relative_base) + res_pos=$(get_param_loc data $((pos+3)) ${immediate[3]} $relative_base) + data[$res_pos]=0 + if [ "$instruction" == "07" ]; then + if [ $val1 -lt $val2 ]; then + data[$res_pos]=1 + fi + else + if [ $val1 -eq $val2 ]; then + data[$res_pos]=1 + fi + fi + ;; + 09) + # adjust relative base + param_count=1 + val=$(get_param data $((pos+1)) ${immediate[1]} $relative_base) + relative_base=$((relative_base+$val)) + ;; + 99) + break + ;; + *) + echo "Invalid opcode: $instruction at position $pos" + exit 1 + ;; + esac + pos=$(($pos+$param_count+1)) + done + echo -n $'\r'" "$'\r' + echo -n $'\r'" "$'\r' +} + diff --git a/day11/input.txt b/day11/input.txt new file mode 100644 index 0000000..b1a2f81 --- /dev/null +++ b/day11/input.txt @@ -0,0 +1 @@ +3,8,1005,8,332,1106,0,11,0,0,0,104,1,104,0,3,8,102,-1,8,10,101,1,10,10,4,10,108,1,8,10,4,10,101,0,8,28,3,8,102,-1,8,10,1001,10,1,10,4,10,1008,8,1,10,4,10,101,0,8,51,1,1103,5,10,1,1104,9,10,2,1003,0,10,1,5,16,10,3,8,102,-1,8,10,101,1,10,10,4,10,108,0,8,10,4,10,1001,8,0,88,1006,0,2,1006,0,62,2,8,2,10,3,8,1002,8,-1,10,101,1,10,10,4,10,1008,8,1,10,4,10,102,1,8,121,1006,0,91,1006,0,22,1006,0,23,1006,0,1,3,8,102,-1,8,10,1001,10,1,10,4,10,1008,8,1,10,4,10,101,0,8,155,1006,0,97,1,1004,2,10,2,1003,6,10,3,8,1002,8,-1,10,101,1,10,10,4,10,108,0,8,10,4,10,1002,8,1,187,1,104,15,10,2,107,9,10,1006,0,37,1006,0,39,3,8,1002,8,-1,10,1001,10,1,10,4,10,108,0,8,10,4,10,102,1,8,223,2,2,17,10,1,1102,5,10,3,8,1002,8,-1,10,101,1,10,10,4,10,108,0,8,10,4,10,1001,8,0,253,3,8,102,-1,8,10,1001,10,1,10,4,10,1008,8,1,10,4,10,1002,8,1,276,1006,0,84,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,0,10,4,10,1001,8,0,301,2,1009,9,10,1006,0,10,2,102,15,10,101,1,9,9,1007,9,997,10,1005,10,15,99,109,654,104,0,104,1,21102,1,936995738516,1,21101,0,349,0,1105,1,453,21102,1,825595015976,1,21102,1,360,0,1105,1,453,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,21102,46375541763,1,1,21101,0,407,0,1105,1,453,21102,1,179339005019,1,21101,0,418,0,1106,0,453,3,10,104,0,104,0,3,10,104,0,104,0,21102,825012036372,1,1,21102,441,1,0,1105,1,453,21101,988648461076,0,1,21101,452,0,0,1105,1,453,99,109,2,22102,1,-1,1,21102,40,1,2,21102,484,1,3,21101,0,474,0,1106,0,517,109,-2,2105,1,0,0,1,0,0,1,109,2,3,10,204,-1,1001,479,480,495,4,0,1001,479,1,479,108,4,479,10,1006,10,511,1102,1,0,479,109,-2,2105,1,0,0,109,4,2102,1,-1,516,1207,-3,0,10,1006,10,534,21101,0,0,-3,21202,-3,1,1,22101,0,-2,2,21102,1,1,3,21102,553,1,0,1106,0,558,109,-4,2106,0,0,109,5,1207,-3,1,10,1006,10,581,2207,-4,-2,10,1006,10,581,22102,1,-4,-4,1105,1,649,21202,-4,1,1,21201,-3,-1,2,21202,-2,2,3,21101,0,600,0,1105,1,558,21201,1,0,-4,21101,0,1,-1,2207,-4,-2,10,1006,10,619,21101,0,0,-1,22202,-2,-1,-2,2107,0,-3,10,1006,10,641,22102,1,-1,1,21102,1,641,0,106,0,516,21202,-2,-1,-2,22201,-4,-2,-4,109,-5,2105,1,0 diff --git a/day11/robot.sh b/day11/robot.sh new file mode 100644 index 0000000..c5b5613 --- /dev/null +++ b/day11/robot.sh @@ -0,0 +1,149 @@ +#!/bin/bash + +set -u + +__robot_direction=u +__robot_lowest_x=0 +__robot_lowest_y=0 +__robot_highest_x=0 +__robot_highest_y=0 +__robot_cur_x=0 +__robot_cur_y=0 +__robot_start_on_white=0 +declare -A __robot_grid +declare -A __robot_painted + +reset_robot() { + __robot_direction=u + __robot_lowest_x=0 + __robot_lowest_y=0 + __robot_highest_x=0 + __robot_highest_y=0 + __robot_cur_x=0 + __robot_cur_y=0 + __robot_start_on_white=0 + unset __robot_grid + unset __robot_painted + declare -g -A __robot_grid + declare -g -A __robot_painted +} + +get_robot_paint_colour() { + get_paint_colour $__robot_cur_x $__robot_cur_y +} + +get_paint_colour() { + x=$1 + y=$2 + + if [ ${__robot_grid[$x,$y]+a} ]; then + echo ${__robot_grid[$x,$y]} + else + if [ $x -eq 0 ] && [ $y -eq 0 ] && [ $__start_on_white -eq 1 ]; then + echo 1 + else + echo 0 + fi + fi +} + +set_robot_start_on_white() { + start=${1:-1} + + __robot_start_on_white=$start +} + +set_robot_paint_colour() { + paint_colour=$1 + + __robot_grid[$__robot_cur_x,$__robot_cur_y]=$paint_colour + if ! [ ${__robot_painted[$__robot_cur_x,$__robot_cur_y]+a} ]; then + __robot_painted[$__robot_cur_x,$__robot_cur_y]=1 + fi +} + +get_robot_paint_count() { + echo ${#__robot_painted[@]} +} + +do_robot_move() { + direction=$1 + + case $direction in + 0) + case $__robot_direction in + u) + __robot_direction=l + __robot_cur_x=$((__robot_cur_x - 1)) + ;; + l) + __robot_direction=d + __robot_cur_y=$((__robot_cur_y - 1)) + ;; + d) + __robot_direction=r + __robot_cur_x=$((__robot_cur_x + 1)) + ;; + r) + __robot_direction=u + __robot_cur_y=$((__robot_cur_y + 1)) + ;; + esac + ;; + 1) + case $__robot_direction in + u) + __robot_direction=r + __robot_cur_x=$((__robot_cur_x + 1)) + ;; + r) + __robot_direction=d + __robot_cur_y=$((__robot_cur_y - 1)) + ;; + d) + __robot_direction=l + __robot_cur_x=$((__robot_cur_x - 1)) + ;; + l) + __robot_direction=u + __robot_cur_y=$((__robot_cur_y + 1)) + ;; + esac + ;; + esac + + # adjust min/max + if [ $__robot_cur_x -lt $__robot_lowest_x ]; then + __robot_lowest_x=$__robot_cur_x + fi + + if [ $__robot_cur_x -gt $__robot_highest_x ]; then + __robot_highest_x=$__robot_cur_x + fi + + if [ $__robot_cur_y -lt $__robot_lowest_y ]; then + __robot_lowest_y=$__robot_cur_y + fi + + if [ $__robot_cur_y -gt $__robot_highest_y ]; then + __robot_highest_y=$__robot_cur_y + fi +} + +do_robot_paint_and_move() { + paint_colour=$1 + direction=$2 + set_robot_paint_colour $paint_colour + do_robot_move $direction +} + +draw_panel() { + colours=("." "#") + + for (( y=$__robot_lowest_y; y<=$__robot_highest_y; y++ )); do + for (( x=$__robot_lowest_x; x<=$__robot_highest_x; x++ )); do + echo -n ${colours[$(get_paint_colour $x $y)]} + done + echo + done +} diff --git a/day11/run.sh b/day11/run.sh new file mode 100755 index 0000000..353ce16 --- /dev/null +++ b/day11/run.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +set -u + +exec 3/dev/null 2>&1 ); do + get_robot_paint_colour >&${computer[1]} + read -u ${computer[0]} direction + read -u ${computer[0]} colour + do_robot_paint_and_move $direction $colour + sleep 0.1 +done + +# just incase the spinner is still about +echo -n $'\r'" "$'\r' + +# we've done all the painting, now lets display it +draw_panel + +echo +echo "Painted: $(get_robot_paint_count) panels at least once" diff --git a/day11/run2.sh b/day11/run2.sh new file mode 100755 index 0000000..9520560 --- /dev/null +++ b/day11/run2.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +set -u +set -e + +exec 3/dev/null 2>&1 ); do + get_robot_paint_colour >&${computer[1]} + read -u ${computer[0]} direction + read -u ${computer[0]} colour + do_robot_paint_and_move $direction $colour + sleep 0.1 +done + +# just incase the spinner is still about +echo -n $'\r'" "$'\r' + +# we've done all the painting, now lets display it +draw_panel + +echo +echo "Painted: $(get_robot_paint_count) panels at least once" -- 2.39.5