126 lines
2.7 KiB
Bash
Executable File
126 lines
2.7 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# ex2.bash: Advent2020 game, day 4/game 2.
|
|
|
|
CMD=${0##*/}
|
|
shopt -s extglob
|
|
|
|
declare -A KEYS=( ["byr"]="" ["iyr"]="" ["eyr"]="" ["hgt"]="" ["hcl"]="" ["ecl"]=""
|
|
["pid"]="" ["cid"]="" )
|
|
NKEYS=${#KEYS[@]}
|
|
|
|
function reset_array() { # reset array values
|
|
local -n array=${1}
|
|
local key
|
|
|
|
#echo before reset: ${KEYS[@]}
|
|
for key in "${!array[@]}"; do
|
|
array[$key]=""
|
|
done
|
|
#echo after reset: ${KEYS[@]}
|
|
}
|
|
|
|
# returns 1 if $1 length is $2
|
|
function check_length() {
|
|
return $((${#1} != $2))
|
|
}
|
|
function check_digits() {
|
|
[[ "$1" =~ ^[[:digit:]]+$ ]] && return 0 || return 1
|
|
}
|
|
# returns 1 if $1 is between $2 and $3
|
|
function check_range() {
|
|
(($1 >= $2 && $1 <= $3)) && return 0 || return 1
|
|
}
|
|
declare -A COLORS=( ["amb"]="" ["blu"]="" ["brn"]="" ["gry"]=""
|
|
["grn"]="" ["hzl"]="" ["oth"]="" )
|
|
function check_eye() {
|
|
[[ -v COLORS["$1"] ]] && return 0 || return 1
|
|
}
|
|
function check_height() {
|
|
local -i ret=1
|
|
local val="$1" unit=${val: -2}
|
|
local num=${val%%$unit}
|
|
|
|
#printf "unit=%s hgt=%s\n" "$unit" "$num"
|
|
case "$unit" in
|
|
"cm") check_digits "$num" && check_range "$num" 150 193 && ret=0
|
|
;;
|
|
"in") check_digits "$num" && check_range "$num" 59 76 && ret=0
|
|
;;
|
|
esac
|
|
return $ret
|
|
}
|
|
function check_hair() {
|
|
[[ "$1" =~ ^#[a-f0-9]{6}$ ]] && return 0 || return 1
|
|
}
|
|
|
|
function check_key() {
|
|
local -i valid=0
|
|
local key="$1" val="${KEYS[$key]}"
|
|
|
|
#printf "KEY/VAL = %s=[%s]\n" "$key" "$val"
|
|
case "$key" in
|
|
cid) valid=1
|
|
;;
|
|
byr) check_digits "$val" &&
|
|
check_length "$val" 4 &&
|
|
check_range "$val" 1920 2002 && valid=1
|
|
;;
|
|
iyr) check_digits "$val" &&
|
|
check_length "$val" 4 &&
|
|
check_range "$val" 2010 2020 && valid=1
|
|
;;
|
|
eyr) check_digits "$val" &&
|
|
check_length "$val" 4 &&
|
|
check_range "$val" 2020 2030 && valid=1
|
|
;;
|
|
pid) check_digits "$val" &&
|
|
check_length "$val" 9 && valid=1
|
|
;;
|
|
ecl) check_eye "$val" && valid=1
|
|
;;
|
|
hcl) check_hair "$val" && valid=1
|
|
;;
|
|
hgt) check_height "$val" && valid=1
|
|
;;
|
|
# TODO
|
|
*) valid=1
|
|
;;
|
|
esac
|
|
#printf "%s=[%s] : valid=%d\n" "$key" "$val" $valid
|
|
#[[ ! $key == "cid" ]] && [[ -z ${KEYS[$key]} ]] && valid=0 && break
|
|
return $valid
|
|
}
|
|
|
|
function passport_valid() {
|
|
local -i ret=0
|
|
|
|
for key in "${!KEYS[@]}"; do
|
|
#printf "current key: %s\n" "$key"
|
|
[[ $key != "cid" ]] && #[[ -z ${KEYS[$key]} ]] &&
|
|
check_key "$key" && ret=1 && break
|
|
done
|
|
return $ret
|
|
}
|
|
|
|
declare -i current=0 nvalids=0
|
|
|
|
while read -r line; do
|
|
if [[ -z "$line" ]]; then
|
|
((current++))
|
|
passport_valid && ((nvalids ++))
|
|
reset_array KEYS
|
|
continue
|
|
fi
|
|
for pair in $line; do
|
|
key=${pair%%:*}
|
|
val=${pair##*:}
|
|
[[ -v KEYS[$key] ]] && KEYS[$key]="$val" # valid key
|
|
done
|
|
done
|
|
((current++))
|
|
passport_valid && ((nvalids ++))
|
|
printf "%s : valid=%d/%d\n" "$CMD" "$nvalids" "$current"
|
|
|
|
exit 0
|