@@ -5,33 +5,14 @@ class Day14 < Day # >
5
5
# @example
6
6
# day.part1 #=> 136
7
7
def part1
8
- columns =
9
- input
10
- . split ( "\n " )
11
- . map ( &:chars )
12
- . transpose # pivot so that each array is a column
13
- . reject { |column | !column . include? ( "O" ) } # don't bother with columns that don't have rounded rocks
14
- . map ( &:join ) # make it a string again
15
- . map { |column |
16
- column
17
- . reverse # north is now towards the end of the string
18
- . split ( "#" , -1 ) # find the stretches between cube rocks, keep trailing empties
19
- . map { |substring |
20
- substring . chars . sort . join # roll rocks within stretches
21
- }
22
- . join ( "#" ) # put the cubes back in
23
-
24
- }
25
- . map { |rolled_column |
26
- ( 0 ..rolled_column . length )
27
- . filter_map { |i | i +1 if rolled_column [ i ] == "O" }
28
- . reduce ( &:+ )
29
- }
30
- . reduce ( &:+ )
8
+ Platform
9
+ . new ( input )
10
+ . tilt
11
+ . total_load_on_north_beams
31
12
end
32
13
33
- # example
34
- # day.part2 #=> 'how are you'
14
+ # example 1_000_000_000 cycles
15
+ # day.part2 #=> 64
35
16
def part2
36
17
end
37
18
@@ -47,4 +28,73 @@ def part2
47
28
#....###..
48
29
#OO..#....
49
30
INPUT
31
+
32
+ FIRST_TILT_NORTH = <<~TILT
33
+ OOOO.#.O..
34
+ OO..#....#
35
+ OO..O##..O
36
+ O..#.OO...
37
+ ........#.
38
+ ..#....#.#
39
+ ..O..#.O.O
40
+ ..O.......
41
+ #....###..
42
+ #....#....
43
+ TILT
44
+ end
45
+
46
+ class Platform
47
+ require_relative 'grid'
48
+ require 'matrix'
49
+
50
+ ROUNDED = "O"
51
+ CUBED = "#"
52
+ EMPTY = "."
53
+
54
+ attr_reader :rounded_rocks , :immovable_rocks , :grid
55
+
56
+ def initialize ( input )
57
+ @input = input
58
+ @grid = Grid . new ( input ) . parse
59
+ @rows_max = @grid . row_bounds . max
60
+ end
61
+
62
+ # @example
63
+ # p = new(Day14::EXAMPLE_INPUT)
64
+ # p.tilt
65
+ # p.to_s #=> Day14::FIRST_TILT_NORTH
66
+ def tilt
67
+ loop do
68
+ things_are_moving = false
69
+ rounded_rocks
70
+ . each do |coords , rock |
71
+ move_to = ( Vector [ *coords ] + Vector [ -1 , 0 ] ) . to_a
72
+ if grid . cover? ( move_to ) && grid . at ( move_to ) == EMPTY
73
+ grid . set ( move_to , ROUNDED )
74
+ grid . set ( coords , EMPTY )
75
+ things_are_moving = true
76
+ end
77
+ end
78
+ break unless things_are_moving
79
+ end
80
+ self
81
+ end
82
+
83
+ # @example
84
+ # new(Day14::EXAMPLE_INPUT).tilt.total_load_on_north_beams #=> 136
85
+ def total_load_on_north_beams
86
+ rounded_rocks
87
+ . map { |coords , _value | @rows_max - coords [ 0 ] + 1 }
88
+ . reduce ( &:+ )
89
+ end
90
+
91
+ def rounded_rocks
92
+ grid . select { |_coords , value | value == ROUNDED }
93
+ end
94
+
95
+ # @example
96
+ # new(Day14::EXAMPLE_INPUT).to_s #=> Day14::EXAMPLE_INPUT
97
+ def to_s
98
+ grid . to_s
99
+ end
50
100
end
0 commit comments