X-Git-Url: https://git.sommitrealweird.co.uk/advent-of-code-2021.git/blobdiff_plain/a8478dc6f1b0da0421ec3c07ce400aeb8b39a9eb..37f395fcc0f553c839358bbc9f840aa5f6cf83b1:/day03/diag.sh diff --git a/day03/diag.sh b/day03/diag.sh new file mode 100755 index 0000000..9e8c823 --- /dev/null +++ b/day03/diag.sh @@ -0,0 +1,152 @@ +#!/bin/bash + +set -e +set -u + +filename="${1:-example.txt}" + +exec 3<"$filename" + +line_length=0 +declare -a most_common=( 0 ) +declare -a all_binaries +line_count=0 + +while read -u 3 line; do + all_binaries+=($line) + if [ $line_length -eq 0 ]; then + line_length=${#line} + fi + for (( i=0; i < $line_length; i++ )); do + if [ ${#most_common[@]} -lt $i ]; then + most_common[$i]=0 + fi + if [ ${line:$i:1} -eq 1 ]; then + ((most_common[$i]+=1)) + fi + done + ((line_count+=1)) +done + +half_line_count=$((line_count/2)) +binary_string="" +inverse_binary_string="" + +for (( i=0; i < $line_length; i++ )); do + if [ ${most_common[$i]} -gt $half_line_count ]; then + binary_string+=1 + inverse_binary_string+=0 + else + binary_string+=0 + inverse_binary_string+=1 + fi +done + +total=$((2#$binary_string * 2#$inverse_binary_string)) + +echo Answer: $total + +declare -a co2_scrubber +declare -a o2_generator + +# first populate co2_scrubbers and o2_generator + +co2_filter_digit=1 +o2_generator_digit=0 + +if [ ${most_common[0]} -gt $half_line_count ]; then + co2_filter_digit=0 + o2_generator_digit=1 +else + co2_filter_digit=1 + o2_generator_digit=0 +fi + +for val in "${all_binaries[@]}"; do + if [ ${val:0:1} -eq $co2_filter_digit ]; then + co2_scrubber+=($val) + fi + if [ ${val:0:1} -eq $o2_generator_digit ]; then + o2_generator+=($val) + fi +done + +get_most_common() { + offset=$1 + local -n arr=$2 + ones=0 + zeros=0 + + for val in "${arr[@]}"; do + part=${val:$offset:1} + if [ $part -eq 1 ]; then + ((ones+=1)) + else + ((zeros+=1)) + fi + done + + if [ $ones -gt $zeros ]; then + echo 1 + elif [ $ones -lt $zeros ]; then + echo 0 + else + echo 2 + fi +} + +get_least_common() { + offset=$1 + array_name=$2 + + val=$(get_most_common $offset $array_name) + case $val in + 0) + echo 1 + ;; + 1) + echo 0 + ;; + 2) + echo 2 + ;; + esac +} + +filter_array() { + val=$1 + pos=$2 + local -n arr=$3 + + if [ ${#arr[@]} -eq 1 ]; then + return + fi + + declare -a new_arr + for thing in "${arr[@]}"; do + if [ ${thing:$pos:1} -eq $val ]; then + new_arr+=($thing) + fi + done + + arr=("${new_arr[@]}") +} + +for ((i=1; i < $line_length; i++)); do + co2_filter=$(get_least_common $i co2_scrubber) + o2_filter=$(get_most_common $i o2_generator) + + if [ $co2_filter -eq 2 ]; then + co2_filter=0 + fi + + if [ $o2_filter -eq 2 ]; then + o2_filter=1 + fi + + filter_array $co2_filter $i co2_scrubber + filter_array $o2_filter $i o2_generator +done + +# we've only got 1 in each - so... +echo Life Support Rating: $((2#${o2_generator[0]} * 2#${co2_scrubber[0]}))