5 filename="${1:-example.txt}"
13 while read -u 3 row; do
14 for (( a=0; a<${#row}; a++ )); do
22 for (( a=0; a<$height; a++ )); do
23 for (( b=0; b<$width; b++ )); do
24 offset=$((($a*$width)+$b))
25 if [ ${low_spots[$offset]+abc} ]; then
28 echo -n "${map[$offset]}"
29 if [ ${low_spots[$offset]+abc} ]; then
40 # we entirely cheat, and just store the index positions
41 # in the array low_spots
44 for (( y=0; y<$height; y++ )); do
45 for (( x=0; x<$width; x++ )); do
46 offset=$((($y*width)+$x))
47 is_lowest=$(check_adjacents $offset)
48 if [ $is_lowest -eq 0 ]; then
49 low_spots[$offset]=$((${map[$offset]}+1))
59 # we'll get y by dividing offset by width
60 local y=$((offset/$width))
61 # and x by taking the remainder of that
62 local x=$((offset%width))
67 above_offset=$(((($y-1)*$width)+$x))
68 if [ ${map[$above_offset]} -le ${map[$offset]} ]; then
72 if [ $y -lt $((height - 1)) ]; then
74 below_offset=$(((($y+1)*$width)+$x))
75 if [ ${map[$below_offset]} -le ${map[$offset]} ]; then
81 left_offset=$((offset-1))
82 if [ ${map[$left_offset]} -le ${map[$offset]} ]; then
86 if [ $x -lt $((width - 1)) ]; then
88 right_offset=$((offset+1))
89 if [ ${map[$right_offset]} -le ${map[$offset]} ]; then
99 local -n __been_checked="$2"
100 local -n __to_check="$3"
101 local x=$((offset % $width))
102 local y=$((offset / $width))
104 __offset=$((($y*$width)+$x))
106 if [ $x -gt 0 ]; then
107 check_offset=$((($y*$width)+($x-1)))
108 if [ ! ${__been_checked[$check_offset]+abc} ] && [ ${map[$check_offset]} -ne 9 ]; then
109 __to_check[$check_offset]=1
112 if [ $y -gt 0 ]; then
113 check_offset=$(((($y-1)*$width)+$x))
114 if [ ! ${__been_checked[$check_offset]+abc} ] && [ ${map[$check_offset]} -ne 9 ]; then
115 __to_check[$check_offset]=1
118 if [ $x -lt $(($width-1)) ]; then
119 check_offset=$((($y*$width)+$x+1))
120 if [ ! ${__been_checked[$check_offset]+abc} ] && [ ${map[$check_offset]} -ne 9 ]; then
121 __to_check[$check_offset]=1
124 if [ $y -lt $(($height-1)) ]; then
125 check_offset=$(((($y+1)*$width)+$x))
126 if [ ! ${__been_checked[$check_offset]+abc} ] && [ ${map[$check_offset]} -ne 9 ]; then
127 __to_check[$check_offset]=1
130 __been_checked[$__offset]=1
131 unset __to_check[$__offset]
135 # we find the basin by using the low_spots.
136 for basin_mid in "${!low_spots[@]}"; do
137 basin_x=$(($basin_mid % $width))
138 basin_y=$(($basin_mid / $width))
142 # add surrounding blocks to the to_check list
143 to_check[$basin_mid]=1
144 while [ ${#to_check[@]} -gt 0 ]; do
145 for offset in "${!to_check[@]}"; do
146 get_surrounding $offset checked to_check
149 # this *should* have avoided all 9s and got anything else in the area that we wanted, so the checked array
150 # at this point should contain the number of elements we care about
151 basins+=("${#checked[@]}")
158 for lowpoint in "${low_spots[@]}"; do
168 echo "The risk is: $(sum_risk)"
173 sorted=($(sort -n <<<"${basins[*]}" | tail -n 3))
175 echo "The largest 3 basin sizes are: ${sorted[@]}"
176 echo "Multiplied together they are: $((${sorted[0]} * ${sorted[1]} * ${sorted[2]}))"