+declare -A asteroids
+declare __asteroids_grid_height
+declare __asteroids_grid_width
+
+get_grid_height() {
+ echo $__asteroids_grid_height
+}
+
+get_grid_width() {
+ echo $__asteroids_grid_width
+}
+
+read_file() {
+ filename="$1"
+
+ if [ ! -e "$filename" ]; then
+ echo "Couldn't find file: $filename"
+ exit 2
+ fi
+
+ exec 3<"$filename"
+ unset asteroids
+ declare -g -A asteroids
+
+ __asteroids_grid_height=0
+ __asteroids_grid_width=0
+
+ while read -u 3 line; do
+ __asteroids_grid_width=${#line}
+ for (( a=0; a<${#line}; a++ )); do
+ char=${line:$a:1}
+ if [ "${char}" == "#" ]; then
+ asteroids[$a,$__asteroids_grid_height]=0
+ fi
+ done
+ __asteroids_grid_height=$((__asteroids_grid_height+1))
+ done
+}
+
get_vector() {
local x1=$1
local y1=$2
get_vector $x1 $y1 $x2 $y2
}
+get_angle() {
+ local a1=$1
+ local a2=$2
+
+ local vector=$(get_asteroids_vector $a1 $a2)
+ local move_x=${vector%,*}
+ local move_y=${vector#*,}
+
+ val="$(calc -p 'round(((90 + ((180/pi()) * atan2('$move_y','$move_x'))) % 360) * 100000000) / 100000000')"
+ echo "$val"
+}
+
+get_closest_asteroid() {
+ local asteroids=$1
+
+ local IFS="|"
+ local min_dist=-1
+ local nearest_asteroid=
+ local x=0
+ local y=0
+
+ for asteroid in $asteroids; do
+ vector=$(get_asteroids_vector $our_asteroid $asteroid)
+ x=${vector%,*}
+ y=${vector#*,}
+ # use absolute numbers for length calculation!
+ x=${x#-}
+ y=${y#-}
+
+ distance=$((x+y))
+ if [ $distance -lt $min_dist -o $min_dist -eq -1 ]; then
+ min_dist=$distance
+ nearest_asteroid=$asteroid
+ fi
+ done
+
+ echo $nearest_asteroid
+}
+
+remove_asteroid_from_string() {
+ local asteroids=$1
+ local asteroid=$2
+ local new_asteroids=
+ local a
+
+ local IFS="|"
+ local seperator=""
+
+ for a in $asteroids; do
+ if [ "$a" != "$asteroid" ]; then
+ new_asteroids+="${seperator}$a"
+ fi
+ if [ "x$new_asteroids" != "x" ]; then
+ seperator="|"
+ fi
+ done
+
+ echo "$new_asteroids"
+}
+
+get_angles_list() {
+ local -n __asteroid_angles=$1
+ printf "%s\n" "${!__asteroid_angles[@]}" | sort -g
+}