implemented day 3 part 1.
This commit is contained in:
1 parent
4ddb2bc807
commit
6d36e67a24
4 files changed
+384
No files matched your search
@@ -0,0 +1,137 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
def group_neighbour(lst, &block)
|
||||
if lst.empty?
|
||||
return []
|
||||
end
|
||||
ret = [[lst[0]]]
|
||||
lst.each_cons(2) do |first_and_second|
|
||||
first, second = first_and_second
|
||||
if block.call first, second
|
||||
ret[-1].append second
|
||||
else
|
||||
ret.append [second]
|
||||
end
|
||||
end
|
||||
ret
|
||||
end
|
||||
|
||||
class EngineNumber
|
||||
def initialize(line_index, start, end_, value)
|
||||
@line_index = line_index
|
||||
@start = start
|
||||
@end_ = end_
|
||||
@value = value
|
||||
end
|
||||
|
||||
|
||||
attr_accessor :line_index
|
||||
attr_accessor :start
|
||||
attr_accessor :end_
|
||||
attr_accessor :value
|
||||
|
||||
end
|
||||
|
||||
class EngineLine
|
||||
def initialize(idx, line)
|
||||
@idx = idx
|
||||
@line = line
|
||||
end
|
||||
|
||||
def is_symbols?(letter)
|
||||
unless letter
|
||||
return false
|
||||
end
|
||||
"1234567890.".index(letter) == nil
|
||||
end
|
||||
|
||||
def has_any_symbols_at(indexes)
|
||||
indexes.any? do |idx|
|
||||
is_symbols? @line[idx]
|
||||
end
|
||||
end
|
||||
|
||||
def extract_digit_indexes(word)
|
||||
digit_indexes = []
|
||||
word.split("").each_with_index do |letter, index|
|
||||
if "0123456789".index letter
|
||||
digit_indexes.append index
|
||||
end
|
||||
end
|
||||
digit_indexes
|
||||
end
|
||||
|
||||
def group_digit_indexes(digit_indexes)
|
||||
group_neighbour(digit_indexes) {|x, y| y == x + 1}
|
||||
end
|
||||
|
||||
def create_engine_number(digit_group)
|
||||
start = digit_group.min
|
||||
end_ = 1 + digit_group.max
|
||||
value = @line[start...end_].to_i
|
||||
EngineNumber.new @idx, start, end_, value
|
||||
end
|
||||
|
||||
def extract_engine_numbers
|
||||
digit_indexes = extract_digit_indexes @line
|
||||
group_digit_indexes(digit_indexes).map &method(:create_engine_number)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Engine
|
||||
def initialize(engine_lines)
|
||||
@engine_lines = engine_lines
|
||||
end
|
||||
|
||||
def self.deserialize(ser)
|
||||
els = ser.strip.split("\n").each_with_index.map { |line, idx| EngineLine.new idx, line}
|
||||
return self.new els
|
||||
end
|
||||
|
||||
def extract_engine_numbers
|
||||
@engine_lines
|
||||
.map {|line| line.extract_engine_numbers}
|
||||
.flatten
|
||||
end
|
||||
|
||||
def has_symbol?(line_index, indexes_in_line)
|
||||
# indexes_in_line = indexes_in_line || []
|
||||
# puts "> #{ indexes_in_line }"
|
||||
@engine_lines[line_index]&.has_any_symbols_at indexes_in_line
|
||||
end
|
||||
|
||||
def get_engine_number_neighbourhood(engine_number)
|
||||
line_index = engine_number.line_index
|
||||
[
|
||||
{line_index: line_index, indexes_in_line: ((engine_number.start-1)..(engine_number.start-1))},
|
||||
{line_index: line_index, indexes_in_line: ((engine_number.end_)..(engine_number.end_))},
|
||||
{line_index: line_index - 1 , indexes_in_line: ((engine_number.start - 1)...(engine_number.end_+1))},
|
||||
{line_index: line_index + 1 , indexes_in_line: ((engine_number.start - 1)...(engine_number.end_+1))},
|
||||
]
|
||||
|
||||
end
|
||||
|
||||
def touches_symbol?(engine_number)
|
||||
get_engine_number_neighbourhood(engine_number).map do |h|
|
||||
has_symbol?(h[:line_index], h[:indexes_in_line])
|
||||
end
|
||||
.any?
|
||||
end
|
||||
|
||||
def extract_engine_numbers_that_touches_symbols
|
||||
extract_engine_numbers.filter {|engine_number| touches_symbol? engine_number}
|
||||
end
|
||||
|
||||
attr_accessor :engine_lines
|
||||
end
|
||||
|
||||
|
||||
input_file_name = File.join(File.dirname(__FILE__), "day_3_input.txt")
|
||||
|
||||
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
|
||||
|
||||
Reference in new issue
Block a user