aoc/2023/3/1/solution.sh

75 lines
1.7 KiB
Bash
Executable File

#!/usr/bin/env bash
set -o errexit
set -o nounset
set -o pipefail
if [[ "${TRACE-0}" == "1" ]]; then
set -o xtrace
fi
LINES=$(wc -l < "$1")
COLUMNS=140
mapfile -t -O 1 INPUT < "$1"
declare -a valid_numbers
find_numbers ()
{
# Find and append valid numbers to array.
for ((line=1; line<=LINES; line++)); do
for ((column=1; column<=COLUMNS; column++)); do
if [[ $(arr "${line}" $((column-1))) =~ ^[0-9]$ ]]; then
continue # not start of number
else
local number='' length=0
for ((i=column; ; i++)); do # find length
if [[ $(arr "${line}" "${i}") =~ ^[0-9]$ ]]; then
((length++)) || true
else
break
fi
done
[[ length -gt 0 ]] || continue # not a number
for ((i=0; i<length; i++)); do # get number
number+="$(arr "${line}" $((column+i)))"
done
declare -a to_check=("${line},$((column-1))" "${line},$((column+length))") # before and after
for ((i=column-1; i<=column+length; i++)); do
to_check+=("$((line-1)),${i}") # above
to_check+=("$((line+1)),${i}") # below
done
for ((i=0; i<${#to_check[@]}; i++)); do
if [[ $(arr "${to_check[i]%,*}" "${to_check[i]#*,}") =~ ^(\$|\*|/|=|\+|-|#|@|&|%)$ ]]; then
valid_numbers+=("${number}")
break
fi
done
fi
done
done
}
arr ()
{
# Usage: arr LINE COLUMN
line="$1"
column=$(($2-1))
if ((line<=0)) || ((line>LINES)) || ((column<0)); then
echo -n ''
else
echo -n "${INPUT[${line}]:${column}:1}"
fi
}
main ()
{
find_numbers
sum=0
for number in "${valid_numbers[@]}"; do
sum=$((sum+number))
done
echo $sum
}
main