From 31afd41329aee6a64ae0392916b7a1f61b50a795 Mon Sep 17 00:00:00 2001 From: Alpha Chen Date: Tue, 12 Dec 2023 21:35:22 -0800 Subject: [PATCH] [2023][ruby][12.2] --- 2023/ruby/day_12.rb | 80 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 68 insertions(+), 12 deletions(-) diff --git a/2023/ruby/day_12.rb b/2023/ruby/day_12.rb index 97cfc1d..ddc6494 100644 --- a/2023/ruby/day_12.rb +++ b/2023/ruby/day_12.rb @@ -1,14 +1,70 @@ -p ARGF.readlines(chomp: true).map {|row| +input = ARGF.readlines(chomp: true).map {|row| springs, groups = row.split(" ") [springs, groups.scan(/\d+/).map(&:to_i)] -}.map {|springs, groups| - unknowns = springs.count(??) - (0...2**unknowns).map {|arrangement| - arrangement = arrangement.to_s(2).rjust(unknowns, ?0).chars.map { _1 == ?0 ? ?. : ?# } - candidate = springs.gsub(??) { arrangement.shift } - candidate.chars - .slice_when { _1 != _2 } - .reject { _1[0] == ?. } - .map(&:size) == groups - }.count(&:itself) -}.sum +} + +p input + # .map { [ _1.chars, _2 ] } + .map { [Array.new(5, _1).join(??).chars, _2 * 5] } + .map {|springs, groups| + arrangement_counts = Hash.new {|h,k| + count, springs, groups = k + first, *rest = springs + h[k] = case [count, first, groups] + in count, _, [] + if count.nonzero? + 0 + elsif springs.include?(?#) + 0 + else + 1 + end + in count, _, groups if count > groups.fetch(0) + 0 # early exit if the damaged group ever gets too large + in count, nil, groups # no more springs + if groups.size > 1 + 0 + elsif count == groups.fetch(0) + 1 + else + 0 + end + in count, ?#, groups # continue a damaged group + h[[count + 1, rest, groups]] + in 0, ?., groups + h[[0, rest, groups]] + in count, ?., groups # finish a damaged group + if count == groups.fetch(0) + h[[0, rest, groups[1..]]] + else + 0 + end + in count, ??, g if count == g.fetch(0) # unknown spring, matched current group + h[[0, rest, g[1..]]] + in count, ??, g unless count.zero? # unknown spring, ongoing group + h[[count + 1, rest, g]] + in count, ??, g # unknown spring + [ + h[[count, rest, g]], # undamaged + h[[count + 1, rest, g]], # damaged + ].sum + else + fail "#{{first:, springs: springs.join, groups:}}" + end + } + arrangement_counts[[0, springs, groups]] + }.sum + +# original part one +# p input.map {|springs, groups| +# unknowns = springs.count(??) +# (0...2**unknowns).map {|arrangement| +# arrangement = arrangement.to_s(2).rjust(unknowns, ?0).chars.map { _1 == ?0 ? ?. : ?# } +# candidate = springs.gsub(??) { arrangement.shift } +# candidate.chars +# .slice_when { _1 != _2 } +# .reject { _1[0] == ?. } +# .map(&:size) == groups +# }.count(&:itself) +# }.sum +