Day 15 faster version and initial part 2
[advent-of-code-2021.git] / day10 / syntax_check.sh
1 #!/bin/bash
2
3 set -u
4
5 filename="${1:-example.txt}"
6 exec 3<"$filename"
7
8 declare -a brackets
9
10 line_number=0
11 score=0
12 completion_score=0
13
14 declare -A bracket_scores=( [")"]=3 ["]"]=57 ["}"]=1197 [">"]=25137 )
15 declare -A bracket_complete_score=( [")"]=1 ["]"]=2 ["}"]=3 [">"]=4 )
16 declare -a completion_scores
17
18 while read -u 3 line; do
19     ((line_number+=1))
20     bad_line=0
21     for (( a=0; a<${#line}; a++ )); do
22         char=${line:$a:1}
23         case $char in
24             "(")
25                 brackets+=(")")
26                 ;;
27             "<")
28                 brackets+=(">")
29                 ;;
30             "[")
31                 brackets+=("]")
32                 ;;
33             "{")
34                 brackets+=("}")
35                 ;;
36             *)
37                 if [ $char != ${brackets[-1]} ]; then
38                     echo "Syntax error, bracket: $char, expected ${brackets[-1]} at offset $a on line $line_number"
39                     ((score+=${bracket_scores[$char]}))
40                     brackets=()
41                     bad_line=1
42                     # we're now skipping the rest of the line
43                     continue 2
44                 else
45                     # all good, so remove the last element of the array
46                     unset brackets[-1]
47                 fi
48                 ;;
49         esac
50     done
51     if [ $bad_line -eq 0 ]; then
52         incomplete_lines+=("$line")
53         completion_score=0
54         # usefully, brackets will still contain the right things
55         while [ ${#brackets[@]} -gt 0 ]; do
56             ((completion_score*=5))
57             ((completion_score+=${bracket_complete_score[${brackets[-1]}]}))
58             unset brackets[-1]
59         done
60         completion_scores+=($completion_score)
61     fi
62 done
63
64 echo "Score for file: $score"
65
66 # sort completion_scores
67 IFS=$'\n'
68 completion_scores=($(sort -n <<<"${completion_scores[*]}"))
69 # now get the middle value
70 mid_completion=$((${#completion_scores[@]} / 2))
71 echo "Completion score: ${completion_scores[$mid_completion]}"