rename repo, subdir for yearly challenges
This commit is contained in:
125
2020/day04/ex2.bash
Executable file
125
2020/day04/ex2.bash
Executable file
@@ -0,0 +1,125 @@
|
||||
#!/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
|
Reference in New Issue
Block a user