From b37a204b4f6db8154543b04849e7e7e19ac87ecc Mon Sep 17 00:00:00 2001 From: Einar Jon Gunnarsson Date: Sat, 4 Dec 2021 21:06:18 +0100 Subject: [PATCH 01/10] 2021: I can't stop I need help --- .gitignore | 2 +- 2021/01.sh | 7 +++++++ 2021/02.sh | 19 +++++++++++++++++++ 2021/03.sh | 29 +++++++++++++++++++++++++++++ 2021/04.sh | 43 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 99 insertions(+), 1 deletion(-) create mode 100755 2021/01.sh create mode 100755 2021/02.sh create mode 100755 2021/03.sh create mode 100755 2021/04.sh diff --git a/.gitignore b/.gitignore index 2dd43d8..54a115b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ ./*.txt* 201[6-9]/ -202[1-9]/ +202[2-9]/ diff --git a/2021/01.sh b/2021/01.sh new file mode 100755 index 0000000..37cb768 --- /dev/null +++ b/2021/01.sh @@ -0,0 +1,7 @@ +#! /usr/bin/env bash +A=($(< "${1:-1.txt}")); a=${A[0]}; ANS=0 +for b in "${A[@]:1}"; do ((b>a && ++ANS)); a=$b; done +echo "1A: ${ANS}" +a=$((A[0]+A[1]+A[2])); b=$a; idx=(${!A[@]}); ANS2=0 +for i in "${idx[@]:3}"; do ((b+=A[i]-A[i-3], b>a && ++ANS2)); a=$b; done +echo "1B: ${ANS2}" diff --git a/2021/02.sh b/2021/02.sh new file mode 100755 index 0000000..d9ed869 --- /dev/null +++ b/2021/02.sh @@ -0,0 +1,19 @@ +#! /usr/bin/env bash +declare -i X=0 Y=0 y=0 +while read -r dir n; do + case $dir in + up) Y+=-$n;; + down) Y+=$n;; + forward) X+=$n; y+=$((Y*n));; + esac +done < "${1:-2.txt}" +echo "12A: $X*$Y = $((X*Y))" +echo "12B: $X*$y = $((X*y))" +# golfed with awk +#awk 'n=$2 /u/{Y-=n}/n/{Y+=n}/f/{X+=n;y+=n*Y}END{print X*Y,X*y}' ${1:-2.txt} +#paste -d"*" <(paste -sd+ <(rg ^f input.txt | rev | cut -c 1) | bc) <(paste -sd+ <(rg '^[du]' input.txt | sed 's/down/1\*/;s/up/-1\*/g' | bc) | bc) | bc + +#paste -d"*" <(paste -sd+ <(paste -d* <(cut -c 1 input.txt) <(rev input.txt | cut -c -1) <(sed 's/down/1\*/;s/up/-1\*/;s/forward/0\*/g' input.txt | bc | awk '{total += $0; $0 = total}1') | rg f | tr f 1 | bc ) | bc) <(paste -sd+ <(rg ^f input.txt | rev | cut -c 1) | bc) | bc +# /u/obluff +paste -d"*" <(paste -sd+ <(sed -n 's/f.* //p' input.txt )|bc) <(paste -sd+ <(sed 's/down //;s/up /-/g;/f/d' input.txt)|bc) | bc +paste -d"*" <(paste -sd+ <(paste -d* <(cut -c1 input.txt) <(tr -dc '0-9\n' < input.txt) <(x=0 && sed 's/down //;s/up/-/;s/f.*/0/' input.txt | while read a;do echo $((x+=a));done) | sed -n s/f.//p | bc) | bc) <(paste -sd+ <(sed -n 's/f.* //p' input.txt) | bc) | bc diff --git a/2021/03.sh b/2021/03.sh new file mode 100755 index 0000000..883b557 --- /dev/null +++ b/2021/03.sh @@ -0,0 +1,29 @@ +#! /usr/bin/env bash +nextchar() { + local -n most=$1 least=$2 in=$3 + local all=$(printf "%s\n" "${in[@]}" | cut -c"$4" | tr -d '\n' ) + local ones=${all//0} zeros=${all//1} + if (( ${#ones} >= ${#zeros} )); then + most+=1; least+=0 + else most+=0; least+=1; fi +} +A=($(< "${1:-3.txt}")) +idx=(${!A[@]}) len=${#A[0]} g="" e="" +time for i in "${idx[@]:1:len}"; do + nextchar g e A $i +done +echo "3A: $g*$e = $(($((2#$g))*$((2#$e))))" +time { +O=(${A[@]}) C=(${A[@]}) c=${e:0:1} o=${g:0:1} +for i in "${idx[@]:2:len}"; do + O=($(printf "%s\n" "${O[@]}" | grep "^$o")) + (( ${#O[@]} <= 1 )) && break + nextchar o _ O $i +done +for i in "${idx[@]:2:len}"; do + C=($(printf "%s\n" "${C[@]}" | grep "^$c")) + (( ${#C[@]} <= 1 )) && break + nextchar _ c C $i +done +} +echo "3B: $O*$C = $(($((2#$O))*$((2#$C))))" diff --git a/2021/04.sh b/2021/04.sh new file mode 100755 index 0000000..1e9222e --- /dev/null +++ b/2021/04.sh @@ -0,0 +1,43 @@ +#! /usr/bin/env bash +declare -i i +while read -r a b c d e; do + if (( ${#NUMBERS[@]} == 0 )); then NUMBERS=(${a//,/ }); + elif [[ -n $a ]]; then + C[i++]="-$a--$b--$c--$d--$e-" # rows + j=$((10*(i/10))) # columns + C[j+5]+="-$a-";C[j+6]+="-$b-";C[j+7]+="-$c-";C[j+8]+="-$d-";C[j+9]+="-$e-"; + ((i%5==0)) && i+=5 + fi +done < "${1:-4.txt}" +idx=(${!C[@]}) +for k in "${!NUMBERS[@]}"; do + n=${NUMBERS[k]} + C=("${C[@]//-$n-}") + B=(${C[@]}) # lazy "find empty" + (( ${#B[@]} != ${#C[@]} )) && break +done +for i in "${idx[@]}"; do [[ -z ${C[i]} ]] && break; done +j=$((10*(i/10))) # columns +printf -v sum "%s" "${C[@]:j:5}" +sum=${sum//--/+}; sum=${sum//-} +echo "12A: $n*$sum = $((n*(sum)))" +printf -v WON "=%d=" {0..990..10} +WON=${WON/=$j=} # only do each card once +for i in "${idx[@]:j:10}"; do C[i]=DONE; done +for k in "${!NUMBERS[@]}"; do + n=${NUMBERS[k]} + C=("${C[@]//-$n-}") + B=(${C[@]}) + if (( ${#B[@]} != ${#C[@]} )); then + for i in "${idx[@]}"; do + if [[ -z ${C[i]} ]]; then + j=$((10*(i/10))) + WON=${WON/=$j=}; [[ -z $WON ]] && break 2 + for l in "${idx[@]:j:10}"; do C[l]=DONE; done + fi + done + fi +done +printf -v sum "%s" "${C[@]:j:5}" +sum=${sum//--/+}; sum=${sum//-} +echo "12B: $n*$sum = $((n*(sum)))" From 72e9ca2ac79fafce98677c2951f96bff473aa99c Mon Sep 17 00:00:00 2001 From: Einar Jon Gunnarsson Date: Tue, 7 Dec 2021 20:44:06 +0100 Subject: [PATCH 02/10] 2021: Days 5-7 and README.md --- 2021/05.sh | 25 +++++++++++++++++++++++++ 2021/06.sh | 16 ++++++++++++++++ 2021/07.sh | 20 ++++++++++++++++++++ 2021/README.md | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+) create mode 100755 2021/05.sh create mode 100755 2021/06.sh create mode 100755 2021/07.sh create mode 100644 2021/README.md diff --git a/2021/05.sh b/2021/05.sh new file mode 100755 index 0000000..edf493d --- /dev/null +++ b/2021/05.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +input=${1:-5.txt} +swap(){ + local -n _x=$1 _y=$2 + local tmp=$_x; _x=$_y; _y=$tmp +} +IFS=$' ,\n'; ANS=0; ANS2=0; declare -Ai C=() D=() +while read -r x y _ X Y; do + if (( x == X )); then + (( y > Y )) && swap y Y + while ((y<=Y)); do C[$x.$y]+=1; ((y++));done + elif (( y == Y )); then + (( x > X )) && swap x X + while ((x<=X)); do C[$x.$y]+=1; ((x++));done + elif (( (X-x) == (Y-y) || (X-x) == -(Y-y) )); then + (( x > X )) && swap x X && swap y Y + if (( y > Y )); then i=-1; else i=1; fi + while ((x<=X)); do D[$x.$y]+=1; ((x++,y+=i));done + fi +done < "$input" +ANS=(${C[@]//1}) # Lazy count. Fails if there are 11 crossings +echo "5A: ${#ANS[@]}" +for i in "${!C[@]}"; do D[$i]+=${C[$i]}; done +ANS2=(${D[@]//1}) +echo "5B: ${#ANS2[@]}" diff --git a/2021/06.sh b/2021/06.sh new file mode 100755 index 0000000..9a845d3 --- /dev/null +++ b/2021/06.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +A=$(< "${1:-6.txt}") +A=${A//,} +solve() { + for ((; n < $1; ++n)); do + #births=${A//[^0]}; births=${births//0/8} + births=$(tr -cd 0 <<< "$A" | tr 0 8) + B=$(echo -n "$A" | tr 876543210 765432106 ) + A[i]="${B[i]}${births}" + done +} +n=0 +solve 80 +echo "6A: ${#A}" +#solve 256 +#echo "6B: ${#A}" diff --git a/2021/07.sh b/2021/07.sh new file mode 100755 index 0000000..610358b --- /dev/null +++ b/2021/07.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +A=($(tr , '\n' < "${1:-7.txt}" | sort -n )) +MIN=(99999999 0) MIN2=(9999999999999 0) +N=${#A[@]} +for ((i=A[N/4]; isum)) && MIN=($sum $i) +done +echo "7A: ${MIN[0]}" + +for ((i=A[N/4]; isum2)) && MIN2=($sum2 $i) +done +echo "7B: ${MIN2[0]}" diff --git a/2021/README.md b/2021/README.md new file mode 100644 index 0000000..f923854 --- /dev/null +++ b/2021/README.md @@ -0,0 +1,37 @@ +# adventofcode.sh +Advent of Code 2021, done in bash. Because I can't stop +https://adventofcode.com/2021/ + +Input can be given on the command line. +Defaults to *number*.txt in the same folder (no leading 0). +Added my input files in input/ folder. +Setting env variable PUREBASH to any value (or giving a second argument) will use slow bash instead of using faster awk when needed. + +Description of what I'm doing. Contains spoilers.... + +### 01.sh + 1. Dumb looping through all variables. + 2. Use a sliding window. 2/3 of the values in the windows are the same, but this is fine. + +### 02.sh + Simple switch to handle all cases. Both parts handled at once. + +### 03.sh + 1. Slightly tricky. Use a function to find the most/least common number in each position. + 2. Same function, but change the input for every char. + +### 04.sh + 1. Use an array to store all lines/rows of a bingo card. Delete numbers from all lines until a line is empty. + 2. Remove a card when a line is empty. Keep going until all cards are gone. + +### 05.sh + 1. Mark all points on the grid in a hash table. Return a count of points that are != 1. + 2. Mark diagonals on a second hash table. Add the first hash table to it and return a count of points that are != 1. + +### 06.sh + 1. String manipulation. Bad O(), but finishes part 1 in half a second. + 2. Too slow... + +### 07.sh + 1. Brute force search. + 2. More brute force. From b25ff15879b6eb2d174555cd2a43c5888cf968a5 Mon Sep 17 00:00:00 2001 From: Einar Jon Gunnarsson Date: Tue, 7 Dec 2021 20:49:36 +0100 Subject: [PATCH 03/10] 2021: Improvements on days 6 and 7 --- 2021/06.sh | 20 +++++++++----------- 2021/07.sh | 29 ++++++++++++----------------- 2 files changed, 21 insertions(+), 28 deletions(-) diff --git a/2021/06.sh b/2021/06.sh index 9a845d3..3d1047b 100755 --- a/2021/06.sh +++ b/2021/06.sh @@ -1,16 +1,14 @@ #!/usr/bin/env bash -A=$(< "${1:-6.txt}") -A=${A//,} +declare -i A=(0 0 0 0 0 0 0 0 0) n=0 +while read freq age; do A[age]=$freq; done < <(grep -o [0-9] "${1:-6.txt}" | sort | uniq -c) solve() { - for ((; n < $1; ++n)); do - #births=${A//[^0]}; births=${births//0/8} - births=$(tr -cd 0 <<< "$A" | tr 0 8) - B=$(echo -n "$A" | tr 876543210 765432106 ) - A[i]="${B[i]}${births}" + while ((n < $1)); do + i=$((n++%9)) + A[i-2]+=${A[i]} done + sum=0; for i in "${!A[@]}"; do ((sum+=A[i])); done } -n=0 solve 80 -echo "6A: ${#A}" -#solve 256 -#echo "6B: ${#A}" +echo "6A: $sum" +solve 256 +echo "6B: $sum" diff --git a/2021/07.sh b/2021/07.sh index 610358b..797e178 100755 --- a/2021/07.sh +++ b/2021/07.sh @@ -1,20 +1,15 @@ -#!/usr/bin/env bash -A=($(tr , '\n' < "${1:-7.txt}" | sort -n )) +#!/bin/bash +input=$(< ${1:-7.txt}) +A=($(echo -e "${input//,/\\n}" | sort -n)) MIN=(99999999 0) MIN2=(9999999999999 0) N=${#A[@]} -for ((i=A[N/4]; isum)) && MIN=($sum $i) +avg=$(((${input//,/+})/N)) +n=""; for k in ${A[@]};do n+=+$((k-A[N/2])); done +sum=$((${n//-})) # lazy abs() +echo "7A: $sum" +declare -i sum2=0 +for k in ${A[@]}; do + dist=$((k-avg)); dist=${dist/-} + sum2+=$((dist*(dist+1)/2)) done -echo "7A: ${MIN[0]}" - -for ((i=A[N/4]; isum2)) && MIN2=($sum2 $i) -done -echo "7B: ${MIN2[0]}" +echo "7B: $sum2" From e33aaaddbc4d0bba7b3dd000f55db5064e18d784 Mon Sep 17 00:00:00 2001 From: Einar Jon Gunnarsson Date: Wed, 8 Dec 2021 16:03:00 +0100 Subject: [PATCH 04/10] 2021: Day 8. Update README.md --- 2021/08.sh | 42 ++++++++++++++++++++++++++++++++++++++++++ 2021/README.md | 11 +++++++---- 2 files changed, 49 insertions(+), 4 deletions(-) create mode 100755 2021/08.sh diff --git a/2021/08.sh b/2021/08.sh new file mode 100755 index 0000000..e578042 --- /dev/null +++ b/2021/08.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +input=${1:-8.txt} +printf "8A: " +cut -d\| -f 2 "$input" | grep -Eo "[a-g]+" | grep -cE "^([a-g]{2,4}|[a-g]{7})$" +sum="" +while read -r -a A; do + T=() P235=() P690=() n="" + for i in "${A[@]:0:10}"; do + case ${#i} in + 2) T[1]=$i;; + 3) T[7]=$i;; + 4) T[4]=$i;; + 5) P235+=($i);; + 6) P690+=($i);; + 7) T[8]=$i;; + esac + done + for i in "${P235[@]}"; do + if [[ ${i//[${T[4]}]} == ??? ]]; then T[2]=$i + elif [[ ${i//[${T[7]}]} == ?? ]]; then T[3]=$i + else T[5]=$i + fi + done + for i in "${P690[@]}"; do + if [[ ${i//[${T[7]}]} == ???? ]]; then T[6]=$i + elif [[ ${i//[${T[4]}]} == ?? ]]; then T[9]=$i + else T[0]=$i + fi + done + for i in "${A[@]:11}"; do + case ${#i} in + 2) n+=1;; + 3) n+=7;; + 4) n+=4;; + 5) for k in 2 3 5 ?; do [[ -z ${i//[${T[k]}]} ]] && break; done; n+=$k;; + 6) for k in 6 9 0 ?; do [[ -z ${i//[${T[k]}]} ]] && break; done; n+=$k;; + 7) n+=8;; + esac + done + sum+=+$((10#$n)) # leading 0 means octal. A '?' will throw an error here +done < "${input}" +echo "8B: $((sum))" diff --git a/2021/README.md b/2021/README.md index f923854..1e08e53 100644 --- a/2021/README.md +++ b/2021/README.md @@ -29,9 +29,12 @@ Description of what I'm doing. Contains spoilers.... 2. Mark diagonals on a second hash table. Add the first hash table to it and return a count of points that are != 1. ### 06.sh - 1. String manipulation. Bad O(), but finishes part 1 in half a second. - 2. Too slow... + Store a count of the fishes each day in a circular buffer, with the current 0-day at n%9. Bash arrays are circular by default. ### 07.sh - 1. Brute force search. - 2. More brute force. + 1. Use the median. + 2. Use the mean. + +### 07.sh + 1. Simple grep to fish out the output digits and isolate the ones with 2-4 or 7 digits. + 2. A damn bother, since the letters were scrambled. Assigned the numbers based on length. The 5-6 length ones got special handling, by checking the length after removing the letters that make up 4 and 7. That was enough to identify every one. From 31a5721d4de69ea150a8c71bb41c79f175572b3a Mon Sep 17 00:00:00 2001 From: Einar Jon Gunnarsson Date: Wed, 8 Dec 2021 16:34:40 +0100 Subject: [PATCH 05/10] 2021: Shellcheck fixes and minor cleanup --- 2021/02.sh | 11 ++++++----- 2021/03.sh | 13 ++++++------- 2021/04.sh | 5 +++-- 2021/06.sh | 2 +- 2021/07.sh | 7 +++---- 2021/README.md | 2 +- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/2021/02.sh b/2021/02.sh index d9ed869..3ccc8f5 100755 --- a/2021/02.sh +++ b/2021/02.sh @@ -1,4 +1,5 @@ #! /usr/bin/env bash +input=${1:-2.txt} declare -i X=0 Y=0 y=0 while read -r dir n; do case $dir in @@ -6,14 +7,14 @@ while read -r dir n; do down) Y+=$n;; forward) X+=$n; y+=$((Y*n));; esac -done < "${1:-2.txt}" +done < "${input}" echo "12A: $X*$Y = $((X*Y))" echo "12B: $X*$y = $((X*y))" # golfed with awk #awk 'n=$2 /u/{Y-=n}/n/{Y+=n}/f/{X+=n;y+=n*Y}END{print X*Y,X*y}' ${1:-2.txt} -#paste -d"*" <(paste -sd+ <(rg ^f input.txt | rev | cut -c 1) | bc) <(paste -sd+ <(rg '^[du]' input.txt | sed 's/down/1\*/;s/up/-1\*/g' | bc) | bc) | bc +#paste -d"*" <(paste -sd+ <(rg ^f "${input}" | rev | cut -c 1) | bc) <(paste -sd+ <(rg '^[du]' "${input}" | sed 's/down/1\*/;s/up/-1\*/g' | bc) | bc) | bc -#paste -d"*" <(paste -sd+ <(paste -d* <(cut -c 1 input.txt) <(rev input.txt | cut -c -1) <(sed 's/down/1\*/;s/up/-1\*/;s/forward/0\*/g' input.txt | bc | awk '{total += $0; $0 = total}1') | rg f | tr f 1 | bc ) | bc) <(paste -sd+ <(rg ^f input.txt | rev | cut -c 1) | bc) | bc +#paste -d"*" <(paste -sd+ <(paste -d* <(cut -c 1 "${input}") <(rev "${input}" | cut -c -1) <(sed 's/down/1\*/;s/up/-1\*/;s/forward/0\*/g' "${input}" | bc | awk '{total += $0; $0 = total}1') | rg f | tr f 1 | bc ) | bc) <(paste -sd+ <(rg ^f "${input}" | rev | cut -c 1) | bc) | bc # /u/obluff -paste -d"*" <(paste -sd+ <(sed -n 's/f.* //p' input.txt )|bc) <(paste -sd+ <(sed 's/down //;s/up /-/g;/f/d' input.txt)|bc) | bc -paste -d"*" <(paste -sd+ <(paste -d* <(cut -c1 input.txt) <(tr -dc '0-9\n' < input.txt) <(x=0 && sed 's/down //;s/up/-/;s/f.*/0/' input.txt | while read a;do echo $((x+=a));done) | sed -n s/f.//p | bc) | bc) <(paste -sd+ <(sed -n 's/f.* //p' input.txt) | bc) | bc +paste -d"*" <(paste -sd+ <(sed -n 's/f.* //p' "${input}" )|bc) <(paste -sd+ <(sed 's/down //;s/up /-/g;/f/d' "${input}")|bc) | bc +paste -d"*" <(paste -sd+ <(paste -d* <(cut -c1 "${input}") <(tr -dc '0-9\n' < "${input}") <(x=0 && sed 's/down //;s/up/-/;s/f.*/0/' "${input}" | while read -r a;do echo $((x+=a));done) | sed -n s/f.//p | bc) | bc) <(paste -sd+ <(sed -n 's/f.* //p' "${input}") | bc) | bc diff --git a/2021/03.sh b/2021/03.sh index 883b557..65604ce 100755 --- a/2021/03.sh +++ b/2021/03.sh @@ -1,7 +1,7 @@ #! /usr/bin/env bash nextchar() { local -n most=$1 least=$2 in=$3 - local all=$(printf "%s\n" "${in[@]}" | cut -c"$4" | tr -d '\n' ) + local all; all=$(printf "%s\n" "${in[@]}" | cut -c"$4" | tr -d '\n' ) local ones=${all//0} zeros=${all//1} if (( ${#ones} >= ${#zeros} )); then most+=1; least+=0 @@ -9,21 +9,20 @@ nextchar() { } A=($(< "${1:-3.txt}")) idx=(${!A[@]}) len=${#A[0]} g="" e="" -time for i in "${idx[@]:1:len}"; do - nextchar g e A $i +for i in "${idx[@]:1:$len}"; do + nextchar g e A "$i" done echo "3A: $g*$e = $(($((2#$g))*$((2#$e))))" -time { O=(${A[@]}) C=(${A[@]}) c=${e:0:1} o=${g:0:1} for i in "${idx[@]:2:len}"; do O=($(printf "%s\n" "${O[@]}" | grep "^$o")) (( ${#O[@]} <= 1 )) && break - nextchar o _ O $i + nextchar o _ O "$i" done for i in "${idx[@]:2:len}"; do C=($(printf "%s\n" "${C[@]}" | grep "^$c")) (( ${#C[@]} <= 1 )) && break - nextchar _ c C $i + nextchar _ c C "$i" done -} +# shellcheck disable=SC2128 echo "3B: $O*$C = $(($((2#$O))*$((2#$C))))" diff --git a/2021/04.sh b/2021/04.sh index 1e9222e..5f44540 100755 --- a/2021/04.sh +++ b/2021/04.sh @@ -20,7 +20,8 @@ for i in "${idx[@]}"; do [[ -z ${C[i]} ]] && break; done j=$((10*(i/10))) # columns printf -v sum "%s" "${C[@]:j:5}" sum=${sum//--/+}; sum=${sum//-} -echo "12A: $n*$sum = $((n*(sum)))" +echo "12A: $((n*(sum)))" + printf -v WON "=%d=" {0..990..10} WON=${WON/=$j=} # only do each card once for i in "${idx[@]:j:10}"; do C[i]=DONE; done @@ -40,4 +41,4 @@ for k in "${!NUMBERS[@]}"; do done printf -v sum "%s" "${C[@]:j:5}" sum=${sum//--/+}; sum=${sum//-} -echo "12B: $n*$sum = $((n*(sum)))" +echo "12B: $((n*(sum)))" diff --git a/2021/06.sh b/2021/06.sh index 3d1047b..afbc848 100755 --- a/2021/06.sh +++ b/2021/06.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash declare -i A=(0 0 0 0 0 0 0 0 0) n=0 -while read freq age; do A[age]=$freq; done < <(grep -o [0-9] "${1:-6.txt}" | sort | uniq -c) +while read -r freq age; do A[age]=$freq; done < <(grep -o "[0-9]" "${1:-6.txt}" | sort | uniq -c) solve() { while ((n < $1)); do i=$((n++%9)) diff --git a/2021/07.sh b/2021/07.sh index 797e178..952e9f4 100755 --- a/2021/07.sh +++ b/2021/07.sh @@ -1,14 +1,13 @@ #!/bin/bash -input=$(< ${1:-7.txt}) +input=$(< "${1:-7.txt}") A=($(echo -e "${input//,/\\n}" | sort -n)) -MIN=(99999999 0) MIN2=(9999999999999 0) N=${#A[@]} avg=$(((${input//,/+})/N)) -n=""; for k in ${A[@]};do n+=+$((k-A[N/2])); done +n=""; for k in "${A[@]}";do n+=+$((k-A[N/2])); done sum=$((${n//-})) # lazy abs() echo "7A: $sum" declare -i sum2=0 -for k in ${A[@]}; do +for k in "${A[@]}"; do dist=$((k-avg)); dist=${dist/-} sum2+=$((dist*(dist+1)/2)) done diff --git a/2021/README.md b/2021/README.md index 1e08e53..1c29df0 100644 --- a/2021/README.md +++ b/2021/README.md @@ -35,6 +35,6 @@ Description of what I'm doing. Contains spoilers.... 1. Use the median. 2. Use the mean. -### 07.sh +### 08.sh 1. Simple grep to fish out the output digits and isolate the ones with 2-4 or 7 digits. 2. A damn bother, since the letters were scrambled. Assigned the numbers based on length. The 5-6 length ones got special handling, by checking the length after removing the letters that make up 4 and 7. That was enough to identify every one. From 5f8848844ba89aa93a1bcf4cd2239cc75d87b27c Mon Sep 17 00:00:00 2001 From: Einar Jon Gunnarsson Date: Sun, 12 Dec 2021 21:34:02 +0100 Subject: [PATCH 06/10] 2021: Days 9-12 --- 2021/09.sh | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2021/10.sh | 17 +++++++++++++ 2021/11.sh | 29 +++++++++++++++++++++ 2021/12.sh | 27 ++++++++++++++++++++ 2021/README.md | 23 +++++++++++++++-- 5 files changed, 163 insertions(+), 2 deletions(-) create mode 100755 2021/09.sh create mode 100755 2021/10.sh create mode 100755 2021/11.sh create mode 100755 2021/12.sh diff --git a/2021/09.sh b/2021/09.sh new file mode 100755 index 0000000..c82023e --- /dev/null +++ b/2021/09.sh @@ -0,0 +1,69 @@ +#! /usr/bin/env bash +A=($(< "${1:-9.txt}")) +B=(9${A//?/9}9); for i in "${A[@]}"; do B+=(9${i}9); done; B+=($B); C=("${B[@]}"); +n=${#A} N=${#A[@]} +declare -A LOWS +for ((y=1; y<=N; ++y)); do + for ((x=1; x<=n; ++x)); do + while (( ${B[y]:x:1} > ${B[y]:x+1:1} )); do ((++x)); done + low=${B[y]:x:1} + if (( low < ${B[y]:x-1:1} && low < ${B[y]:x+1:1} + && low < ${B[y-1]:x:1} && low < ${B[y+1]:x:1})); then + LOWS[$y,$x]=$low + fi + done +done +printf -v sum "+%s" "${LOWS[@]}" +echo "9A: $((sum + ${#LOWS[@]}))" + +C=(${C[@]//[0-8]/-}) c=0 +F=({a..z} {A..Z} {0..8} + _ / =) +idx=($(printf "%s\n" "${!LOWS[@]}" | sort -n)) +for i in "${idx[@]}"; do + LOWS[$i]=${F[c]} + x=${i/*,} y=${i/,*} + C[y]=${C[y]:0:x}${F[c]}${C[y]:x+1} + for k in 1 -1; do + j=$k + while [[ ${C[y+j]:x:1} != 9 ]]; do + C[y+j]=${C[y+j]:0:x}${F[c]}${C[y+j]:x+1} + ((j+=k)); + done + done + (( ++c >= ${#F[@]} && ++d)) && c=0 +done +# Terrible "grow" +for i in {1..6}; do + C=($(printf "%s\n" "${C[@]}" | sed -e "s/-\([^9-]\)/\1\1/g;s/\([^9-]\)-/\1\1/g")) +done +while [[ "${C[*]}" == *-* ]]; do + #echo "round $((++round))" + for y in ${!C[@]}; do + [[ ${C[y]} != *-* ]] && continue + minus=($(sed "s/./&\n/g" <<< ${C[y]:1} | grep -n '-')) + for x in ${minus[@]//:*}; do + for j in 1 -1; do + k=$j + while [[ ${C[y+k]:x:1} == - ]]; do ((k+=j)); done + p=${C[y+k]:x:1} + if [[ $p != 9 ]]; then + while ((k+=-j)); do C[y+k]=${C[y+k]:0:x}$p${C[y+k]:x+1}; done + C[y]=${C[y]:0:x}$p${C[y]:x+1} + break + fi + done + done + done + for i in {1..2}; do + C=($(printf "%s\n" "${C[@]}" | sed -e "s/-\([^9-]\)/\1\1/g;s/\([^9-]\)-/\1\1/g")) + done +done + +AREA=() +for i in ${F[@]}; do + while read -r A;do + AREA+=(${#A}:$A) + done < <(printf "%s\n" "${C[@]}" | grep -a1 $i | tr -cd "$i-" | tr -s '-' '\n') +done +BIG=($(printf "%s\n" "${AREA[@]//:*}" | sort -nr)) +echo "9B: $((BIG[0]*BIG[1]*BIG[2]))" diff --git a/2021/10.sh b/2021/10.sh new file mode 100755 index 0000000..1b17a0c --- /dev/null +++ b/2021/10.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +A=($(tr '()[]{}<>' '1a2b3c4d' < "${1:-10.txt}")) +while [[ ${A[*]} =~ (1a|2b|3c|4d) ]]; do + A=(${A[@]//1a}); A=(${A[@]//2b}); A=(${A[@]//3c}); A=(${A[@]//4d}) +done +# shellcheck disable=SC2034 +a=3 b=57 c=1197 d=25137 TMP=(${A[@]//[1234]}) C=() +printf -v sum "+%.1s" "${TMP[@]}" # TMP only contains closing brackets. Print first char +echo "10A: $((sum))" +while read -r -a B; do + sum=0 + for i in "${B[@]}"; do sum=$((sum*5+i)); done + C+=($sum) +done < <( printf "%s\n" "${A[@]}" | grep -v -E '[a-d]' | rev | sed 's/./ &/g') +C=($(printf "%s\n" "${C[@]}" | sort -n )) +N=${#C[@]} +echo "10B: ${C[N/2]}" diff --git a/2021/11.sh b/2021/11.sh new file mode 100755 index 0000000..7b36649 --- /dev/null +++ b/2021/11.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +A=($(sed -e 's/^/X/;s/./& /g' "${1:-11.txt}")) +Zeros=${A[*]//*/0} flashes=0 last=0 idx=(${!A[@]}) +A+=(X X X X X X X X X X X X) +A=(${A[@]//X/-999999999}) +flash(){ + local n=$1 j cur + ((++flashes)) + for j in -12 -11 -10 -1 1 10 11 12; do + cur=$((n+j)) + ((++A[cur] >= 10 && F[cur]++ == 0 )) && flash $cur + done +} +round(){ + F=(${Zeros}) + for i in ${idx[@]}; do ((++A[i] >= 10 && F[i]++ == 0)) && flash $i ; done + A=(${A[@]//1?/0}) + #A=(${A[@]//-99??/-9999}) +} +for rounds in {1..100}; do + round +done +echo "11A: $flashes" +while ((flashes-last != 100)); do + ((last=flashes,rounds++)) + round +done +echo "11B: $rounds" diff --git a/2021/12.sh b/2021/12.sh new file mode 100755 index 0000000..4d76009 --- /dev/null +++ b/2021/12.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +declare -A Next=() +IFS=$' -\n' +while read -r a b; do + [[ $a != start ]] && Next[$b]+="$a " + [[ $b != start ]] && Next[$a]+="$b " +done < "${1:-12.txt}" +#for i in "${!Next[@]}"; do echo "$i: '${Next[$i]}'"; done + +r() { + local route=$1 cur=$2 visited=$3 k deeper=false + if [[ $cur == end ]]; then + PATHS+=("$route:$cur") + elif [[ $cur != "${cur,,}" || $route != *:${cur}:* + || ($cur == "${cur,,}" && $((visited++)) == 0) ]]; then + for k in ${Next[$cur]}; do + r "$route:$cur" "$k" $visited + done + fi +} + +PATHS=() +r "" start 1 +echo "12A: ${#PATHS[@]}" +PATHS=() +r "" start 0 +echo "12B: ${#PATHS[@]}" diff --git a/2021/README.md b/2021/README.md index 1c29df0..2eaa285 100644 --- a/2021/README.md +++ b/2021/README.md @@ -21,7 +21,7 @@ Description of what I'm doing. Contains spoilers.... 2. Same function, but change the input for every char. ### 04.sh - 1. Use an array to store all lines/rows of a bingo card. Delete numbers from all lines until a line is empty. + 1. Use an array to store all lines/rows of a bingo card. Delete numbers from all lines until a line is empty. 2. Remove a card when a line is empty. Keep going until all cards are gone. ### 05.sh @@ -29,7 +29,8 @@ Description of what I'm doing. Contains spoilers.... 2. Mark diagonals on a second hash table. Add the first hash table to it and return a count of points that are != 1. ### 06.sh - Store a count of the fishes each day in a circular buffer, with the current 0-day at n%9. Bash arrays are circular by default. + 80 rounds can be done in half a second with string shenaningans, but 256 days would take terabytes of RAM, and lots of time. + Instead store a count of the fishes each day in a circular buffer, with the current 0-day at n%9. Bash arrays are circular by default. ### 07.sh 1. Use the median. @@ -38,3 +39,21 @@ Description of what I'm doing. Contains spoilers.... ### 08.sh 1. Simple grep to fish out the output digits and isolate the ones with 2-4 or 7 digits. 2. A damn bother, since the letters were scrambled. Assigned the numbers based on length. The 5-6 length ones got special handling, by checking the length after removing the letters that make up 4 and 7. That was enough to identify every one. + +### 09.sh + 1. For each line, go forward in the string while the next char is lower. Once you reach that, add a low point if all 4 neighbours are higher. + 2. Clean out the map so that all numbers except edges and 9s are empty. Add each low point from part 1 with a different symbol. + Use terrible bash to grow the symbols until the whole map is filled. Count the size of each symbol block. + +### 10.sh + Renamed the brackets for easier grok-ing, and so that I could assign values to each one. + 1. Keep removing "innermost" bracket pairs until none remains, then remove opening brackets and sum up the values in the first column, if any. + 2. Remove any string containing a closing bracket, reverse the rest. Instead of adding a closing bracket, add the value for each opening bracket at a time. + +### 11.sh + 1. Convert the map to a 1D array, and add -9999999 to the sides so I don\'t need to think about edges. Recursve function to flash the octopi. + 2. Run until all fields flash at once. + +### 12.sh + 1. Brute force. Simplified version of the recursive functions of 2015 (9 and 13). Collect a hashmap wit the destinations for each cave. Remove "start" from the destinations to simplify coding. + 2. Add a dumb check to allow the first lowercase cave twice. Takes way too long to run. From a3a8c5d12670d514f5b1c1be783beb3f03f5144a Mon Sep 17 00:00:00 2001 From: Einar Jon Gunnarsson Date: Sun, 12 Dec 2021 21:40:15 +0100 Subject: [PATCH 07/10] 2021/08: Simplify logic No need to collect every number to the T array. Just identify 4 and 7, and use those to find the differences between 2,3,5 and 6,9,0. --- 2021/08.sh | 45 +++++++++++++++++---------------------------- 1 file changed, 17 insertions(+), 28 deletions(-) diff --git a/2021/08.sh b/2021/08.sh index e578042..31579d7 100755 --- a/2021/08.sh +++ b/2021/08.sh @@ -4,39 +4,28 @@ printf "8A: " cut -d\| -f 2 "$input" | grep -Eo "[a-g]+" | grep -cE "^([a-g]{2,4}|[a-g]{7})$" sum="" while read -r -a A; do - T=() P235=() P690=() n="" + T4="" T7="" n="" for i in "${A[@]:0:10}"; do - case ${#i} in - 2) T[1]=$i;; - 3) T[7]=$i;; - 4) T[4]=$i;; - 5) P235+=($i);; - 6) P690+=($i);; - 7) T[8]=$i;; + case ${#i} in # Just find 4 and 7, ignore the rest + 3) T7=$i; [[ -n $T4 ]] && break;; + 4) T4=$i; [[ -n $T7 ]] && break;; esac done - for i in "${P235[@]}"; do - if [[ ${i//[${T[4]}]} == ??? ]]; then T[2]=$i - elif [[ ${i//[${T[7]}]} == ?? ]]; then T[3]=$i - else T[5]=$i - fi - done - for i in "${P690[@]}"; do - if [[ ${i//[${T[7]}]} == ???? ]]; then T[6]=$i - elif [[ ${i//[${T[4]}]} == ?? ]]; then T[9]=$i - else T[0]=$i - fi - done for i in "${A[@]:11}"; do - case ${#i} in - 2) n+=1;; - 3) n+=7;; - 4) n+=4;; - 5) for k in 2 3 5 ?; do [[ -z ${i//[${T[k]}]} ]] && break; done; n+=$k;; - 6) for k in 6 9 0 ?; do [[ -z ${i//[${T[k]}]} ]] && break; done; n+=$k;; - 7) n+=8;; + case ${#i},${i//[$T4]},${i//[$T7]} in + 2,*) n+=1;; + 3,*) n+=7;; + 4,*) n+=4;; + 5,???,*) n+=2;; + 5,*,??) n+=3;; + 5,*) n+=5;; + 6,*,????) n+=6;; + 6,??,*) n+=9;; + 6,*) n+=0;; + 7,*) n+=8;; + *) echo ERROR: ${#i},${i//[$T4]},${i//[$T7]}; break 2;; esac done - sum+=+$((10#$n)) # leading 0 means octal. A '?' will throw an error here + sum+=+$((10#$n)) done < "${input}" echo "8B: $((sum))" From ec029a8c23d38676ebe83e91d0013ad27ccbfe7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Einar=20J=C3=B3n?= Date: Sun, 12 Dec 2021 22:07:11 +0100 Subject: [PATCH 08/10] 2021: Update README.md --- 2021/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/2021/README.md b/2021/README.md index 2eaa285..42ec021 100644 --- a/2021/README.md +++ b/2021/README.md @@ -51,9 +51,9 @@ Description of what I'm doing. Contains spoilers.... 2. Remove any string containing a closing bracket, reverse the rest. Instead of adding a closing bracket, add the value for each opening bracket at a time. ### 11.sh - 1. Convert the map to a 1D array, and add -9999999 to the sides so I don\'t need to think about edges. Recursve function to flash the octopi. + 1. Convert the map to a 1D array, and add -9999999 to the sides so I don\'t need to think about edges. Recursive function to flash the octopi. 2. Run until all fields flash at once. ### 12.sh - 1. Brute force. Simplified version of the recursive functions of 2015 (9 and 13). Collect a hashmap wit the destinations for each cave. Remove "start" from the destinations to simplify coding. + 1. Brute force. Simplified version of the recursive functions of 2015 (9 and 13). Collect a hashmap with the destinations for each cave. Remove "start" from the destinations to simplify coding. 2. Add a dumb check to allow the first lowercase cave twice. Takes way too long to run. From 4d1498400603bb20b9c1c01b2ad7d205dc8b4cca Mon Sep 17 00:00:00 2001 From: Einar Jon Gunnarsson Date: Tue, 14 Dec 2021 21:55:44 +0100 Subject: [PATCH 09/10] 2021: Days 13 and 14 --- 2021/13.sh | 36 ++++++++++++++++++++++++++++++++++++ 2021/14.sh | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2021/README.md | 8 ++++++++ 3 files changed, 88 insertions(+) create mode 100755 2021/13.sh create mode 100755 2021/14.sh diff --git a/2021/13.sh b/2021/13.sh new file mode 100755 index 0000000..c1c29a3 --- /dev/null +++ b/2021/13.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# Oneliner for part 1. First fold hardcoded. +#echo "13A: $(while read x y; do ((x >655)) && x=$((2*655-x)); echo $x,$y; done < <(grep , 13.txt| tr , ' ') | sort -u | wc -l)" + +fold_x() { + local n=$1 C=(${DOTS[@]}) i + for i in "${!C[@]}"; do + x=${C[i]//,*} + ((x>n)) && C[i]=$(((2*n-x))),${C[i]/*,} + done + DOTS=($(printf "%s\n" "${C[@]}"| sort -n | uniq)) +} +fold_y() { + local n=$1 C=(${DOTS[@]}) i + for i in "${!C[@]}"; do + y=${C[i]//*,} + ((y>n)) && C[i]=${C[i]/,*},$(((2*n-y))) + done + DOTS=($(printf "%s\n" "${C[@]}"| sort -n | uniq)) +} + +DOTS=($(grep , "${1:-13.txt}")) +FOLDS=($(grep -o '.=.*' "${1:-13.txt}")) +fold_"${FOLDS[0]/=*}" "${FOLDS[0]:2}" +echo "13A: ${#DOTS[@]}" +for line in "${FOLDS[@]:1}"; do + xy=${line/=*} + "fold_$xy" "${line:2}" +done +TEXT=() spaces=" " +for i in "${!DOTS[@]}"; do + x=${DOTS[i]//,*} y=${DOTS[i]//*,} len=${#TEXT[y]} + TEXT[y]+="${spaces:0:x-len}#" +done +echo "13B:" +printf "%s\n" "${TEXT[@]}" diff --git a/2021/14.sh b/2021/14.sh new file mode 100755 index 0000000..f07d8e2 --- /dev/null +++ b/2021/14.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +input=${1:-14.txt} +declare -A SET=() +declare -iA COUNT=() +POL=$(head -1 "${input}") +while read -r a _ b;do + SET[$a]="${a:0:1}$b $b${a:1}"; +done < <( grep ' -> ' "${input}") +for ((i=0; i<${#POL}-1;i++)); do + j=${POL:i:2} + COUNT[$j]+=1; +done + +solve() { + for ((; round < $1; round++)); do + local -iA NEW_COUNT=() + for j in "${!COUNT[@]}"; do + for k in ${SET[$j]}; do + NEW_COUNT[$k]+=${COUNT[$j]} + done + done + COUNT=() + for j in "${!NEW_COUNT[@]}"; do COUNT[$j]=${NEW_COUNT[$j]}; done + done +} +diff() { + local -n ans=$1 + local -Ai ALPHA=([${POL:0:1}]=1 [${POL: -1}]=1) # ends are only counted once + for k in "${!COUNT[@]}"; do + ALPHA[${k:0:1}]+=$((COUNT["$k"])) + ALPHA[${k:1}]+=$((COUNT["$k"])) + done + FREQ=($(printf "%s\n" "${ALPHA[@]}" | sort -n)) + #shellcheck disable=SC2034 + ans=$((FREQ[-1]/2-FREQ[0]/2)) +} + +round=0 +for i in 10 40;do + solve $i + diff "ANS[n++]" +done +echo "14A: ${ANS[0]}" +echo "14B: ${ANS[1]}" diff --git a/2021/README.md b/2021/README.md index 42ec021..1bc1077 100644 --- a/2021/README.md +++ b/2021/README.md @@ -57,3 +57,11 @@ Description of what I'm doing. Contains spoilers.... ### 12.sh 1. Brute force. Simplified version of the recursive functions of 2015 (9 and 13). Collect a hashmap with the destinations for each cave. Remove "start" from the destinations to simplify coding. 2. Add a dumb check to allow the first lowercase cave twice. Takes way too long to run. + +### 13.sh + 1. Functions fold_x/fold_y for easier handling. Fold and remove duplicates for first line. + 2. Repeat for rest of the lines. Collect space-delimited dots in an array of strings. Print the array. + +### 14.sh + Collect the conversions in an array. Count the number of pairs in the initial polymer. For each polymer, convert the input to 2 outputs. + For the final count, every char is part of 2 pairs except the ends, so add 1 to the ends and then divide by 2 for the final number. From 9410a802cdd8773ba04a67d2253f4839154436cc Mon Sep 17 00:00:00 2001 From: Einar Jon Gunnarsson Date: Wed, 12 Jan 2022 09:15:52 +0100 Subject: [PATCH 10/10] 2021: Shellcheck fixes and cleanup Minor cleanup in 4, 7 and 9-12 --- 2021/01.sh | 2 +- 2021/02.sh | 2 +- 2021/03.sh | 2 +- 2021/04.sh | 16 +++++++--------- 2021/07.sh | 13 ++++++------- 2021/08.sh | 2 +- 2021/09.sh | 16 ++++++++-------- 2021/10.sh | 8 +++++--- 2021/11.sh | 11 ++++++----- 2021/12.sh | 19 ++++++++++--------- 10 files changed, 46 insertions(+), 45 deletions(-) diff --git a/2021/01.sh b/2021/01.sh index 37cb768..42251a4 100755 --- a/2021/01.sh +++ b/2021/01.sh @@ -1,4 +1,4 @@ -#! /usr/bin/env bash +#!/usr/bin/env bash A=($(< "${1:-1.txt}")); a=${A[0]}; ANS=0 for b in "${A[@]:1}"; do ((b>a && ++ANS)); a=$b; done echo "1A: ${ANS}" diff --git a/2021/02.sh b/2021/02.sh index 3ccc8f5..534158c 100755 --- a/2021/02.sh +++ b/2021/02.sh @@ -1,4 +1,4 @@ -#! /usr/bin/env bash +#!/usr/bin/env bash input=${1:-2.txt} declare -i X=0 Y=0 y=0 while read -r dir n; do diff --git a/2021/03.sh b/2021/03.sh index 65604ce..3937153 100755 --- a/2021/03.sh +++ b/2021/03.sh @@ -1,4 +1,4 @@ -#! /usr/bin/env bash +#!/usr/bin/env bash nextchar() { local -n most=$1 least=$2 in=$3 local all; all=$(printf "%s\n" "${in[@]}" | cut -c"$4" | tr -d '\n' ) diff --git a/2021/04.sh b/2021/04.sh index 5f44540..0044255 100755 --- a/2021/04.sh +++ b/2021/04.sh @@ -1,12 +1,11 @@ -#! /usr/bin/env bash -declare -i i +#!/usr/bin/env bash +declare -i i j=0 while read -r a b c d e; do if (( ${#NUMBERS[@]} == 0 )); then NUMBERS=(${a//,/ }); elif [[ -n $a ]]; then C[i++]="-$a--$b--$c--$d--$e-" # rows - j=$((10*(i/10))) # columns C[j+5]+="-$a-";C[j+6]+="-$b-";C[j+7]+="-$c-";C[j+8]+="-$d-";C[j+9]+="-$e-"; - ((i%5==0)) && i+=5 + ((i%5==0)) && i+=5 j+=10 fi done < "${1:-4.txt}" idx=(${!C[@]}) @@ -17,16 +16,15 @@ for k in "${!NUMBERS[@]}"; do (( ${#B[@]} != ${#C[@]} )) && break done for i in "${idx[@]}"; do [[ -z ${C[i]} ]] && break; done -j=$((10*(i/10))) # columns +j=$((10*(i/10))) # card number printf -v sum "%s" "${C[@]:j:5}" sum=${sum//--/+}; sum=${sum//-} -echo "12A: $((n*(sum)))" +echo "12A: $((n*sum))" printf -v WON "=%d=" {0..990..10} WON=${WON/=$j=} # only do each card once for i in "${idx[@]:j:10}"; do C[i]=DONE; done -for k in "${!NUMBERS[@]}"; do - n=${NUMBERS[k]} +for n in "${NUMBERS[@]:k+1}"; do C=("${C[@]//-$n-}") B=(${C[@]}) if (( ${#B[@]} != ${#C[@]} )); then @@ -41,4 +39,4 @@ for k in "${!NUMBERS[@]}"; do done printf -v sum "%s" "${C[@]:j:5}" sum=${sum//--/+}; sum=${sum//-} -echo "12B: $((n*(sum)))" +echo "12B: $((n*sum))" diff --git a/2021/07.sh b/2021/07.sh index 952e9f4..9efd043 100755 --- a/2021/07.sh +++ b/2021/07.sh @@ -1,14 +1,13 @@ -#!/bin/bash +#!/usr/bin/env bash input=$(< "${1:-7.txt}") A=($(echo -e "${input//,/\\n}" | sort -n)) -N=${#A[@]} -avg=$(((${input//,/+})/N)) -n=""; for k in "${A[@]}";do n+=+$((k-A[N/2])); done -sum=$((${n//-})) # lazy abs() -echo "7A: $sum" -declare -i sum2=0 +N=${#A[@]} n="" +declare -i avg=$(((${input//,/+})/N)) sum2=0 for k in "${A[@]}"; do + n+=+$((k-A[N/2])); dist=$((k-avg)); dist=${dist/-} sum2+=$((dist*(dist+1)/2)) done +sum=${n//-} # lazy abs() +echo "7A: $((sum))" echo "7B: $sum2" diff --git a/2021/08.sh b/2021/08.sh index 31579d7..fd71b08 100755 --- a/2021/08.sh +++ b/2021/08.sh @@ -23,7 +23,7 @@ while read -r -a A; do 6,??,*) n+=9;; 6,*) n+=0;; 7,*) n+=8;; - *) echo ERROR: ${#i},${i//[$T4]},${i//[$T7]}; break 2;; + *) echo "ERROR: ${#i},${i//[$T4]},${i//[$T7]}"; break 2;; esac done sum+=+$((10#$n)) diff --git a/2021/09.sh b/2021/09.sh index c82023e..4b4a9a9 100755 --- a/2021/09.sh +++ b/2021/09.sh @@ -1,6 +1,6 @@ -#! /usr/bin/env bash +#!/usr/bin/env bash A=($(< "${1:-9.txt}")) -B=(9${A//?/9}9); for i in "${A[@]}"; do B+=(9${i}9); done; B+=($B); C=("${B[@]}"); +B=(9${A//?/9}9); for i in "${A[@]}"; do B+=(9${i}9); done; B+=(${B[0]}); C=("${B[@]}"); n=${#A} N=${#A[@]} declare -A LOWS for ((y=1; y<=N; ++y)); do @@ -17,7 +17,7 @@ printf -v sum "+%s" "${LOWS[@]}" echo "9A: $((sum + ${#LOWS[@]}))" C=(${C[@]//[0-8]/-}) c=0 -F=({a..z} {A..Z} {0..8} + _ / =) +F=({a..z} {A..Z} {0..8} + _ / "=") idx=($(printf "%s\n" "${!LOWS[@]}" | sort -n)) for i in "${idx[@]}"; do LOWS[$i]=${F[c]} @@ -38,10 +38,10 @@ for i in {1..6}; do done while [[ "${C[*]}" == *-* ]]; do #echo "round $((++round))" - for y in ${!C[@]}; do + for y in "${!C[@]}"; do [[ ${C[y]} != *-* ]] && continue - minus=($(sed "s/./&\n/g" <<< ${C[y]:1} | grep -n '-')) - for x in ${minus[@]//:*}; do + minus=($(sed "s/./&\n/g" <<< "${C[y]:1}" | grep -n '-')) + for x in "${minus[@]//:*}"; do for j in 1 -1; do k=$j while [[ ${C[y+k]:x:1} == - ]]; do ((k+=j)); done @@ -60,10 +60,10 @@ while [[ "${C[*]}" == *-* ]]; do done AREA=() -for i in ${F[@]}; do +for i in "${F[@]}"; do while read -r A;do AREA+=(${#A}:$A) - done < <(printf "%s\n" "${C[@]}" | grep -a1 $i | tr -cd "$i-" | tr -s '-' '\n') + done < <(printf "%s\n" "${C[@]}" | grep -a1 "$i" | tr -cd "$i-" | tr -s '-' '\n') done BIG=($(printf "%s\n" "${AREA[@]//:*}" | sort -nr)) echo "9B: $((BIG[0]*BIG[1]*BIG[2]))" diff --git a/2021/10.sh b/2021/10.sh index 1b17a0c..f7613c5 100755 --- a/2021/10.sh +++ b/2021/10.sh @@ -2,16 +2,18 @@ A=($(tr '()[]{}<>' '1a2b3c4d' < "${1:-10.txt}")) while [[ ${A[*]} =~ (1a|2b|3c|4d) ]]; do A=(${A[@]//1a}); A=(${A[@]//2b}); A=(${A[@]//3c}); A=(${A[@]//4d}) + echo $((++i)) done +# P1 only contains closing brackets. P2 only contains lines with no closing brackets # shellcheck disable=SC2034 -a=3 b=57 c=1197 d=25137 TMP=(${A[@]//[1234]}) C=() -printf -v sum "+%.1s" "${TMP[@]}" # TMP only contains closing brackets. Print first char +a=3 b=57 c=1197 d=25137 P1=(${A[@]//[1234]}) P2=(${A[@]/*[^1234]*}) C=() +printf -v sum "+%.1s" "${P1[@]}" # Only print first char echo "10A: $((sum))" while read -r -a B; do sum=0 for i in "${B[@]}"; do sum=$((sum*5+i)); done C+=($sum) -done < <( printf "%s\n" "${A[@]}" | grep -v -E '[a-d]' | rev | sed 's/./ &/g') +done < <(printf "%s\n" "${P2[@]}" | rev | sed 's/./ &/g') C=($(printf "%s\n" "${C[@]}" | sort -n )) N=${#C[@]} echo "10B: ${C[N/2]}" diff --git a/2021/11.sh b/2021/11.sh index 7b36649..34865de 100755 --- a/2021/11.sh +++ b/2021/11.sh @@ -1,22 +1,23 @@ #!/usr/bin/env bash A=($(sed -e 's/^/X/;s/./& /g' "${1:-11.txt}")) -Zeros=${A[*]//*/0} flashes=0 last=0 idx=(${!A[@]}) +flashes=0 last=0 idx=(${!A[@]}) A+=(X X X X X X X X X X X X) A=(${A[@]//X/-999999999}) flash(){ local n=$1 j cur ((++flashes)) + # hardcoded neighbours. There's an X on one side, so Y-offset is cols+1 for j in -12 -11 -10 -1 1 10 11 12; do cur=$((n+j)) - ((++A[cur] >= 10 && F[cur]++ == 0 )) && flash $cur + ((++A[cur] >= 10 && FLASHED[cur]++ == 0 )) && flash $cur done } round(){ - F=(${Zeros}) - for i in ${idx[@]}; do ((++A[i] >= 10 && F[i]++ == 0)) && flash $i ; done - A=(${A[@]//1?/0}) + FLASHED=() + for i in "${idx[@]}"; do ((++A[i] >= 10 && FLASHED[i]++ == 0)) && flash "$i"; done #A=(${A[@]//-99??/-9999}) + A=(${A[@]//1?/0}) } for rounds in {1..100}; do round diff --git a/2021/12.sh b/2021/12.sh index 4d76009..1a60946 100755 --- a/2021/12.sh +++ b/2021/12.sh @@ -1,27 +1,28 @@ #!/usr/bin/env bash -declare -A Next=() +declare -A Next=() BIG=() IFS=$' -\n' while read -r a b; do [[ $a != start ]] && Next[$b]+="$a " [[ $b != start ]] && Next[$a]+="$b " done < "${1:-12.txt}" +for i in "${!Next[@]}"; do [[ -z ${i//[A-Z]} ]] && BIG[$i]=1; done #for i in "${!Next[@]}"; do echo "$i: '${Next[$i]}'"; done r() { - local route=$1 cur=$2 visited=$3 k deeper=false + local route=$1 cur=$2 visited=$3 k if [[ $cur == end ]]; then - PATHS+=("$route:$cur") - elif [[ $cur != "${cur,,}" || $route != *:${cur}:* - || ($cur == "${cur,,}" && $((visited++)) == 0) ]]; then + PATHS+=1 + elif [[ -n ${BIG[$cur]} || $route != *:${cur}:* ]] \ + || ((visited++ == 0)); then for k in ${Next[$cur]}; do r "$route:$cur" "$k" $visited done fi } -PATHS=() +declare -i PATHS=0 r "" start 1 -echo "12A: ${#PATHS[@]}" -PATHS=() +echo "12A: ${PATHS}" +PATHS=0 r "" start 0 -echo "12B: ${#PATHS[@]}" +echo "12B: ${PATHS}" pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy