From bc22dc65c144ea1cb865aaffc2d9bac8df94491c Mon Sep 17 00:00:00 2001 From: red Date: Wed, 13 Mar 2024 04:59:56 +0100 Subject: [PATCH] Year 2016: Day 19 --- README.md | 2 +- spec/year_2016/day_19_input | 1 + spec/year_2016/day_19_spec.rb | 29 +++++++++++++++++++++++++++++ year_2016.md | 17 +++++++++++++++++ year_2016/day_19.rb | 30 ++++++++++++++++++++++++++++++ 5 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 spec/year_2016/day_19_input create mode 100644 spec/year_2016/day_19_spec.rb create mode 100644 year_2016/day_19.rb diff --git a/README.md b/README.md index 17c81ed..9267dce 100644 --- a/README.md +++ b/README.md @@ -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 18](year_2016.md) +* [2016, up to day 19](year_2016.md) * [2023, up to day 04](year_2023.md) # How to use diff --git a/spec/year_2016/day_19_input b/spec/year_2016/day_19_input new file mode 100644 index 0000000..a452141 --- /dev/null +++ b/spec/year_2016/day_19_input @@ -0,0 +1 @@ +3012210 \ No newline at end of file diff --git a/spec/year_2016/day_19_spec.rb b/spec/year_2016/day_19_spec.rb new file mode 100644 index 0000000..83043f3 --- /dev/null +++ b/spec/year_2016/day_19_spec.rb @@ -0,0 +1,29 @@ +require 'year_2016/day_19' + +describe Year2016::Day19 do + context 'when Part 1' do + it 'gives a final result' do + expect(described_class.new('5', true).solve).to eq(3) + end + end + + context 'when Part 2' do + it 'gives a final result' do + expect(described_class.new('5').solve).to eq(2) + end + end + + context 'when Results' do + subject(:input_data) do + File.read('spec/year_2016/day_19_input') + end + + it 'correctly answers part 1' do + expect(described_class.new(input_data, true).solve).to eq(1_830_117) + end + + it 'correctly answers part 2' do + expect(described_class.new(input_data).solve).to eq(1_417_887) + end + end +end diff --git a/year_2016.md b/year_2016.md index 4024898..6ac28ae 100644 --- a/year_2016.md +++ b/year_2016.md @@ -260,3 +260,20 @@ Very funny exercise. For testing purpose, the first version generated each strin The second version took...around 20 seconds for 400K lines, which was sub-optimal. One thing you should always strive to do is not just *read the rules*, but *understand* them. In this case, the four rules for a trap can be summed up as: "different left and right will produce a trap". + +## Day 19: An Elephant Named Joseph + +``` +Year2016::Day19 + when Part 1 + gives a final result + when Part 2 + gives a final result + when Results + correctly answers part 1 + correctly answers part 2 +``` + +Oftentimes, the real answer to an exercise is all about understanding the math problem hidden behind. In this case, it's [Josephus Problem](https://en.wikipedia.org/wiki/Josephus_problem#Bitwise) (for the first part at least), and the answer is ridiculously simple. + +For the second part, treating the elves as two sets with one stealing from the other makes the most sense, however, if you were to look at the first hundred results, you'd notice [an interesting pattern emerging](https://github.com/rHermes/adventofcode/blob/master/2016/19/y2016_d19_p02.py). diff --git a/year_2016/day_19.rb b/year_2016/day_19.rb new file mode 100644 index 0000000..08b8e37 --- /dev/null +++ b/year_2016/day_19.rb @@ -0,0 +1,30 @@ +class Year2016 + class Day19 + def initialize(input_data, input_part_one = false) + @version = input_part_one ? 1 : 2 + @input = input_data.chomp.to_i + end + + # rubocop:disable Metrics/AbcSize, Metrics/MethodLength + def solve + return @input.to_s(2).chars.rotate(1).join.to_i(2) if @version == 1 + + # Nice trick from https://pastebin.com/Zm7tLbAe + mid = (@input + 1.0) / 2 + arr_v1 = Array.new(mid.floor - 1){|i| i + 1 } + arr_v2 = Array.new(mid.ceil.to_i){|i| mid + i } + + loop do + if arr_v2.length >= arr_v1.length + arr_v2.shift + return arr_v1.first if arr_v2.empty? + else + arr_v1.pop + end + arr_v1.push(arr_v2.shift) + arr_v2.push(arr_v1.shift) + end + end + # rubocop:enable Metrics/AbcSize, Metrics/MethodLength + end +end