Skip to content

Commit

Permalink
Year 2016: Day 14
Browse files Browse the repository at this point in the history
  • Loading branch information
joshleaves committed Mar 10, 2024
1 parent 48a1561 commit 1cd5f1b
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ I'm also adding notes that may be useful if you're learning Ruby.

Notes for solving:
* [2015, complete](year_2015.md)
* [2016, up to day 13](year_2016.md)
* [2016, up to day 14](year_2016.md)
* [2023, up to day 04](year_2023.md)

# How to use
Expand Down
29 changes: 29 additions & 0 deletions spec/year_2016/day_14_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
require 'year_2016/day_14'

describe Year2016::Day14 do
context 'when Part 1' do
it 'gives a final result' do
expect(described_class.new('abc', true).to_i).to eq(22_728)
end
end

context 'when Part 2' do
it 'gives a final result', skip: 'Test is too slow for CI' do
expect(described_class.new('abc').to_i).to eq(22_551)
end
end

context 'when Results' do
subject(:input_data) do
'yjdafjpo'
end

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

it 'correctly answers part 2', skip: 'Test is too slow for CI' do
expect(described_class.new(input_data).to_i).to eq(22_045)
end
end
end
25 changes: 25 additions & 0 deletions year_2016.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,28 @@ Year2016::Day13
```

Thinking in terms of X and Y can be a source of pain, but this one was straight enough.

## Day 14: One-Time Pad

```
Year2016::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 one is even more annoying than [the last one](year_2016.md#day-05-how-about-a-nice-game-of-chess).

There is also a funny edge-case where your last key may look something like this:
```
abc22034 => Triple
abc22045 => Triple
...
abc-smth => Quintuple for abc22045
...
abc-smth => Quintuple for abc22034
```
56 changes: 56 additions & 0 deletions year_2016/day_14.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
require 'digest'

class Year2016
class Day14
def initialize(input_data, input_part_one = false)
@version = input_part_one ? 1 : 2
@input = input_data.chomp
end

def md5
@md5 ||= Digest::MD5.new
end

def hash(str)
md5.reset
md5 << str
return md5.hexdigest if @version == 1

digest = md5.hexdigest
1.upto(2016) do
md5.reset
md5 << digest
digest = md5.hexdigest
end
digest
end

def generate_hashes(starter, length)
0.upto(length).map{|cnt| hash("#{@input}#{starter + cnt}") }
end

# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
def to_i
cnt = -1
hash_queue = generate_hashes(0, 1000)
keys = []
loop do
cnt += 1
hash_queue.concat(generate_hashes(cnt, 1000)) if hash_queue.empty?
digest = hash_queue.shift
next unless digest =~ /(.)\1\1/

letter = $1
hash_queue.concat(generate_hashes(cnt + 1 + hash_queue.length, 1000 - hash_queue.length))
0.upto(999) do |idx|
next unless hash_queue[idx].include?(letter * 5)
return cnt if keys.length == 63

keys.push(digest)
break
end
end
end
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
end
end

0 comments on commit 1cd5f1b

Please sign in to comment.