1
1
LAYOUT = DATA . each_line . map { |row | row . strip . split '' }
2
2
3
- SLOPES = [ -1 , 0 , 1 ] . repeated_permutation ( 2 ) . reject { | d | d == [ 0 , 0 ] }
3
+ SLOPES = [ -1 , 0 , 1 ] . repeated_permutation ( 2 ) . to_a - [ [ 0 , 0 ] ]
4
4
5
5
ROWS = LAYOUT . size
6
6
COLS = LAYOUT [ 0 ] . size
7
+ SEATS = ( 0 ...ROWS ) . to_a . product ( ( 0 ...COLS ) . to_a ) . reject { |r , c | LAYOUT [ r ] [ c ] == ?. }
7
8
8
9
def in_layout? r , c
9
10
( 0 ...ROWS ) === r && ( 0 ...COLS ) === c
10
11
end
11
12
12
- def take_all_neighbors layout , r , c
13
+ def count_occupied min_no_of_occupied , &look_for_seats
14
+ layout = LAYOUT . clone . map &:clone
15
+ next_layout = nil
16
+
17
+ loop do
18
+ next_layout = layout . clone . map &:clone
19
+
20
+ SEATS . each do |r , c |
21
+ seat = layout [ r ] [ c ]
22
+ no_of_occupied = look_for_seats . call ( layout , r , c ) . count ?#
23
+
24
+ if seat == ?L && no_of_occupied . zero?
25
+ next_layout [ r ] [ c ] = ?#
26
+ elsif seat == ?# && no_of_occupied >= min_no_of_occupied
27
+ next_layout [ r ] [ c ] = ?L
28
+ end
29
+ end
30
+
31
+ break if layout == next_layout
32
+
33
+ layout . replace next_layout
34
+ end
35
+
36
+ layout . flatten . count ?#
37
+ end
38
+
39
+ occupied = count_occupied 4 do |layout , r , c |
13
40
SLOPES
14
41
. map { |dr , dc | [ r + dr , c + dc ] }
15
42
. filter_map { |r , c | layout [ r ] [ c ] if in_layout? r , c }
16
43
end
17
44
18
- def take_all_you_see layout , r , c
45
+ puts occupied # 2211
46
+
47
+
48
+ occupied = count_occupied 5 do |layout , r , c |
19
49
SLOPES . filter_map do |dr , dc |
20
50
( 1 ..)
21
51
. lazy
@@ -26,36 +56,7 @@ def take_all_you_see layout, r, c
26
56
end
27
57
end
28
58
29
- def count_occupied fn , min_no_of_occupied
30
- layout = LAYOUT . clone . map &:clone
31
- next_layout = nil
32
-
33
- loop do
34
- next_layout = LAYOUT . clone . map &:clone
35
-
36
- ( 0 ...ROWS ) . to_a . product ( ( 0 ...COLS ) . to_a ) . each do |r , c |
37
- cell = layout [ r ] [ c ]
38
-
39
- next_layout [ r ] [ c ] = case cell
40
- in "L" if fn . call ( layout , r , c ) . none? "#"
41
- "#"
42
- in "#" if fn . call ( layout , r , c ) . count ( "#" ) >= min_no_of_occupied
43
- "L"
44
- else
45
- layout [ r ] [ c ]
46
- end
47
- end
48
-
49
- break if layout == next_layout
50
-
51
- layout . replace next_layout
52
- end
53
-
54
- layout . flatten . count "#"
55
- end
56
-
57
- puts count_occupied ( method ( :take_all_neighbors ) , 4 ) # 2211
58
- puts count_occupied ( method ( :take_all_you_see ) , 5 ) # 1995
59
+ puts occupied # 1995
59
60
60
61
__END__
61
62
LLLLLLLL.LLLL.LLLLLLLLL.LLLLLL..L.LLLLL.LLLLL.LLLLLL.LLLLLLLLLLLLLL.LLLLLLLLLLLLLL.L.LLLLLLLLLL
0 commit comments