Day 9 2020
[advent-of-code-2020.git] / day09 / numbers.sh
diff --git a/day09/numbers.sh b/day09/numbers.sh
new file mode 100755 (executable)
index 0000000..34f55c9
--- /dev/null
@@ -0,0 +1,105 @@
+#!/bin/bash
+
+preamble=25
+window=25
+
+declare -a data
+
+exec 3<input.txt
+while read -u 3 d; do
+    data+=($d)
+done
+
+check_for_sum() {
+    local -n sd=$1
+    local check=$2
+    local a
+    local num1
+    local num2
+
+    declare -a values
+    values=( "${sd[@]}" )
+
+    for (( a=0; $a<${#values[@]}; a++ )); do
+        declare -a values_2
+        values_2=( "${values[@]:0:$a}" )
+        values_2+=( "${values[@]:$((a+1))}" )
+        num1=${values[$a]}
+        for num2 in "${values_2[@]}"; do
+            if [ $((num1+$num2)) -eq $check ]; then
+                return 0
+            fi
+        done
+        unset values_2
+    done
+
+    return 1
+}
+
+sequential_sum() {
+    local -n sum_data=$1
+    local check=$2
+    local a
+    local b
+    local cur_sum
+
+    for (( a=0; $a<${#sum_data[@]}; a++ )); do
+        cur_sum=${sum_data[$a]}
+        local -a cur_nums=( ${sum_data[$a]} )
+        for (( b=$((a+1)); b<${#sum_data[@]}; b++ )); do
+            cur_nums+=( "${sum_data[$b]}" )
+            let cur_sum+=$((${sum_data[$b]}))
+            if [ $cur_sum -eq $check ]; then
+                echo "${cur_nums[@]}"
+                return 0
+            elif [ $cur_sum -gt $check ]; then
+                continue 2
+            fi
+        done
+    done
+
+    return 1
+}
+
+get_lowest_highest() {
+    local -n hl=$1
+    local lowest=${hl[0]}
+    local highest=${hl[0]}
+    local a
+
+    for (( a=0; a<${#hl[@]}; a++ )); do
+        if [ ${hl[$a]} -lt $lowest ]; then
+            lowest=${hl[$a]}
+        elif [ ${hl[$a]} -gt $highest ]; then
+            highest=${hl[$a]}
+        fi
+    done
+
+    echo "$lowest $highest"
+}
+
+offset=0
+for (( a=$preamble; a< $((${#data[@]}-1)); a++ )); do
+    unset check_array
+    declare -a check_array
+    check_array=( "${data[@]:${offset}:$window}" )
+    check_digit="${data[$a]}"
+    let offset+=1
+    if ! check_for_sum check_array $check_digit; then
+        echo "$check_digit is invalid (position $((a)))"
+        break
+    fi
+    unset check_array
+done
+
+echo "Doing sequential sums"
+declare -a sum_nums=( $(sequential_sum data $check_digit) )
+unset nums
+declare -a nums=( $(get_lowest_highest sum_nums) )
+
+sum=0
+for num in "${nums[@]}"; do
+    let sum+=$num
+done
+
+echo "Sum of lowest (${nums[0]}) and highest (${nums[1]}) numbers: $sum"