2022 day 8: Bash parts 1 & 2

This commit is contained in:
2022-12-11 18:36:21 +01:00
parent c608f6dcde
commit f5ebb5c5cc
2 changed files with 278 additions and 1 deletions

View File

@@ -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?/ 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: **

211
2022/day08/aoc.bash Executable file
View File

@@ -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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
#
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
. 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[@]}