6 basedir=$(dirname $(readlink -f ${BASH_SOURCE}))
8 filename=${1:-$basedir/3_4_8.txt}
18 while read -u 3 line; do
20 for (( a=0; a<${#line}; a++ )); do
22 if [ "${char}" == "#" ]; then
29 debug_line=true # default to not actually outputting any debug info
31 if [ ${DEBUG:-0} -gt 0 ]; then
49 echo "$x_diff,$y_diff"
53 # we want to know if vector2 is going to get in the way of vector1
57 $debug_line Comparing: $vector1 $vector2
59 vector1_x=${vector1%,*}
60 vector1_y=${vector1#*,}
61 vector2_x=${vector2%,*}
62 vector2_y=${vector2#*,}
64 # potentially blocking asteroid
65 # first calculate the minimum x and y steps that are whole numbers
66 # min number first, we'll then halve it and work through the steps
68 # work out which asteroid is furthest from use
69 vector1_x_val=${vector1_x#-}
70 vector1_y_val=${vector1_y#-}
71 vector2_x_val=${vector2_x#-}
72 vector2_y_val=${vector2_y#-}
74 minimum_number=$vector2_x_val
75 if [ $vector2_x_val -gt $vector2_y_val -a $vector2_y_val -gt 0 ] || [ $minimum_number -eq 0 ]; then
76 minimum_number=$vector2_y_val
79 $debug_line "Min number: $minimum_number"
83 for (( a=$minimum_number; a>0; a-- )); do
84 if [ $((vector2_x % $a)) -eq 0 -a $((vector2_y % $a)) -eq 0 ]; then
85 minstep_x=$((vector2_x / $a))
86 minstep_y=$((vector2_y / $a))
90 $debug_line "Have minsteps: $minstep_x,$minstep_y"
92 # in all other cases, we're at least heading in the right direction
96 $debug_line "Looking for: $vector1_x,$vector1_y"
97 $debug_line "Start: $cur_x,$cur_y"
99 # from the starting point, add the min steps until we're past the other asteroid
100 while keep_going $cur_x $cur_y $minstep_x $minstep_y $vector1_x $vector1_y; do
101 cur_x=$((cur_x+$minstep_x))
102 cur_y=$((cur_y+$minstep_y))
103 $debug_line "Step: $cur_x,$cur_y"
104 if [ $cur_x -eq $vector1_x -a $cur_y -eq $vector1_y ]; then
105 $debug_line "Collision!"
115 start_x=${asteroid%,*}
116 start_y=${asteroid#*,}
126 # -1, 1 - diagonal left down
127 # -1,-1 - diagonal left up
128 # 1, 1 - diagonal right down
129 # 1,-1 - diagonal right up
130 for direction in -1,0 1,0 0,1 0,-1 -1,1 -1,-1 1,1 1,-1; do
131 #for direction in "-1,0" "1,0" "0,1" "0,-1"; do
132 stepx=${direction%,*}
133 stepy=${direction#*,}
134 do_blocker_check $start_x $start_y $stepx $stepy
146 if [ $stepx -eq 0 -a $stepy -eq 0 ]; then
147 echo "Somehow got 0 and 0 as steps"
154 # add the steps before we start the loop to not be
159 while [ $x -le $width -a $x -ge 0 -a $y -le $ln -a $y -ge 0 ]; do
160 if [ ${asteroids[$x,$y]+a} ]; then
161 if [ $hitblocker -eq 0 ]; then
162 cansee[$asteroid,$x,$y]=1
163 cansee[$x,$y,$startx,$starty]=1
166 cantsee[$startx,$starty,$x,$y]=1
167 cantsee[$x,$y,$startx,$starty]=1
183 # first check the horizontal and vertical planes
184 if [[ ( $source_x -eq $sink_x && $sink_x -eq $blocker_x ) && ( $sink_y -gt $blocker_y && $blocker_y -gt $source_y ) || ( $sink_y -lt $blocker_y && $blocker_y -lt $source_y ) ]] ||
185 [[ ( $source_y -eq $sink_y && $sink_y -eq $blocker_y ) && ( $sink_x -gt $blocker_x && $blocker_x -gt $source_x ) || ( $sink_x -lt $blocker_x && $blocker_x -lt $source_x ) ]]; then
189 # if our source asteroid is further to the right thank our sink, then to stand half a chance
190 # of being in the way, the blocker has to be x > $sink_x and x < source_x
191 # apply the same rule for y
192 # reverse the direction and do the same checks.
193 # So if source_x < sink_x then blocker_x has to be < sink_x > source_x
194 if [ $source_x -gt $sink_x -a $blocker_x -gt $sink_x -a $blocker_x -lt $source_x ] ||
195 [ $source_y -gt $sink_y -a $blocker_y -gt $sink_y -a $blocker_y -lt $source_y ] ||
196 [ $source_x -lt $sink_x -a $blocker_x -lt $sink_x -a $blocker_x -gt $source_x ] ||
197 [ $source_y -lt $sink_y -a $blocker_y -lt $sink_y -a $blocker_y -gt $source_y ]; then
212 if [ $minstep_x -lt 0 -a $cur_x -lt $ast_x ] ||
213 [ $minstep_y -lt 0 -a $cur_y -lt $ast_y ] ||
214 [ $minstep_x -gt 0 -a $cur_x -gt $ast_x ] ||
215 [ $minstep_y -gt 0 -a $cur_y -gt $ast_y ]; then
216 $debug_line "keepgoing finished"
223 # we check for if the first asteroid is blocked viewing the second asteroid
224 # by the third asteroid, if not we add 1 to it's total
225 asteroid_loop=("${!asteroids[@]}")
227 start_count=${#asteroids[@]}
228 for asteroid in ${asteroid_loop[@]}; do
229 ast1_x=${asteroid%,*}
230 ast1_y=${asteroid#*,}
231 cur_count=${#asteroid_loop[@]}
232 percent=$((100-(100*$cur_count / $start_count)))
234 $debug_line "Doing fast checks"
235 fast_checks $asteroid
236 $debug_line "Running main loops"
238 printf '\r%02d%% complete' $percent
239 for asteroid2 in ${asteroid_loop[@]}; do
240 if [ $asteroid2 == $asteroid ]; then
243 ast2_x=${asteroid2%,*}
244 ast2_y=${asteroid2#*,}
246 vector1=$(get_vector $ast1_x $ast1_y $ast2_x $ast2_y)
248 # if we've got a cached can't see, use it to continue the loop
249 if [ ${cantsee[$asteroid,$asteroid2]+a} ]; then
253 if ! [ ${cansee[$asteroid,$asteroid2]+a} ]; then # we already calculated this
254 for asteroid3 in "${!asteroids[@]}"; do
255 if [ $asteroid == $asteroid3 ] || [ $asteroid2 == $asteroid3 ]; then
258 ast3_x=${asteroid3%,*}
259 ast3_y=${asteroid3#*,}
261 # if this asteroid can't be in the way, continue the loop
262 if ! possibly_in_way $ast1_x $ast1_y $ast2_x $ast2_y $ast3_x $ast3_y; then
263 $debug_line "Apparently $ast1_x $ast1_y to $ast2_x $ast2_y cannot be blocked by $ast3_x $ast3_y"
267 $debug_line "Checking for collision between $asteroid and $asteroid2 by $asteroid3"
268 vector2=$(get_vector $ast1_x $ast1_y $ast3_x $ast3_y)
269 if ( check_collision $vector1 $vector2 ); then
270 # path is blocked go on to next in outer loop
271 $debug_line "We hit $asteroid3 when looking for $asteroid2 from $asteroid"
272 cantsee[$asteroid2,$asteroid]=1
273 cantsee[$asteroid,$asteroid2]=1
278 # nothing blocked the view of asteroid2 from asteroid1
279 $debug_line "Apparently $asteroid can see $asteroid2"
280 asteroids[$asteroid]=$((${asteroids[$asteroid]}+1))
281 asteroids[$asteroid2]=$((${asteroids[$asteroid2]}+1))
282 cansee[$asteroid2,$asteroid]=1 # don't bother doing the expensive calculations on the return path
284 unset asteroid_loop[$index]
287 echo -n $'\r'" "$'\r'
291 for asteroid in ${!asteroids[@]}; do
292 count=${asteroids[$asteroid]}
293 if [ $count -gt $best_count ]; then
297 $debug_line "$asteroid: ${asteroids[$asteroid]}"
300 echo "Best asteroid: $best_ast which can see $best_count asteroids"
303 #printf "%.0s-" $(seq 1 $width)
305 ## redraw the board with numbers
306 #for (( a=0; a<$ln; a++ )); do
308 # for (( b=0; b<$width; b++ )); do
309 # if [ ${asteroids[$b,$a]+a} ]; then
310 # echo -n ${asteroids[$b,$a]}
318 #printf "%.0s-" $(seq 1 $width)