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..)


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


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


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



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:


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



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:


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


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:


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


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:


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: