From 48a15611a0cf113d3c07ab764440bcb0134bb586 Mon Sep 17 00:00:00 2001 From: red Date: Sun, 10 Mar 2024 01:00:13 +0100 Subject: [PATCH] Year 2016: Day 13 --- README.md | 2 +- spec/year_2016/day_13_spec.rb | 23 +++++++++++++ year_2016.md | 13 ++++++++ year_2016/day_13.rb | 61 +++++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 spec/year_2016/day_13_spec.rb create mode 100644 year_2016/day_13.rb diff --git a/README.md b/README.md index d22c9cd..f69af86 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 12](year_2016.md) +* [2016, up to day 13](year_2016.md) * [2023, up to day 04](year_2023.md) # How to use diff --git a/spec/year_2016/day_13_spec.rb b/spec/year_2016/day_13_spec.rb new file mode 100644 index 0000000..1b2bd7f --- /dev/null +++ b/spec/year_2016/day_13_spec.rb @@ -0,0 +1,23 @@ +require 'year_2016/day_13' + +describe Year2016::Day13 do + context 'when Part 1' do + subject(:sample_one) do + described_class.new(10, 7, 4, true) + end + + it 'gives a final result' do + expect(sample_one.to_i).to eq(11) + end + end + + context 'when Results' do + it 'correctly answers part 1' do + expect(described_class.new(1_352, 31, 39, true).to_i).to eq(90) + end + + it 'correctly answers part 2' do + expect(described_class.new(1_352, 31, 39).to_i).to eq(135) + end + end +end diff --git a/year_2016.md b/year_2016.md index 9ac252f..5928184 100644 --- a/year_2016.md +++ b/year_2016.md @@ -174,3 +174,16 @@ Year2016::Day12 ``` After yesterday's mess, building a [virtual machine](https://en.wikipedia.org/wiki/Virtual_machine) is a delight. Nothing specific, refer to [Year 2015, Day 23](year_2015.md#day-23-opening-the-turing-lock) for more info. + +## Day 13: A Maze of Twisty Little Cubicles + +``` +Year2016::Day13 + when Part 1 + gives a final result + when Results + correctly answers part 1 + correctly answers part 2 +``` + +Thinking in terms of X and Y can be a source of pain, but this one was straight enough. diff --git a/year_2016/day_13.rb b/year_2016/day_13.rb new file mode 100644 index 0000000..d142868 --- /dev/null +++ b/year_2016/day_13.rb @@ -0,0 +1,61 @@ +class Year2016 + class Day13 + class << self + def next_moves(state) + [ + [state[0] - 1, state[1]], + [state[0] + 1, state[1]], + [state[0], state[1] - 1], + [state[0], state[1] + 1] + ].reject do |x, y| + x.negative? || y.negative? + end + end + end + + def initialize(input_favorite, input_x, input_y, input_part_one = false) + @version = input_part_one ? 1 : 2 + @favorite = input_favorite + @reach_x = input_x + @reach_y = input_y + end + + def cell_value(pos_x, pos_y) + [ + (pos_x * pos_x), + (3 * pos_x), + (2 * pos_x * pos_y), + pos_y, + (pos_y * pos_y) + ].sum + end + + def cell_is_a_wall?(pos) + (cell_value(pos[0], pos[1]) + @favorite).to_s(2).chars.count('1').odd? + end + + # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity + def search(states, moves_tried, moves) + return moves if @version == 1 && states.any?([@reach_x, @reach_y]) + return moves_tried.count{|pos| !cell_is_a_wall?(pos) } if @version == 2 && moves == 51 + + next_states = [] + states.each do |state| + next if moves_tried.include?(state) + + moves_tried.add(state) + next if cell_is_a_wall?(state) + + Day13.next_moves(state).each do |next_state| + next_states.push(next_state) unless moves_tried.include?(next_state) + end + end + search(next_states, moves_tried, moves + 1) + end + # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity + + def to_i + search([[1, 1]], Set.new, 0) + end + end +end