day 19 part 1 (bash)

This commit is contained in:
2021-07-17 20:38:07 +02:00
parent 50e657c55f
commit 4159c69c1d
2 changed files with 93 additions and 0 deletions

30
day19/Makefile Normal file
View File

@@ -0,0 +1,30 @@
INPUT := INPUT.txt
SHELL := /bin/bash
CFLAGS := -w -g
#CFLAGS := -w -g -pg
#CFLAGS := -w -O3
TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n"
export PATH := .:$(PATH)
.PHONY: clean all compile deploy ex1 ex2
all: ex1 ex2
output:
@$(MAKE) --no-print-directory all 2>&1 > OUTPUT
compile: ex1-c ex2-c
ex1:
@$(TIME) ex1.bash < $(INPUT) 2>&1
@#$(TIME) ex1-c 2020 < $(INPUT) 2>&1
ex2:
@$(TIME) ex2.bash < $(INPUT) 2>&1
@#$(TIME) ex1-c 30000000 < $(INPUT) 2>&1
clean:
@rm -f ex1-c ex2-c core
deploy:
@$(MAKE) -C .. deploy

63
day19/ex1.bash Executable file
View File

@@ -0,0 +1,63 @@
#!/bin/bash
#
# ex1.bash: Advent2020 game, day 19/game 1.
CMD=${0##*/}
set -o noglob
shopt -s extglob
declare -a RULE=() MATCH=() STRING=()
# shellcheck disable=SC2034
declare var_0
declare -i res=0
# build a regexp use-able by bash =~ operator.
# Recursively replace rules, until we get final text values.
# To avoid running subshell, we must create local variables w/ different
# names at each recursion level (to avoid "circular name reference" error).
function buildtree {
local -i prof="$1" # to allow ≠ local names
local -n upname="$2" # caller variable name
local name="var_$prof" # local var name, w/ depth
eval "local $name" # ... declared here
shift 2
local args=$* res="" arg
for arg in $args; do
if [[ -z "${arg/[|ab]}" ]]; then
res+="$arg"
else
if [[ ! -v MATCH[$arg] ]]; then
buildtree "$((prof+1))" "$name" "${RULE[$arg]}"
MATCH[$arg]="(${!name})"
fi
res+=${MATCH[$arg]}
fi
done
# shellcheck disable=SC2034
upname="$res"
}
while read -r line; do
case ${line:0:1} in
[0-9]*) # rule
rule=${line%:*}
val=${line#*: }
RULE[$rule]="${val//\"}"
;;
[a-z]*) # string
STRING+=("$line")
;;
esac
done
buildtree 1 var_0 0
#printf "RULE ZERO = %s\n" "${MATCH[0]}"
for str in "${STRING[@]}"; do
[[ "$str" =~ ^${MATCH[0]}$ ]] && ((res++))
done
printf "%s : res=%d\n" "$CMD" "$res"
exit 0