From 06068a3114399870b85a7555d0add9d29eed3c21 Mon Sep 17 00:00:00 2001 From: Alpha Chen Date: Wed, 13 Dec 2023 09:09:39 -0800 Subject: [PATCH] [2023][ruby][13.2] --- 2023/ruby/day_13.rb | 85 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 75 insertions(+), 10 deletions(-) diff --git a/2023/ruby/day_13.rb b/2023/ruby/day_13.rb index 7a90360..093da3e 100644 --- a/2023/ruby/day_13.rb +++ b/2023/ruby/day_13.rb @@ -1,14 +1,79 @@ -patterns = ARGF.read.split("\n\n") - .map { _1.split("\n").map(&:chars) } - -def find_fold(pattern) - (0.5...pattern.length-0.5).step(1).find {|fold| +def reflection_points(pattern) + (0.5...pattern.length-0.5).step(1).filter_map {|fold| a = pattern[0..fold.floor] b = pattern[fold.ceil..] - a.reverse.zip(b).reject { _1.any?(&:nil?) }.all? { _1 == _2 } - }&.ceil + if a.reverse.zip(b).reject { _1.any?(&:nil?) }.all? { _1 == _2 } + fold + else + nil + end + }.map(&:ceil) end -verts = patterns.map { find_fold(_1.transpose) }.compact -hors = patterns.map { find_fold(_1) }.compact -p verts.sum + hors.sum { _1 * 100 } +Pattern = Data.define(:pattern) do + def reflection_axes + ary = to_a + reflection_points(ary).map { [:y, _1] } + reflection_points(ary.transpose).map { [:x, _1] } + end + + def smudges + return enum_for(__method__) unless block_given? + + max_y, max_x = extents + (0..max_y).each do |y| + (0..max_x).each do |x| + smudged = case pattern[[y,x]] + when ?# then ?. + when ?. then ?# + else fail + end + yield Pattern.new(pattern.merge({[y,x] => smudged})) + end + end + end + + def to_a + max_y, max_x = extents + (0..max_y).map {|y| + (0..max_x).map {|x| + pattern.fetch([y,x]) + } + } + end + + def to_s + to_a.map(&:join).join("\n") + end + + def extents + max_y = pattern.keys.map(&:first).max + max_x = pattern.keys.map(&:last).max + [max_y, max_x] + end +end + +patterns = ARGF.read.strip.split("\n\n") + .map {|pattern| + pattern.split("\n").map(&:chars) + .each.with_index.inject({}) {|h, (row, y)| + h.merge(row.each.with_index.to_h {|elem,x| [[y,x], elem]}) + } + }.map { Pattern.new(_1) } + +# part one +x, y = patterns.map { _1.reflection_axes.fetch(0) } + .partition {|axis,_| axis == :x } + .map { _1.map(&:last) } # keep index (discard axis) +p x.sum + y.sum { _1 * 100 } + +# part two + +x, y = patterns.map {|pattern| + original_reflection_axis = pattern.reflection_axes.fetch(0) + pattern.smudges.lazy + .flat_map { _1.reflection_axes} + .reject { _1 == original_reflection_axis } + .first +}.partition {|axis,_| axis == :x } + .map { _1.map(&:last) } # keep index (discard axis) +p x.sum + y.sum { _1 * 100 }