2022 day 8: Bash parts 1 & 2
This commit is contained in:
@@ -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
211
2022/day08/aoc.bash
Executable 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[@]}
|
Reference in New Issue
Block a user