Advent of Code F# – Day 21

The source code for this post (both Part 1 and Part 2) is avail­able here and you can click here to see my solu­tions for the oth­er Advent of Code chal­lenges.

Descrip­tion for today’s chal­lenge is here.

 

Mod­el­ling and sim­u­lat­ing a RPG, this chal­lenge total­ly got my nerd brain into over­drive, which is prob­a­bly why I went total­ly over­board with mod­el­ling the domain! (you’ll see soon enough..)

Modelling

First we have char­ac­ters in the game (you and the boss) with hit points (HP), dam­age and armor scores:

day21_01

Then we have the equip­ments, which have costs, as well as dam­age and armor stats:

day21_02

Then we also have shops, who sell these equip­ments:

day21_03

Configurations

Ini­tial­ly, you have 100 Hit Points, but no dam­age or armor stats (these come from equip­ments).

The state of the boss comes from your input:

day21_04

We also need to con­fig­ure the shop’s inven­to­ry accord­ing to the descrip­tion of the chal­lenge:

day21_05

Simulation

From the descrip­tion, we know that:

  • you have to pick one weapon
  • you can have 0–1 armor
  • you can have 0–2 rings

So, to make com­bin­ing equip­ments eas­i­er lat­er on (we want your selec­tion of equip­ments to be a sim­ple Equip­ment[]), let’s cre­ate a few sequences of Equip­ment[] to rep­re­sent your choic­es of weapons, armors and rings.

For weapons and armors, this is pret­ty straight­for­ward:

day21_06

For rings, it’s slight­ly more involved:

day21_07

Because the order­ing of the rings are not impor­tant — [| ring1; ring2 |] is the same as [| ring2; ring1 |] — so here we work out all com­bi­na­tions of 2 rings from the avail­able 6.

Next, let’s work out all pos­si­ble equip­ment com­bi­na­tions we can buy from the shop:

day21_08

We’ll also need to be able to sim­u­late a game between you and the boss:

day21_12

Notice in the inner recur­sive loop above, we swap the role of the attack­er and defend­er on every iter­a­tion (whilst also deduct­ing the defender’s HP) and return the name of the win­ner when the defender’s HP reach­es 0<HP>.

Now that all the pieces are in place, we can answer the chal­lenge by iter­at­ing over all equip­ment com­bos, and send­ing you in bat­tle with the boss with each. For the com­bos that results in you win­ning, we sim­ply work out the cost and find the min:

day21_10

job done!

 

Part 2

Only a minor tweak is required here — change the win­ner to “boss” and look for max cost instead of min:

day21_11