diff --git a/2023/ruby/day_18.rb b/2023/ruby/day_18.rb new file mode 100644 index 0000000..6351c65 --- /dev/null +++ b/2023/ruby/day_18.rb @@ -0,0 +1,93 @@ +require "matrix" + +# part one +plan = ARGF.read.scan(/([UDLR])\s+(\d+)\s+\(#(\w+)\)/) + .map { [_1.to_sym, _2.to_i, _3] } + +# part two +plan = plan.map { _3.chars }.map {|hex| + dist = hex[0..4].join.to_i(16) + dir = "RDLU".chars.fetch(hex.last.to_i).to_sym + [dir, dist] +} + +deltas = { U: [-1,0], D: [1,0], L: [0,-1], R: [0,1] } + +points = plan.inject([[0,0]]) {|points, (dir, dist, _)| + delta = deltas.fetch(dir).map { _1*dist } + next_point = points.last.zip(delta).map { _1 + _2 } + points << next_point +} + +p [ + (0.5 * points.each_cons(2).sum { Matrix.columns(_1).determinant }.abs).to_i, + plan.select {|dir,_,_| %i[ D L ].include?(dir) }.sum { _2 }, + 1, +].sum + +# trench = plan.inject([[0,0]]) {|trench, (dir, dist, _)| +# delta = deltas.fetch(dir) +# dist.times do +# trench << trench.last.zip(delta).map { _1 + _2 } +# end +# trench +# }.uniq + +# y_range = Range.new(*trench.map(&:first).minmax) +# x_range = Range.new(*trench.map(&:last).minmax) + +# y_range.each do |y| +# x_range.each do |x| +# print trench.include?([y,x]) ? ?# : ?. +# end +# puts +# end + +# part one +# lagoon = trench.to_set + +# seed = [1, x_range.find {|x| lagoon.include?([0,x]) } + 1] +# frontier = [seed] +# until frontier.empty? +# current = frontier.shift +# lagoon << current + +# frontier.concat( +# [[-1,0],[1,0],[0,-1],[0,1]].map {|delta| +# current.zip(delta).map { _1 + _2 } +# }.reject { lagoon.include?(_1) || frontier.include?(_1) } +# ) +# end + +# p lagoon.size + +# row_counts = {} + +# count = trench.size +# y_range.each do |y| +# inside = nil + +# segments = trench.select {|y_,_| y_ == y }.map(&:last).sort.slice_when { _1+1 != _2 } +# if row_count = row_counts[segments] +# count += row_count +# next +# end + +# row_count = 0 +# segments.each do |segment| +# if [-1,1].all? {|dy| [[y+dy,segment[0]],[y+dy,segment[-1]]].any? { trench.include?(_1) }} +# if inside +# row_count += segment[0] - inside +# inside = nil +# else +# inside = segment[-1] + 1 +# end +# elsif inside +# row_count += segment[0] - inside +# inside = segment[-1] + 1 +# end +# end +# row_counts[segments] = row_count +# count += row_count +# end +# p count