#!/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 gear_ratios find_gears () { # Find and append gear ratios to array. for ((line=1; line<=LINES; line++)); do for ((column=1; column<=COLUMNS; column++)); do if [[ $(arr "${line}" "${column}") =~ ^\*$ ]]; then declare -i ratio=1 declare -a adjacent=() for ((i=column-1; i<=column+1; i++)); do # check above if [[ $(arr $((line-1)) "${i}") =~ ^[0-9]$ ]]; then number="$(arr $((line-1)) "${i}")" for ((j=i-1; j>i-3; j--)); do # check before i, numbers are max 3-digit if [[ $(arr $((line-1)) "${j}") =~ ^[0-9]$ ]]; then number="$(arr $((line-1)) "${j}")${number}" else break fi done add_to_i=0 for ((k=i+1; ki-3; j--)); do # check before i if [[ $(arr $((line+1)) "${j}") =~ ^[0-9]$ ]]; then number="$(arr $((line+1)) "${j}")${number}" else break fi done add_to_i=0 for ((k=i+1; kcolumn-4; i--)); do # search for beginning if [[ $(arr "${line}" "${i}") =~ ^[0-9]$ ]]; then number="$(arr "${line}" "${i}")${number}" else break fi done adjacent+=("${number}") fi if [[ $(arr "${line}" $((column+1))) =~ ^[0-9]$ ]]; then # check after gear number="$(arr "${line}" $((column+1)))" for ((i=column+2; iLINES)) || ((column<0)); then echo -n '' else echo -n "${INPUT[${line}]:${column}:1}" fi } main () { find_gears sum=0 for number in "${gear_ratios[@]}"; do sum=$((sum+number)) done echo "${sum}" } main