diff day3.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/day3.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(: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}