AoC - Day 13

:date: 2023-12-13 12:00

Part One

I'm getting weary of this whole thing. But today, for some very stupid reason I thought, I bet this would be ok to solve with a shell script. It was quite ghastly to do so, but I did. Basically I iterated through some head ... | tr -d ... | wc -c which let me know how many "#" characters were on the first N lines. Then I checked N+1 down using tail. If they matched, then this was a strong candidate. I then iterated through plucking the right line numbers out that should match and paste <(line1) <(line2) | uniq | wc -l If there was 1 they were a match - no regular expressions needed! If I made it to the top, then it must be valid. But this only worked for the top. So I just copypasta the whole mess and ran it roughly again with tac and that did the trick. Ok, so that's horizontal. What about vertical? Well, I couldn't be bothered so I wrote a super simple Python script to transpose the array. Then ran those through the same script as before. Done!

This is not pretty, but why bother for a throw away program?

#!/bin/bash
# Start by pulling these into separate files.
# This command line takes care of it.
#
# $ F="i13/00" C=00; while read L ; do F=i13/i$(printf "%02d" $C) ; if [[ -z "$L" ]] ; then C=$((C+1));else echo $L>>$F ; fi; done < input13
#
# Then to run all:
#
# for F in i13/i??; do echo $F; ./script13a.sh $F; done | less
I=$1
function count_up_to_row_n { head -n $1 | tr -d '.\n' | wc -c ; }

function count_n_past_row_n { tail -n +$(( $1+1 )) | head -n $1 | tr -d '.\n' | wc -c ; }

N=$(wc -l < $I)
H=$(( ((N + 1) / 2) - 1 ))
for R in $(seq 1 $H); do
    TOP=$(count_up_to_row_n $R < $I)
    BOT=$(count_n_past_row_n $R < $I)
    if test $TOP -eq $BOT; then
        # Verify
        CLb=$R
        CLf=$((R + 1))
        while [[ $CLb -gt 0 ]]; do
            if paste -d '\n' <(sed -n "${CLb}p" $I) <(sed -n "${CLf}p" $I) | uniq | wc -l | grep -v 1 >/dev/null; then
               # echo " No... FAIL."
                break
            else
                CLb=$(( CLb - 1 ))
                CLf=$(( CLf + 1 ))
            fi
        done
        if [[ $CLb -eq 0 ]]; then
            # echo "VERIFIED!!!! (from top) $R"
            echo $I $R && exit
        fi
    fi
    TOP=$(tac $I | count_up_to_row_n $R )
    BOT=$(tac $I | count_n_past_row_n $R )
    if test $TOP -eq $BOT ; then
        Rend=$(( N - R ))
        # Verify
        CLb=$R
        CLf=$((R + 1))
        while [[ $CLb -gt 0 ]]; do
            #echo "checking tac lines - back:$CLb forward:$CLf"
            #tac $I|sed -n "${CLb}p"
            #tac $I|sed -n "${CLf}p"
            if paste -d '\n' <(tac $I|sed -n "${CLb}p") <(tac $I|sed -n "${CLf}p") | uniq | wc -l | grep -v 1 >/dev/null; then
               # echo "No... FAIL."
                break
            else
                CLb=$(( CLb - 1 ))
                CLf=$(( CLf + 1 ))
            fi
        done
        if [[ $CLb -eq 0 ]]; then
           # echo "VERIFIED!!!! (from bottom) $Rend"
            echo $I $Rend
            exit
        fi
    fi
done
echo $I

Part Two

As with every other day, Part Two requires a complete reassessment of everything so, no, I'm not going to do this twice.