--- /dev/null
+#!/bin/bash
+
+set -u
+
+filename="${1:-example.txt}"
+exec 3<"$filename"
+
+declare -a brackets
+
+line_number=0
+score=0
+completion_score=0
+
+declare -A bracket_scores=( [")"]=3 ["]"]=57 ["}"]=1197 [">"]=25137 )
+declare -A bracket_complete_score=( [")"]=1 ["]"]=2 ["}"]=3 [">"]=4 )
+declare -a completion_scores
+
+while read -u 3 line; do
+ ((line_number+=1))
+ bad_line=0
+ for (( a=0; a<${#line}; a++ )); do
+ char=${line:$a:1}
+ case $char in
+ "(")
+ brackets+=(")")
+ ;;
+ "<")
+ brackets+=(">")
+ ;;
+ "[")
+ brackets+=("]")
+ ;;
+ "{")
+ brackets+=("}")
+ ;;
+ *)
+ if [ $char != ${brackets[-1]} ]; then
+ echo "Syntax error, bracket: $char, expected ${brackets[-1]} at offset $a on line $line_number"
+ ((score+=${bracket_scores[$char]}))
+ brackets=()
+ bad_line=1
+ # we're now skipping the rest of the line
+ continue 2
+ else
+ # all good, so remove the last element of the array
+ unset brackets[-1]
+ fi
+ ;;
+ esac
+ done
+ if [ $bad_line -eq 0 ]; then
+ incomplete_lines+=("$line")
+ completion_score=0
+ # usefully, brackets will still contain the right things
+ while [ ${#brackets[@]} -gt 0 ]; do
+ ((completion_score*=5))
+ ((completion_score+=${bracket_complete_score[${brackets[-1]}]}))
+ unset brackets[-1]
+ done
+ completion_scores+=($completion_score)
+ fi
+done
+
+echo "Score for file: $score"
+
+# sort completion_scores
+IFS=$'\n'
+completion_scores=($(sort -n <<<"${completion_scores[*]}"))
+# now get the middle value
+mid_completion=$((${#completion_scores[@]} / 2))
+echo "Completion score: ${completion_scores[$mid_completion]}"