Skip to content

Commit

Permalink
Year 2015: Day 14
Browse files Browse the repository at this point in the history
  • Loading branch information
joshleaves committed Feb 11, 2024
1 parent ee59d52 commit 36bf5b2
Show file tree
Hide file tree
Showing 6 changed files with 126 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 13](year_2015.md)
* [2015, up to day 14](year_2015.md)
* [2023, up to day 03](year_2023.md)

# How to use
Expand Down
9 changes: 9 additions & 0 deletions spec/year_2015/day_14_input
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Vixen can fly 8 km/s for 8 seconds, but then must rest for 53 seconds.
Blitzen can fly 13 km/s for 4 seconds, but then must rest for 49 seconds.
Rudolph can fly 20 km/s for 7 seconds, but then must rest for 132 seconds.
Cupid can fly 12 km/s for 4 seconds, but then must rest for 43 seconds.
Donner can fly 9 km/s for 5 seconds, but then must rest for 38 seconds.
Dasher can fly 10 km/s for 4 seconds, but then must rest for 37 seconds.
Comet can fly 3 km/s for 37 seconds, but then must rest for 76 seconds.
Prancer can fly 9 km/s for 12 seconds, but then must rest for 97 seconds.
Dancer can fly 37 km/s for 1 seconds, but then must rest for 36 seconds.
2 changes: 2 additions & 0 deletions spec/year_2015/day_14_sample_one
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Comet can fly 14 km/s for 10 seconds, but then must rest for 127 seconds.
Dancer can fly 16 km/s for 11 seconds, but then must rest for 162 seconds.
37 changes: 37 additions & 0 deletions spec/year_2015/day_14_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
require 'year_2015/day_14'

describe Year2015::Day14 do
context 'when Part 1' do
subject(:sample_one) do
described_class.new(File.read('spec/year_2015/day_14_sample_one'), true)
end

it 'gives a final result' do
expect(sample_one.to_i(1000)).to eq(1120)
end
end

context 'when Part 2' do
subject(:sample_one) do
described_class.new(File.read('spec/year_2015/day_14_sample_one'))
end

it 'gives a final result' do
expect(sample_one.to_i(1000)).to eq(689)
end
end

context 'when Results' do
subject(:input_data) do
File.read('spec/year_2015/day_14_input')
end

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

it 'correctly answers part 2' do
expect(described_class.new(input_data).to_i(2503)).to eq(1059)
end
end
end
15 changes: 15 additions & 0 deletions year_2015.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,3 +230,18 @@ Year2015::Day13
Again, refer to [Day 09][##day-09] because we are in a similar configuration, with the exception that we must rejoin our starting point at the end. Nothing too complicated.

Second part is just adding another node with a 0 relationship to all nodes. Surprisingly, it seems our presence lowered the general happiness...

## Day 14

```
Year2015::Day14
when Part 1
gives a final result
when Part 2
gives a final result
when Results
correctly answers part 1
correctly answers part 2
```

This day doesn't have complicated concepts. If you want to dig, you can think of each reindeer as a [finite-state machine](https://en.wikipedia.org/wiki/Finite-state_machine), which is [one of the concepts that are best solved thanks to Object-oriented programming](https://eev.ee/blog/2013/03/03/the-controller-pattern-is-awful-and-other-oo-heresy/).
62 changes: 62 additions & 0 deletions year_2015/day_14.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
class Year2015
class Day14
class Reindeer
attr_reader :name, :curpos
attr_accessor :points

def initialize(input_line)
input_line =~ /(\w+) can fly (\d+) km\/s for (\d+) seconds, but then must rest for (\d+) seconds./
@name = $1
@speed = $2.to_i
@length = $3.to_i
@rest = $4.to_i
@curpos = 0
@state = 'RUNNING'
@progress = 0
@points = 0
end

def switch_state(new_state)
@state = new_state
@progress = 0
end

def advance(kms = 1)
1.upto(kms) do
@progress += 1
if @state == 'RUNNING'
@curpos += @speed
switch_state('RESTING') if @progress == @length
elsif @progress == @rest
switch_state('RUNNING')
end
end
curpos
end
end

def initialize(input_data, input_part_one = false)
@input_file = input_data
@version = input_part_one ? 1 : 2
@reindeers = input_data.chomp.split("\n").map do |input_line|
Reindeer.new(input_line)
end
end

def simple_to_i(kms = 1)
@reindeers.map{|reindeer| reindeer.advance(kms) }.max
end

def to_i(kms = 1)
return simple_to_i(kms) if @version == 1

0.upto(kms) do
lead = @reindeers.map(&:advance).max
@reindeers.select{|reindeer| reindeer.curpos == lead }.each do |reindeer|
reindeer.points += 1
end
end
@reindeers.map(&:points).max
end
end
end

0 comments on commit 36bf5b2

Please sign in to comment.