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/2022/ruby/day_17.rb

90 lines
1.7 KiB

require "set"
rocks = <<~ROCKS.split("\n\n")
####
.#.
###
.#.
..#
..#
###
#
#
#
#
##
##
ROCKS
rocks = rocks
.map {|rock| rock.lines(chomp: true).reverse.map(&:chars) }
.map {|rock|
rock.each.with_index.with_object(Set.new) {|(row, y), rocks|
row.each.with_index do |c, x|
rocks << [x, y] if c == ?#
end
}
}
rocks = rocks.cycle
jet_pattern = ARGF.read.strip.chars
jet_pattern = jet_pattern.cycle
chamber = Hash.new {|_,(x,y)| !(0...7).cover?(x) || y.negative? }
def move_rock(chamber, rock, dx, dy)
next_rock = rock.map {|x,y| [x+dx, y+dy] }
if next_rock.any? {|x,y| chamber[[x, y]] }
rock
else
next_rock
end
end
def debug(chamber, rock)
max_y = [chamber.keys.map(&:last).max || 0, rock.map(&:last).max || 0].max
puts
puts max_y.downto(0).map {|y|
(0...7).map {|x|
(chamber[[x,y]] || rock.include?([x,y])) ? ?# : ?.
}.join
}.join("\n")
end
2022.times do
rock = rocks.next
y = chamber.empty? ? 3 : chamber.keys.map(&:last).max + 4
x = 2
rock = move_rock(chamber, rock, x, y)
loop do
rock = case jet = jet_pattern.next
when ?< then move_rock(chamber, rock, -1, 0)
when ?> then move_rock(chamber, rock, 1, 0)
else fail "invalid jet pattern: #{jet}"
end
next_rock = move_rock(chamber, rock, 0, -1)
break if rock == next_rock
rock = next_rock
end
chamber.merge!(rock.to_h { [_1, true] })
end
# debug(chamber, Set.new)
max_y = chamber.keys.map(&:last).max + 1
p max_y
candidates = (0..max_y).select {|y| (0...7).count {|x| chamber[[x,y]] } == 6 }
# max_delta = candidates.each_cons(2).map { _2 - _1 }.max
candidates.
p candidates
p max_delta