From 0134815002988d8db4a8e87c5673db57a33abb9a Mon Sep 17 00:00:00 2001 From: Clement Date: Fri, 20 Dec 2024 01:01:41 +0800 Subject: [PATCH] Working part 2 --- 2024/day-17/solution-2.sh | 40 ++++++++++------- 2024/day-19/solution-2.sh | 92 +++++++++++++++++---------------------- 2 files changed, 63 insertions(+), 69 deletions(-) diff --git a/2024/day-17/solution-2.sh b/2024/day-17/solution-2.sh index 931ac91..60a5c9b 100644 --- a/2024/day-17/solution-2.sh +++ b/2024/day-17/solution-2.sh @@ -4,8 +4,8 @@ FILE=$1 ITER=1 MACHINE_ITER=999 DEBUG=false -INCREMENT=1 -TAIL_NUM=16 +INCREMENT=100000000000 +TAIL_NUM=3 # Load registry values REG_A=$(grep 'Register A:' "$FILE" | cut -f2 -d: ) @@ -13,8 +13,8 @@ REG_B=$(grep 'Register B:' "$FILE" | cut -f2 -d: ) REG_C=$(grep 'Register C:' "$FILE" | cut -f2 -d: ) # Rewrite registry A starting value -#REG_A=100000000000000 -REG_A=164541160582800 +REG_A=100000000000000 +#REG_A=164541160582800 # Load input string read -r -a INPUT <<< "$(grep 'Program:' "$FILE" | cut -f2 -d: | tr ',' ' ' )" @@ -28,17 +28,25 @@ printf "Registers A: %s B: %s C: %s\n" "$REG_A" "$REG_B" "$REG_C" >&2 . machine.sh # Iterate registry A until last nth digits are matched -while ! check_tail "$TAIL_NUM" +PIN_DIGITS=0 +while ! check_tail "$INPUT_LEN" "$PIN_DIGITS" do - read -r -a OUTPUT <<< "$( execute_machine )" - printf "Register A: %s\n" "$REG_A" - printf "Output:\t" - printf "%s " "${OUTPUT[@]}" - printf "\n" - printf "Input:\t" - printf "%s " "${INPUT[@]}" - printf "\n" - (( REG_A+=INCREMENT)) - #(( ITER-- )) - if [[ $ITER -eq 0 ]] ; then break ; fi + while ! check_tail "$TAIL_NUM" "$PIN_DIGITS" + do + read -r -a OUTPUT <<< "$( execute_machine )" + printf "Register A: %s\n" "$REG_A" + printf "Output:\t" + printf "%s " "${OUTPUT[@]}" + printf "\n" + printf "Input:\t" + printf "%s " "${INPUT[@]}" + printf "\n" + (( REG_A+=INCREMENT)) + #(( ITER-- )) + if [[ $ITER -eq 0 ]] ; then break ; fi + done + PIN_DIGITS=$TAIL_NUM + printf "Matched digit. Reducing count" + (( TAIL_NUM+=1 )) + (( INCREMENT/= 50 )) done diff --git a/2024/day-19/solution-2.sh b/2024/day-19/solution-2.sh index a652a6f..6a81da3 100644 --- a/2024/day-19/solution-2.sh +++ b/2024/day-19/solution-2.sh @@ -2,14 +2,10 @@ TOWEL_FILE=$1 DESIGN_FILE=$2 -TOWEL_ITER=10 read -r -a TOWELS <<< "$( < "$TOWEL_FILE" tr ',' ' ' | paste -s -d " " )" read -r -a DESIGNS <<< "$( < "$DESIGN_FILE" paste -s -d " " )" -#printf "Towel %s\n" "${TOWELS[@]}" -#printf "Design %s\n" "${DESIGNS[@]}" - # Check if towel is a viable match match_towel () { TOWEL=$1 @@ -27,64 +23,54 @@ match_towel () { } TOTAL_VALID=0 -declare -A UNMATCHED_TOWEL_LIST +# Loop through designs for DESIGN in "${DESIGNS[@]}" do + # The idea is for each design, keep a sum of combinations + # for each index position of the DESIGN string + # Since the branches "multiply", just take the sum + # at the starting index, and add it to the end + # of the "combined" index + # for each possible combination. printf "Starting design : %s\n" "$DESIGN" - declare -A MATCH_LIST - # Get all viable starting matches - for TOWEL_IDX in "${!TOWELS[@]}" - do - TOWEL=${TOWELS[$TOWEL_IDX]} - #printf "Testing towel: %s\n" "$TOWEL" + declare -A POINTER_LIST + POINTER_LIST[0]=1 + POINTER_END=$(( ${#DESIGN} )) - if match_towel "$TOWEL" "" "$DESIGN" - then - #printf "Starting match found. towel : %s\n" "$TOWEL" - # Copy towel list and remove the starting towel - read -r -a TOWEL_LIST <<< "$( printf "%s " "${TOWELS[@]}" )" - unset "TOWEL_LIST[$TOWEL_IDX]" - # Add to combinations - MATCH_LIST["$TOWEL"]=$( printf "%s " "${TOWEL_LIST[@]}" ) - unset "TOWEL_LIST" - fi - done - if [[ ${#MATCH_LIST[@]} -eq 0 ]] ; then printf "No available starting matches.\n" ; continue ; fi - # Now iterate over starting matches - LOOP_COUNT=${#TOWELS[@]} - while [[ $LOOP_COUNT -gt 0 ]] + while true do - for TOWEL_MATCH in "${!MATCH_LIST[@]}" + POINTER=${#DESIGN} + # Pick lowest pointer value + for P in "${!POINTER_LIST[@]}" do - read -r -a TOWEL_LIST <<< "${MATCH_LIST[$TOWEL_MATCH]}" - # Iterate over towels and find subsequent match - for TOWEL_IDX in "${!TOWEL_LIST[@]}" - do - TOWEL=${TOWELS[$TOWEL_IDX]} - if match_towel "$TOWEL" "$TOWEL_MATCH" "$DESIGN" - then - #printf "Match found for %s towel : %s\n" "${TOWEL_MATCH}" "$TOWEL" - unset "TOWEL_LIST[$TOWEL_IDX]" - # Add to combinations - MATCH_LIST["$TOWEL_MATCH$TOWEL"]=$( printf "%s " "${TOWEL_LIST[@]}" ) - unset "MATCH_LIST[$TOWEL_MATCH]" - fi - done + if [[ $P -lt $POINTER ]] + then + POINTER=$P + fi done - (( LOOP_COUNT-- )) - done - - # Calculate proper matches - for MATCH in "${!MATCH_LIST[@]}" - do - if [[ $MATCH == "$DESIGN" ]] + POINTER_VALUE=${POINTER_LIST[$POINTER]} + # Check if end has reached + if [[ $POINTER -eq $POINTER_END ]] then - printf "Match found for design %s\n" "$DESIGN" - (( TOTAL_VALID++ )) + break fi - done - # Remove matches - unset MATCH_LIST + # Loop through towels and remove earliest pointer + for TOWEL in "${TOWELS[@]}" + do + TOWEL_LEN=${#TOWEL} + END=$(( POINTER + TOWEL_LEN )) + if [[ ${DESIGN:$POINTER:$TOWEL_LEN} == "$TOWEL" ]] + then + POINTER_LIST[$END]=$(( ${POINTER_LIST[$END]} + POINTER_VALUE )) + fi + done + + # Done looping through for specific point + unset "POINTER_LIST[$POINTER]" + done + printf "Total matches for %s is %s.\n" "$DESIGN" "${POINTER_LIST[$POINTER_END]}" + TOTAL_VALID=$(( TOTAL_VALID + POINTER_LIST[$POINTER_END] )) + unset "POINTER_LIST" done printf "Total valid designs: %s\n" "$TOTAL_VALID"