You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
advent-of-code/2023/ruby/day_18.rb

94 lines
2.2 KiB

12 months ago
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