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