day 25 optimize and improve heuristics
[aoc_eblake.git] / 2015 / advent21.sh
blobfdb31d3d1d5e8b28306a34fd18e8230d3b5b809b
1 read _ _ boss_hit
2 read _ boss_damage
3 read _ boss_armor
4 # battle hit damage armor boss_hit damage armor # return 0 if player beats boss
5 battle() {
6 echo "battle $@"
7 p=$1 b=$4
8 att=$(($2-$6)) def=$(($5-$3))
9 (( att < 1 )) && att=1
10 (( def < 1 )) && def=1
11 turn=0
12 while :; do
13 b=$((b-att))
14 (( b > 0 )) || return 0;
15 p=$((p-def))
16 (( p > 0 )) || return 1;
17 done
19 weapon=('8 4 0' '10 5 0' '25 6 0' '40 7 0' '74 8 0')
20 armor=('0 0 0' '13 0 1' '31 0 2' '53 0 3' '75 0 4' '102 0 5')
21 ring=('0 0 0' '25 1 0' '50 2 0' '100 3 0' '20 0 1' '40 0 2' '80 0 3')
22 lowest=99999
23 highest=0
24 # prep w w w a a a r1 r1 r1 r2 r2 r2 # buy stuff to prepare for battle
25 prep() {
26 echo "prep $@"
27 cost=$(($1 + $4 + $7 + ${10}))
28 if battle 100 $(($2 + $5 + $8 + ${11})) $(($3 + $6 + $9 + ${12})) \
29 $boss_hit $boss_damage $boss_armor; then
30 echo "win, after spending $cost"
31 [[ $cost -lt $lowest ]] && lowest=$cost
32 else
33 echo "loss, after spending $cost"
34 [[ $cost -gt $highest ]] && highest=$cost
37 count=0
38 for w in ${!weapon[*]}; do
39 for a in ${!armor[*]}; do
40 for r1 in ${!ring[*]}; do
41 for r2 in ${!ring[*]}; do
42 (( r1 ? r1 == r2 : r2 )) && continue
43 : $((count++))
44 prep ${weapon[w]} ${armor[a]} ${ring[r1]} ${ring[r2]}
45 done
46 done
47 done
48 done
49 echo "after trying $count scenarios, cheapest win costs $lowest"
50 echo "most expensive loss is $highest"