75 lines
1.7 KiB
Bash
75 lines
1.7 KiB
Bash
|
#!/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
|