1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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