Files
advent-of-code/2024/day-11/solution-2-2.sh

110 lines
2.1 KiB
Bash
Raw Normal View History

#!/usr/bin/env bash
FILE=input
ITERATIONS=75
# Get max num size by squaring the largest number
MAX_NUM_SIZE=0
while read -r NUM
do
if [[ ${#NUM} -gt $MAX_NUM_SIZE ]]
then
MAX_NUM_SIZE=${#NUM}
fi
done <<< "$( < input tr " " "\n" )"
(( MAX_NUM_SIZE*=2 ))
# Just pre-compute a large number of digits
{
# Rule 1
printf "0 1 \n"
# Rule 2 : If even number of digits, split half half
for (( i=10 ; i<100; i+=1 ))
do
DIGIT_COUNT=${#i}
HALF=$(( DIGIT_COUNT / 2 ))
printf "%s %s %s \n" "$i" "$(( 10#${i:0:$HALF} ))" "$(( 10#${i:$HALF} ))"
done
for (( i=1000 ; i<10000; i+=1 ))
do
DIGIT_COUNT=${#i}
HALF=$(( DIGIT_COUNT / 2 ))
printf "%s %s %s \n" "$i" "$(( 10#${i:0:$HALF} ))" "$(( 10#${i:$HALF} ))"
done
for (( i=100000 ; i<1000000; i+=1 ))
do
DIGIT_COUNT=${#i}
HALF=$(( DIGIT_COUNT / 2 ))
printf "%s %s %s \n" "$i" "$(( 10#${i:0:$HALF} ))" "$(( 10#${i:$HALF} ))"
done
# Rule 3
for (( i=1; i<10; i+=1 ))
do
printf "%s %s \n" "$i" "$(( i * 2024 ))"
done
for (( i=100; i<1000; i+=1 ))
do
printf "%s %s \n" "$i" "$(( i * 2024 ))"
done
for (( i=10000; i<100000; i+=1 ))
do
printf "%s %s \n" "$i" "$(( i * 2024 ))"
done
} | sort -n > kv-cache
printf "Cache built. KV size: %s \n" "$( wc -l kv-cache )"
# Load cache file
declare -A KV_CACHE
while read -r LINE
do
KV_CACHE[${LINE%% *}]="${LINE#* }"
done < kv-cache
NUM=0
get_num () {
NUM=$1
# Rule 1 : Convert 0 to 1
if [[ $NUM -eq 0 ]]
then
printf "1 \n"
return
fi
# Rule 2 : If even number of digits, split half half
DIGIT_COUNT=${#NUM}
if [[ $(( DIGIT_COUNT % 2 )) -eq 0 ]]
then
HALF=$(( DIGIT_COUNT / 2 ))
printf "%s %s " "$(( 10#${NUM:0:$HALF} ))" "$(( 10#${NUM:$HALF} ))"
return
fi
# Rule 3 : Multiply by 2024
printf "%s \n" "$(( NUM * 2024 ))"
return
}
# Start the loop
tr " " "\n" < "$FILE" > temp-input
for (( i=0; i<75; i++ ))
do
printf "%s Position %s\n" "$( date )" "$i"
while read -r NUM
do
if [[ -v ${KV_CACHE[$NUM]} ]]
then
printf "%s \n" "${KV_CACHE[$NUM]}"
else
get_num "$NUM"
fi
done < temp-input |
tr " " "\n" |
grep -Eo '[0-9]*' |
sponge temp-input
done
printf "Final count: %s\n" "$(wc -l < temp-input)"