Mercurial > repos > other > adventofcode2023
diff day3b.rb @ 2:0f4991eca11a
Implement day 3
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Sun, 03 Dec 2023 16:07:25 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/day3b.rb Sun Dec 03 16:07:25 2023 +0000 @@ -0,0 +1,59 @@ +#! /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(:value, :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(val[0], 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 symbol_pos.filter {|sym| sym.value == "*"}.map {|sym| number_pos.filter {|num| num.positions.any? {|num_pos| adjacent(num_pos, sym.position)}}}.filter {|nums| nums.length == 2}.map {|val| val.reduce(1) {|v, k| v * k.value}}.reduce(:+) \ No newline at end of file