From 92e8bab4ad3c2dae7bd343c62bc6157c9d76cfe7 Mon Sep 17 00:00:00 2001 From: didier amyot Date: Mon, 4 Dec 2023 11:32:22 -0500 Subject: [PATCH] implemented day 3 part 2. --- src/advent/day3.rb | 58 +++++++++++++++++++++++++++++++++++++++++ src/advent/day3_test.rb | 17 ++++++++++++ 2 files changed, 75 insertions(+) diff --git a/src/advent/day3.rb b/src/advent/day3.rb index 4e86af7..832df4b 100644 --- a/src/advent/day3.rb +++ b/src/advent/day3.rb @@ -16,6 +16,26 @@ def group_neighbour(lst, &block) ret end +class Gear + def initialize(line_index, column_index) + @line_index = line_index + @column_index = column_index + end + + def get_neighbourhood + ret = [] + (-1..1).each do |line_delta| + (-1..1).each do |col_delta| + ret.append({ line_index: @line_index + line_delta, column_index: @column_index + col_delta}) + end + end + ret + end + + attr_accessor :line_index + attr_accessor :column_index +end + class EngineNumber def initialize(line_index, start, end_, value) @line_index = line_index @@ -24,6 +44,10 @@ class EngineNumber @value = value end + def is_located_on(line_index, column_index) + line_index == @line_index and ( @start <= column_index and column_index < @end_) + end + attr_accessor :line_index attr_accessor :start @@ -77,6 +101,16 @@ class EngineLine group_digit_indexes(digit_indexes).map &method(:create_engine_number) end + def extract_gears + ret = [] + @line.split("").each_with_index do |letter, index| + if letter == "*" + ret.append Gear.new @idx, index + end + end + ret + end + end class Engine @@ -123,6 +157,29 @@ class Engine extract_engine_numbers.filter {|engine_number| touches_symbol? engine_number} end + def is_adjacent(engine_number, gear) + gear.get_neighbourhood + .map {|point| engine_number.is_located_on(point[:line_index], point[:column_index])} + .any? + end + + def get_adjacent_number_parts(gear) + extract_engine_numbers + .filter {|eg| is_adjacent(eg, gear)} + end + + def extract_gears + @engine_lines + .map {|line| line.extract_gears} + .flatten + end + + def get_gear_ratios + extract_gears + .map {|gear| get_adjacent_number_parts(gear)} + .filter {|adjacent_numbers| adjacent_numbers.length == 2} + .map {|adjacent_numbers| adjacent_numbers.map {|a| a.value} .reduce(1, :*)} + end attr_accessor :engine_lines end @@ -134,4 +191,5 @@ input_content = File.open(input_file_name).read engine = Engine.deserialize input_content puts engine.extract_engine_numbers_that_touches_symbols.map {|e| e.value} .sum +puts engine.get_gear_ratios.sum diff --git a/src/advent/day3_test.rb b/src/advent/day3_test.rb index c0d9689..ac471d7 100644 --- a/src/advent/day3_test.rb +++ b/src/advent/day3_test.rb @@ -31,6 +31,8 @@ class Day3Test < Test::Unit::TestCase assert_equal "hello"[4..10], "o" + assert_true 0 <= 10 and 10 < 100 + end @@ -102,4 +104,19 @@ class EngineLineTest < Test::Unit::TestCase assert_equal expt, engine.extract_engine_numbers_that_touches_symbols.map {|e| e.value} .sum end + def test_extract_gears + engine = Engine.deserialize @@easy_engine + assert_equal 3, engine.extract_gears.length + end + + def test_get_gear_ratios + engine = Engine.deserialize @@easy_engine + assert_equal [16345, 451490], engine.get_gear_ratios + end + + def test_day_3_part_2_easy + engine = Engine.deserialize @@easy_engine + assert_equal 467835, engine.get_gear_ratios.sum + end + end \ No newline at end of file