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.
90 lines
1.7 KiB
90 lines
1.7 KiB
12 months ago
|
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
|