Skip to content

Commit

Permalink
Year 2015: Day 21
Browse files Browse the repository at this point in the history
  • Loading branch information
joshleaves committed Feb 16, 2024
1 parent 6521976 commit 850af4f
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Consistency is hard without proper goals to set a good (let's dare say "atomic")
I'm also adding notes that may be useful if you're learning Ruby.

Notes for solving:
* [2015, up to day 20](year_2015.md)
* [2015, up to day 21](year_2015.md)
* [2023, up to day 03](year_2023.md)

# How to use
Expand Down
21 changes: 21 additions & 0 deletions spec/year_2015/day_21_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
require 'year_2015/day_21'

describe Year2015::Day21 do
context 'when Results' do
subject(:input_data) do
{
hp: 100,
damage: 8,
armor: 2
}
end

it 'correctly answers part 1' do
expect(described_class.new(input_data, true).to_i).to eq(91)
end

it 'correctly answers part 2' do
expect(described_class.new(input_data).to_i).to eq(158)
end
end
end
11 changes: 11 additions & 0 deletions year_2015.md
Original file line number Diff line number Diff line change
Expand Up @@ -343,3 +343,14 @@ Year2015::Day20
I've had to calculate list of primes and divisors in the past, and it always sucked. My previous algorithms were correct but always too long (but what is "long" when you're nearing infinity?).

Again, [outside help](https://dmatrix.dev/posts/advent-of-code-year-2015-day-20/) is a great resource to find algorithms better than yours.

## Day 21

```
Year2015::Day21
when Results
correctly answers part 1
correctly answers part 2
```

...really nothing to say here.
90 changes: 90 additions & 0 deletions year_2015/day_21.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
class Year2015
class Day21
WEAPONS = [
['Dagger', 8, 4, 0],
['Shortsword', 10, 5, 0],
['Warhammer', 25, 6, 0],
['Longsword', 40, 7, 0],
['Greataxe', 74, 8, 0]
].freeze
ARMORS = [
['None', 0, 0, 0],
['Leather', 13, 0, 1],
['Chainmail', 31, 0, 2],
['Splintmail', 53, 0, 3],
['Bandedmail', 75, 0, 4],
['Platemail', 102, 0, 5]
].freeze
ACCESSORIES = [
['None', 0, 0, 0],
['None', 0, 0, 0],
['Damage +1', 25, 1, 0],
['Damage +2', 50, 2, 0],
['Damage +3', 100, 3, 0],
['Defense +1', 20, 0, 1],
['Defense +2', 40, 0, 2],
['Defense +3', 80, 0, 3]
].freeze

def initialize(input_boss, input_part_one = false)
@version = input_part_one ? 1 : 2
@boss = input_boss
@best_price = @version == 1 ? 256 : 8
end

def simulate_battle(player_damage, player_armor)
player_hp = 100
player_damage = [1, player_damage - @boss[:armor]].max
boss_hp = @boss[:hp]
boss_damage = [1, @boss[:damage] - player_armor].max

player_turns = (player_hp / boss_damage) + 1
boss_turns = (boss_hp / player_damage) + 1
player_turns >= boss_turns

# until boss_hp.negative? || player_hp.negative?
# boss_hp -= player_attack
# # puts "-> Player deals #{player_attack} damage; the boss goes down to #{boss_hp}"
# return true if boss_hp.negative?

# player_hp -= boss_attack
# # puts "-> Boss deals #{boss_attack} damage; the player goes down to #{player_hp}"
# return false if player_hp.negative?
# end
end

def use_equipment(equipment)
price = equipment.sum{|object| object[1] }

damage = equipment.sum{|object| object[2] }
armor = equipment.sum{|object| object[3] }
result = simulate_battle(damage, armor)
update_price(price, result)
end

def loop_equiment
WEAPONS.each do |weapon|
ARMORS.each do |armor|
ACCESSORIES[0..-2].each_with_index do |acc1, i|
ACCESSORIES[i..].each do |acc2|
use_equipment([weapon, armor, acc1, acc2])
end
end
end
end
end

def update_price(price, result)
if @version == 1 && result
@best_price = [@best_price, price].min
elsif @version == 2 && !result
@best_price = [@best_price, price].max
end
end

def to_i
loop_equiment
@best_price
end
end
end

0 comments on commit 850af4f

Please sign in to comment.