Mercurial > repos > other > adventofcode2023
view day3.rb @ 5:a14f6eca67db
Record day5 part 2 instructions
The ranges aren't going to be consistent, so it'll need lots
more processing. Move on to day 6 and come back later.
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Wed, 06 Dec 2023 20:05:05 +0000 |
parents | 0f4991eca11a |
children |
line wrap: on
line source
#! /usr/bin/env ruby if ARGV.length != 1 abort("Incorrect arguments - needs input file") elsif not File.exist? (ARGV[0]) abort("File #{ARGV[0]} did not exist") end file = ARGV[0] number_chars = *('0'..'9') skip_chars = ['.'] numbers = Hash.new symbols = Array.new Position = Struct.new(:x, :y) NumberValue = Struct.new(:value, :positions) SymbolValue = Struct.new(:position) def create_number_position(vals) number = vals.reduce("") {|m, v| m + v[0]}.to_i positions = vals.map {|v| Position.new(v[1], v[2])} NumberValue.new(number, positions) end def adjacent(a, b) (a.x - b.x).abs <= 1 and (a.y - b.y).abs <= 1 end sum = 0 positions = File.open(file, "r").each_line(chomp: true).with_index.map do |line, index| numbers = line.each_char.with_index.map {|c, i| if number_chars.include? c or !skip_chars.include? c then [c, index, i] end }\ .filter {|v| v != nil }\ .reduce([[], []]) do |memo, val| if number_chars.include? val[0] then if memo[1].last and memo[1].last[2] + 1 != val[2] then memo[0] << create_number_position(memo[1]) memo[1] = [] end memo[1] << val else if memo[1] != [] then memo[0] << create_number_position(memo[1]) memo[1] = [] end memo[0] << SymbolValue.new(Position.new(val[1], val[2])) end memo end if numbers[1] != [] then numbers[0] << create_number_position(numbers[1]) end numbers[0] end.flatten.group_by {|elem| elem.class} symbol_pos = positions[SymbolValue] number_pos = positions[NumberValue] puts number_pos.filter {|num| num.positions.any? {|num_pos| symbol_pos.any? { |sym_pos| adjacent(num_pos, sym_pos.position) } } }.sum {|v|v.value}