diff --git a/2023/ruby/day_02.rb b/2023/ruby/day_02.rb
index f93657e..815bc52 100644
--- a/2023/ruby/day_02.rb
+++ b/2023/ruby/day_02.rb
@@ -1,13 +1,13 @@
input = ARGF.read
-def cubes(input)
+def parse_cubes(input)
input
.scan(/(\d+) (\w+)/)
.to_h(&:reverse)
.transform_values(&:to_i)
end
-bag = cubes("12 red cubes, 13 green cubes, and 14 blue cubes")
+bag = parse_cubes("12 red cubes, 13 green cubes, and 14 blue cubes")
Game = Data.define(:id, :reveals) do
def possible?(bag)
@@ -22,7 +22,7 @@ games = input
.map {|id, reveals|
Game.new(
id.to_i,
- reveals.split(?;).map { cubes(_1) }
+ reveals.split(?;).map { parse_cubes(_1) }
)
}
diff --git a/2023/ruby/day_03.rb b/2023/ruby/day_03.rb
new file mode 100644
index 0000000..7812d42
--- /dev/null
+++ b/2023/ruby/day_03.rb
@@ -0,0 +1,43 @@
+cur_num = nil
+nums = {}
+syms = {}
+ARGF.readlines(chomp: true).each.with_index do |row, y|
+ row.chars.each.with_index do |c, x|
+ case c
+ when /\d/
+ if cur_num
+ cur_num << c
+ else
+ cur_num = c
+ end
+ else
+ if cur_num
+ nums[[y,x-cur_num.length]] = cur_num.to_i
+ cur_num = nil
+ end
+
+ if c != ?.
+ syms[[y,x]] = c
+ end
+ end
+ end
+
+ if cur_num
+ nums[[y, row.length-cur_num.length]] = cur_num.to_i
+ cur_num = nil
+ end
+end
+
+p nums
+ .filter_map {|(y,x), num|
+ dy = (-1..1).to_a
+ dx = (-1..num.digits.length).to_a
+ if dy.product(dx)
+ .map {|dy,dx| [y+dy,x+dx] }
+ .any? { syms.has_key?(_1) }
+ num
+ else
+ nil
+ end
+ }
+ .sum