Day 9 2020
[advent-of-code-2020.git] / day09 / numbers.sh
1 #!/bin/bash
2
3 preamble=25
4 window=25
5
6 declare -a data
7
8 exec 3<input.txt
9 while read -u 3 d; do
10     data+=($d)
11 done
12
13 check_for_sum() {
14     local -n sd=$1
15     local check=$2
16     local a
17     local num1
18     local num2
19
20     declare -a values
21     values=( "${sd[@]}" )
22
23     for (( a=0; $a<${#values[@]}; a++ )); do
24         declare -a values_2
25         values_2=( "${values[@]:0:$a}" )
26         values_2+=( "${values[@]:$((a+1))}" )
27         num1=${values[$a]}
28         for num2 in "${values_2[@]}"; do
29             if [ $((num1+$num2)) -eq $check ]; then
30                 return 0
31             fi
32         done
33         unset values_2
34     done
35
36     return 1
37 }
38
39 sequential_sum() {
40     local -n sum_data=$1
41     local check=$2
42     local a
43     local b
44     local cur_sum
45
46     for (( a=0; $a<${#sum_data[@]}; a++ )); do
47         cur_sum=${sum_data[$a]}
48         local -a cur_nums=( ${sum_data[$a]} )
49         for (( b=$((a+1)); b<${#sum_data[@]}; b++ )); do
50             cur_nums+=( "${sum_data[$b]}" )
51             let cur_sum+=$((${sum_data[$b]}))
52             if [ $cur_sum -eq $check ]; then
53                 echo "${cur_nums[@]}"
54                 return 0
55             elif [ $cur_sum -gt $check ]; then
56                 continue 2
57             fi
58         done
59     done
60
61     return 1
62 }
63
64 get_lowest_highest() {
65     local -n hl=$1
66     local lowest=${hl[0]}
67     local highest=${hl[0]}
68     local a
69
70     for (( a=0; a<${#hl[@]}; a++ )); do
71         if [ ${hl[$a]} -lt $lowest ]; then
72             lowest=${hl[$a]}
73         elif [ ${hl[$a]} -gt $highest ]; then
74             highest=${hl[$a]}
75         fi
76     done
77
78     echo "$lowest $highest"
79 }
80
81 offset=0
82 for (( a=$preamble; a< $((${#data[@]}-1)); a++ )); do
83     unset check_array
84     declare -a check_array
85     check_array=( "${data[@]:${offset}:$window}" )
86     check_digit="${data[$a]}"
87     let offset+=1
88     if ! check_for_sum check_array $check_digit; then
89         echo "$check_digit is invalid (position $((a)))"
90         break
91     fi
92     unset check_array
93 done
94
95 echo "Doing sequential sums"
96 declare -a sum_nums=( $(sequential_sum data $check_digit) )
97 unset nums
98 declare -a nums=( $(get_lowest_highest sum_nums) )
99
100 sum=0
101 for num in "${nums[@]}"; do
102     let sum+=$num
103 done
104
105 echo "Sum of lowest (${nums[0]}) and highest (${nums[1]}) numbers: $sum"