day 13 optimize
[aoc_eblake.git] / 2015 / advent7.sh
blobbf91a962d3370615a8c3bda280aebeb55d691dac
1 unset wires cache
2 declare -A wires cache
3 shopt -s extglob
4 count=0
5 while IFS=, read op wire; do
6 wires[$wire]="$op"
7 count=$((count+1))
8 done < <(sed 's/ -> /,/')
9 echo "found $count wires"
10 # Find wire $1, store its value in $val. Recursive.
11 indent=
12 call=0
13 get() {
14 call=$((call+1))
15 if [[ call -gt $((count**2)) ]]; then
16 echo "recursing too deep!"; exit 1
18 local a b vala valb mycall
19 mycall=$call
20 echo "$indent$mycall: looking up wire/value $1 (${wires[$1]})"
21 indent+=" "
22 if [[ ${cache[$1]+set} ]]; then
23 indent=${indent#?}
24 echo "${indent}cached: ${cache[$1]}"
25 val=${cache[$1]}
26 return;
28 case $1_${wires[$1]} in
29 *[0-9]_*) val=$1 ;;
30 *AND*) read a ignore b <<< "${wires[$1]}"
31 get $a
32 vala=$val
33 get $b
34 valb=$val
35 val=$((vala & valb));;
36 *OR*) read a ignore b <<< "${wires[$1]}"
37 get $a
38 vala=$val
39 get $b
40 valb=$val
41 val=$((vala | valb));;
42 *NOT*) read ignore a <<< "${wires[$1]}"
43 get $a
44 vala=$val
45 val=$((~vala & 0xffff));;
46 *LSHIFT*) read a ignore b <<< "${wires[$1]}"
47 get $a
48 vala=$val
49 val=$(((vala << b) & 0xffff));;
50 *RSHIFT*) read a ignore b <<< "${wires[$1]}"
51 get $a
52 vala=$val
53 val=$((vala >> b));;
54 *) get ${wires[$1]} ;;
55 esac
56 indent=${indent#?}
57 printf "$indent$mycall: wire $1 contains 0x%x (%d)\n" "$val" "$val"
58 cache[$1]=$val
60 get ${1:-a}
61 if [[ ${1:-a} == a ]]; then
62 echo "rewriting wire b"
63 unset cache
64 declare -A cache
65 wires[b]=$val
66 get a