#!/usr/bin/env bash FILE=test-input-1 read -r -a MAP_ARRAY <<< "$( < "$FILE" paste -s -d "" | sed -E 's/(.)/\1\ /g' )" MAP_LEN=${#MAP_ARRAY[@]} MAP_WIDTH=$(( $( head -1 "$FILE" | wc -c ) -1 )) MAP_HEIGHT=$( < "$FILE" wc -l ) printf "Len: %s Width: %s Height: %s\n" "$MAP_LEN" "$MAP_WIDTH" "$MAP_HEIGHT" # Check if tiles are adjacent and do not violate bounds check_adjacent () { # Check for out of map bounds if [[ $2 -lt 0 ]] || [[ $2 -gt $MAP_LEN ]] then return 1 fi DIFF=$(( $2 - $1 )) # Valid adjacent distances case "$DIFF" in 1|-1|"${MAP_WIDTH}"|-"${MAP_WIDTH}") : ;; *) return 1 ;; esac # Check for left/right bounds if [[ $DIFF -eq 1 ]] && [[ $(( $2 % MAP_WIDTH )) -eq 0 ]] then return 1 fi if [[ $DIFF -eq -1 ]] && [[ $(( $1 % MAP_WIDTH )) -eq 0 ]] then return 1 fi return 0 } # Basically recurse over mapping and "consume" all adjacent tiles check_and_unset () { IDX=$1 local KV_I=${IDX%% *} # Remove trailing whitespace if [[ -v KV_CACHE[$KV_I] ]] # Check if tile has been "taken" then (( AREA++ )) VALUE=${KV_CACHE[$IDX]} printf "max: %s peri: %s area: %s key: %s val: %s\n" "$MAX_PERI" "$PERI_NUM" "$AREA" "$1" "$VALUE" >&2 (( PERI_NUM+=MAX_PERI )) unset IFS; read -r -a VAL_ARRAY <<< "$VALUE" for VAL in "${VAL_ARRAY[@]}" do (( PERI_NUM-- )) check_and_unset "$VAL" done unset "KV_CACHE[$KV_I]" # "Take" it fi } while read -r CHAR do # Get all indexes for a plant read -r -a CHAR_ARRAY <<< "$( for (( i=0; i&2 declare -A KV_CACHE IFS=':'; while read -r VAR1 VAR2 do KV_CACHE[$VAR1]=$VAR2 done <<< "$( # Find all adjacent tiles for (( i=0; i<${#CHAR_ARRAY[@]}; i++ )) do NUM_ADJ=0 printf "%s:" "${CHAR_ARRAY[i]}" for (( j=i+1; j&2 done )" # Iterate through for CHAR in "${CHAR_ARRAY[@]}" do MAX_PERI=3 PERI_NUM=1 # Special head case AREA=0 check_and_unset "$CHAR" printf "max: %s peri: %s area: %s\n" "$MAX_PERI" "$PERI_NUM" "$AREA" >&2 printf "%s\n" "$(( PERI_NUM * AREA ))" done # Get all plants done <<< "$( < "$FILE" grep -o '[A-Z]' | sort -u | grep -o '[A-Z]*' )" | paste -s -d "+" | bc