From f5ebb5c5cca39aab159224d86fe227b079c8f527 Mon Sep 17 00:00:00 2001 From: Bruno Raoult Date: Sun, 11 Dec 2022 18:36:21 +0100 Subject: [PATCH] 2022 day 8: Bash parts 1 & 2 --- 2022/day08/README.org | 68 +++++++++++++- 2022/day08/aoc.bash | 211 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 278 insertions(+), 1 deletion(-) create mode 100755 2022/day08/aoc.bash diff --git a/2022/day08/README.org b/2022/day08/README.org index fc6a0f3..5538d64 100644 --- a/2022/day08/README.org +++ b/2022/day08/README.org @@ -53,4 +53,70 @@ a total of =21= trees are visible in this arrangement. Consider your map; /how many trees are visible from outside the grid?/ -To begin, [[file:8/input][get your puzzle input]]. +Your puzzle answer was =1698=. + +** --- Part Two --- +Content with the amount of tree cover available, the Elves just need to +know the best spot to build their tree house: they would like to be able +to see a lot of /trees/. + +To measure the viewing distance from a given tree, look up, down, left, +and right from that tree; stop if you reach an edge or at the first tree +that is the same height or taller than the tree under consideration. (If +a tree is right on the edge, at least one of its viewing distances will +be zero.) + +The Elves don't care about distant trees taller than those found by the +rules above; the proposed tree house has large +[[https://en.wikipedia.org/wiki/Eaves][eaves]] to keep it dry, so they +wouldn't be able to see higher than the tree house anyway. + +In the example above, consider the middle =5= in the second row: + +#+begin_example +30373 +25512 +65332 +33549 +35390 +#+end_example + +- Looking up, its view is not blocked; it can see =1= tree (of height + =3=). +- Looking left, its view is blocked immediately; it can see only =1= + tree (of height =5=, right next to it). +- Looking right, its view is not blocked; it can see =2= trees. +- Looking down, its view is blocked eventually; it can see =2= trees + (one of height =3=, then the tree of height =5= that blocks its view). + +A tree's /scenic score/ is found by /multiplying together/ its viewing +distance in each of the four directions. For this tree, this is =4= +(found by multiplying =1 * 1 * 2 * 2=). + +However, you can do even better: consider the tree of height =5= in the +middle of the fourth row: + +#+begin_example +30373 +25512 +65332 +33549 +35390 +#+end_example + +- Looking up, its view is blocked at =2= trees (by another tree with a + height of =5=). +- Looking left, its view is not blocked; it can see =2= trees. +- Looking down, its view is also not blocked; it can see =1= tree. +- Looking right, its view is blocked at =2= trees (by a massive tree of + height =9=). + +This tree's scenic score is =8= (=2 * 2 * 1 * 2=); this is the ideal +spot for the tree house. + +Consider each tree on your map. /What is the highest scenic score +possible for any tree?/ + +Your puzzle answer was =672280=. + +Both parts of this puzzle are complete! They provide two gold stars: ** diff --git a/2022/day08/aoc.bash b/2022/day08/aoc.bash new file mode 100755 index 0000000..0c6bf6d --- /dev/null +++ b/2022/day08/aoc.bash @@ -0,0 +1,211 @@ +#!/usr/bin/env bash +# +# aoc.bash: Advent of Code 2022, day 8 +# +# Copyright (C) 2022 Bruno Raoult ("br") +# Licensed under the GNU General Public License v3.0 or later. +# Some rights reserved. See COPYING. +# +# You should have received a copy of the GNU General Public License along with this +# program. If not, see . +# +# SPDX-License-Identifier: GPL-3.0-or-later + +. common.bash + +declare -a trees=() # trees height +declare -Ai visible=() # visible if set +declare -i size + +parse() { + readarray -t trees + size=${#trees[@]} +} + + # y=${trees[0]:i:1} + # xrev=${trees[i]:size-1:1} + # yrev=${trees[size-1]:i:1} + # printf "x=%d\n" "$x" + # printf "y=%d\n" "$y" + # printf "xrev=%d\n" "$xrev" +# printf "yrev=%d\n" "$yrev" + +# height - return height of a tree +# $1: reference of return value +# $2, $3: x, y +# x is column, y is row +height() { + local -n _ret="$1" + local -i _x="$2" _y="$3" + _ret=${trees[_y]:_x:1} +} + +check_visible() { + local -n _max="$1" + local -i _x="$2" _y="$3" _c + echo "m=$_max x=$x y=$y" + height _c "$x" "y" + printf "(%d,%d)=%d\n" "$x" "$y" "$_c" + if (( _c > _max )); then + printf "right visible (%d,%d)=%d\n" "$x" "$y" "$_c" + (( visible[$x-$y]++, _max=_c )) + (( _max == 9 )) && return 1 + fi + return 0 +} + +part1() { + declare -ig res + local -i x y max c + + # left to right + for ((y = 1; y < size -1; ++y)); do # row + height max 0 "$y" + printf "**** left=%d max=%d\n" "$i" "$max" + (( max == 9 )) && continue + for ((x = 1; x < size -1; ++x)); do # column + check_visible max "$x" "$y" || break + done + done + echo + # right to left + for ((y = 1; y < size -1; ++y)); do # row + height max $((size - 1)) "$y" + printf "**** right=%d max=%d\n" "$i" "$max" + (( max == 9 )) && continue + for ((x = size - 2; x > 0; --x)); do # column + check_visible max "$x" "$y" || break + done + done + echo + # top to bottom + for ((x = 1; x < size -1; ++x)); do # column + height max "$x" 0 + printf "**** top=%d max=%d\n" "$i" "$max" + (( max == 9 )) && continue + for ((y = 1; y < size -1; ++y)); do # column + check_visible max "$x" "$y" || break + done + done + echo + # bottom to top + for ((x = 1; x < size -1; ++x)); do # row + height max "$x" $((size - 1)) + printf "**** bottom=%d max=%d\n" "$i" "$max" + (( max == 9 )) && continue + for ((y = size - 2; y > 0; --y)); do # column + check_visible max "$x" "$y" || break + done + done + (( res = ${#visible[@]} + size * 4 - 4 )) +} + +check_tree() { + local -n res=$1 + local -i X="$2" Y="$3" c x y h + local -ai vis=() + + height h "$X" "$Y" + printf "********** part2(%d,%d) h=%d\n" "$X" "$Y" "$h" + + # east + for ((x = X + 1; x < size ; ++x)); do + height c "$x" "Y" + printf "(%d,%d)=%d " "$x" "$Y" "$c" + (( vis[0]++ )) + ((c >= h)) && break + done + (( res *= vis[0] )) + echo + printf "east=%d\n" "${vis[0]}" + + # west + for ((x = X - 1; x >= 0; --x)); do + height c "$x" "Y" + printf "(%d,%d)=%d " "$x" "$Y" "$c" + (( vis[1]++ )) + ((c >= h)) && break + done + (( res *= vis[1] )) + echo + printf "west=%d\n" "${vis[1]}" + + # south + for ((y = Y + 1; y < size; ++y)); do + height c "$X" "$y" + printf "(%d,%d)=%d " "$X" "$y" "$c" + (( vis[2]++ )) + ((c >= h)) && break + done + (( res *= vis[2] )) + echo + printf "south=%d\n" "${vis[2]}" + + # north + for ((y = Y - 1; y >= 0; --y)); do + height c "$X" "$y" + printf "(%d,%d)=%d " "$X" "$y" "$c" + (( vis[3]++ )) + ((c >= h)) && break + done + (( res *= vis[3] )) + echo + printf "north=%d\n" "${vis[3]}" + # shellcheck disable=1102 + res=$(( "${vis[@]/%/ *}" 1)) + printf "res(%d,%d)=%d * %d * %d * %d = %d\n" "$X" "$Y" "${vis[0]}" "${vis[1]}" "${vis[2]}" "${vis[3]}" "$res" + echo +} + + +part2() { + local -ig res=0 + local -i tmp=1 x y + + for ((x = 1; x < size - 1; ++x)); do + for ((y = 1; y < size - 1; ++y)); do + #echo "ZOB $x $y" + check_tree tmp "$x" "$y" + if ((tmp > res)); then + ((res = tmp)) + printf "NEW MAX at (%d,%d)=%d\n" "$x" "$y" "$tmp" + fi + done + done + + #check_tree tmp 2 3 +} + +solve() { + if ((part == 1)); then + part1 + else + part2 + fi +} + +main "$@" +exit 0 + + for k in "${!visible[@]}"; do + printf "k=%s %d\n" "$k" "${visible[$k]}" + done + echo + for (( i = 1; i < size - 1; ++i )); do + max=${trees[i]:size-1:1} + printf "i=%d max=%d\n" "$i" "$max" + for (( j = size - 2; j > 0; --j )); do + if (( ${trees[i]:j:1} > max)); then + printf "(%d,%d)=%d max=%d\n" "$i" "$j" "${trees[i]:j:1}" "$max" + (( visible[$i-$j]++ )) + max=${trees[i]:j:1} + printf "new max=%d\n" "$max" + (( max == 9 )) && break + fi + done + done + echo + for k in "${!visible[@]}"; do + printf "k=%s %d\n" "$k" "${visible[$k]}" + done + res=${#visible[@]}