X-Git-Url: https://git.sommitrealweird.co.uk/advent-of-code-2021.git/blobdiff_plain/ff11a5a71056e4925c183d385beb270eeafbd97d..64d8769ea65405cdc0a1f8e65a8a1fa25bbf71df:/day08/get_count.sh diff --git a/day08/get_count.sh b/day08/get_count.sh new file mode 100755 index 0000000..4a89d5e --- /dev/null +++ b/day08/get_count.sh @@ -0,0 +1,156 @@ +#!/bin/bash + +set -u + +filename="${1:-input.txt}" + +exec 3<"$filename" + +declare -a all_inputs +declare -a all_outputs + +while read -u 3 -d "|" inputs; do + all_inputs+=("$inputs") + read -u 3 outputs + all_outputs+=("$outputs") +done + +one_count=0 # 2 on signals +seven_count=0 # 3 on signals +four_count=0 # 4 on signals +eight_count=0 # 7 on signals + +for output in "${all_outputs[@]}"; do + read -a seperates <<<$output + for s in "${seperates[@]}"; do + case ${#s} in + 2) + ((one_count+=1)) + ;; + 3) + ((seven_count+=1)) + ;; + 4) + ((four_count+=1)) + ;; + 7) + ((eight_count+=1)) + ;; + esac + done +done + +echo "1 count: $one_count" +echo "4 count: $four_count" +echo "7 count: $seven_count" +echo "8 count: $eight_count" +echo +echo "Total: $((one_count+$four_count+$seven_count+$eight_count))" + +declare -A seg_vals=( [a]=1 [b]=2 [c]=4 [d]=8 [e]=16 [f]=32 [g]=64 ) +declare -A char_map=( [119]=0 [36]=1 [93]=2 [109]=3 [46]=4 [107]=5 [123]=6 [37]=7 [127]=8 [111]=9 ) + +get_digits() { + local input="$1" + local output="$2" + local -A segcounts=( [a]=0 [b]=0 [c]=0 [d]=0 [e]=0 [f]=0 [g]=0 ) + local -A segmap=( [a]= [b]= [c]= [d]= [e]= [f]= [g]= ) + + read -a segs <<<"${input}" + for seg in "${segs[@]}"; do + for (( a=0; a<${#seg}; a++ )); do + ((segcounts[${seg:$a:1}]+=1)) + done + done + + # we've now got some counts, so we can do *some* of the mappings + for seg_name in "${!segcounts[@]}"; do + case ${segcounts[$seg_name]} in + 4) + segmap[$seg_name]=e + ;; + 6) + segmap[$seg_name]=b + ;; + 9) + segmap[$seg_name]=f + ;; + 7) + segmap[$seg_name]=dg + ;; + 8) + segmap[$seg_name]=ac + ;; + esac + done + + # now go through segs again, this time checking how long the string is, because from that + # we can find 7, which will give us a. + + for seg in "${segs[@]}"; do + case ${#seg} in + 2) + # this is number 1 - it has a c but no a + for (( a=0; a<${#seg}; a++ )); do + if [ ${segmap[${seg:$a:1}]} == "ac" ]; then + segmap[${seg:$a:1}]=c + break + fi + done + # because we've worked out where a is, we now go find the one that thinks it's a or c + for seg_name in "${!segmap[@]}"; do + if [ "${segmap[$seg_name]}" == "ac" ]; then + segmap[$seg_name]=a + break + fi + done + ;; + 4) + # this is number 4 + for (( a=0; a<${#seg}; a++ )); do + if [ ${segmap[${seg:$a:1}]} == "dg" ]; then + segmap[${seg:$a:1}]=d + break + fi + done + for seg_name in "${!segmap[@]}"; do + if [ "${segmap[$seg_name]}" == "dg" ]; then + segmap[$seg_name]=g + break + fi + done + ;; + esac + done + + output_digits="" + + # finally, we can get each of the digits in the output, so go through the output + read -a charsets <<<"${output}" + for chars in "${charsets[@]}"; do + char_value=0 + for (( a=0; a<${#chars}; a++ )); do + ((char_value+=${seg_vals[${segmap[${chars:$a:1}]}]})) + done + if [ "${char_map[$char_value]+abc}" ]; then + output_digits+=${char_map[$char_value]} + else + declare -p segmap >&2 + echo "Chars: $chars" >&2 + exit 1 + fi + done + + # remove any leading 0s the cheating way + echo $((10#$output_digits)) +} + +# Now lets start playing with the first input and try working out the outputs + +total_output_count=0 + +for (( a=0; a<${#all_inputs[@]}; a++ )); do + ((total_output_count+=$(get_digits "${all_inputs[$a]}" "${all_outputs[$a]}"))) +done + +echo "Sum of all output digits: $total_output_count"