Use a variable reference for where to store the result, stop putting all results...
[advent-of-code-2020.git] / day15 / memory.sh
1 #!/bin/bash
2
3 set -u
4
5 read_file() {
6     filename="$1"
7     local IFS=","
8     exec 3<"$filename"
9     read -u 3 -a data
10 }
11
12 get_answer() {
13     local number=$1
14     local count=$2
15     local -n __fn_result=$3
16     if [ ${lastseen[$number]+a} ]; then
17         __fn_result=$((count-${lastseen[$number]}))
18     else
19         __fn_result=0
20     fi
21 }
22
23 do_nothing() {
24     return
25 }
26
27 error_echo() {
28     echo "$@" >&2
29 }
30
31 DEBUG="${DEBUG:-}"
32 debug_func=do_nothing
33
34 if [ -n "$DEBUG" ]; then
35     debug_func="error_echo"
36 fi
37
38 filename="${1:-p1_436.txt}"
39
40 read_file "$filename"
41
42 declare -A lastseen
43
44 current_answer=-1
45 last_answer=-1
46 count=0
47
48 result=
49
50 for number in ${data[@]}; do
51     count=$((count+1))
52     last_answer=$current_answer
53     if [ $last_answer -ge 0 ]; then
54         lastseen[$last_answer]=$((count-1))
55     fi
56     current_answer=$number
57 done
58
59 while [ $count -lt 2020 ]; do
60     last_answer=$current_answer
61     get_answer $current_answer $count result
62     count=$((count+1))
63     current_answer=$result
64     lastseen[$last_answer]=$((count-1))
65     $debug_func "$count: $current_answer"
66 done
67
68 echo "Part 1: $current_answer"
69
70 while [ $count -lt 30000000 ]; do
71     last_answer=$current_answer
72     get_answer $current_answer $count result
73     count=$((count+1))
74     current_answer=$result
75     lastseen[$last_answer]=$((count-1))
76     $debug_func "$count: $current_answer"
77 done
78
79 echo "Part 2: $current_answer"