Day 14
[advent-of-code-2021.git] / day14 / poly-different.sh
1 #!/bin/bash
2
3 set -u
4
5 filename="${1:-example.txt}"
6 exec 3<"$filename"
7
8 read -u 3 template
9 read -u 3 blank
10
11 declare -A inserts=()
12
13 while read -u 3 poly; do
14     left="${poly% -> *}"
15     right="${poly#* -> }"
16     inserts[$left]="$right"
17 done
18
19 declare -A pair_result=()
20 for k in "${!inserts[@]}"; do
21     char="${inserts[$k]}"
22     pair_result[$k]="${k:0:1}${char} ${char}${k:1:1}"
23 done
24
25 declare -A pairs=()
26 for (( a=0; a<$((${#template} - 1)); a++ )); do
27     lookup="${template:$a:2}"
28     if [ "${pairs[$lookup]+abc}" ]; then
29         ((pairs[$lookup]+=1))
30     else
31         pairs[$lookup]=1
32     fi
33 done
34
35 do_next_step() {
36     declare -A new_pairs=()
37     for pair in "${!pairs[@]}"; do
38         count=${pairs[$pair]}
39         for new_pair in ${pair_result[$pair]}; do
40             if [ "${new_pairs[$new_pair]+abc}" ]; then
41                 ((new_pairs[$new_pair]+=$count))
42             else
43                 new_pairs[$new_pair]=$count
44             fi
45         done
46     done
47     unset pairs
48     declare -g -A pairs=()
49     for k in "${!new_pairs[@]}"; do
50         pairs[$k]=${new_pairs[$k]}
51     done
52 }
53
54 get_diff() {
55     declare -A char_counts=()
56     for k in "${!pairs[@]}"; do
57         for (( a=0; a<2; a++ )); do
58             char=${k:$a:1}
59             if [ "${char_counts[$char]+abc}" ]; then
60                 ((char_counts[$char]+=${pairs[$k]}))
61             else
62                 char_counts[$char]=${pairs[$k]}
63             fi
64         done
65     done
66
67     for char in ${template:0:1} ${template: -1:1}; do # start and end of template get lost from the original count
68         if [ "${char_counts[$char]+abc}" ]; then
69             ((char_counts[$char]+=1))
70         else
71             char_counts[$char]=1
72         fi
73     done
74
75     declare -a hl=()
76     for v in "${char_counts[@]}"; do
77         hl[$v]=1
78     done
79
80     declare -a vals=("${!hl[@]}")
81     h=${vals[-1]}
82     l=${vals[0]}
83
84     diff=$((h - $l))
85     diff=$((diff / 2)) # because the parts are in pairs, our counts are going to be double what they should be
86
87     echo $diff
88 }
89
90 for (( a=1; a<=10; a++ )); do
91     do_next_step
92 done
93
94 echo "Part 1: $(get_diff)"
95
96 for (( a=11; a<=40; a++ )); do
97     do_next_step
98 done
99
100 echo "Part 2: $(get_diff)"