Skip to content

Commit b59e82d

Browse files
author
Robb Kidd
committed
Day 14, part 1 - but managing state in a Hash
Also, Vectors. Trying out vector math instead of all this array zip-map-reducing to apply grid movements. Really should have considered that earlier.
1 parent a478e33 commit b59e82d

File tree

3 files changed

+78
-25
lines changed

3 files changed

+78
-25
lines changed

2023/ruby/Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ gem "yard-doctest"
1010
gem "rspec"
1111
gem "priority_queue_cxx"
1212
gem "benchmark-ips"
13+
gem "matrix"
1314

1415
gem "debug"
1516
gem "ruby-lsp", "~> 0.3.7", group: :development

2023/ruby/Gemfile.lock

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ GEM
1212
rdoc
1313
reline (>= 0.3.8)
1414
language_server-protocol (3.17.0.3)
15+
matrix (0.4.2)
1516
method_source (1.0.0)
1617
minitest (5.20.0)
1718
prettier_print (1.2.1)
@@ -58,6 +59,7 @@ PLATFORMS
5859
DEPENDENCIES
5960
benchmark-ips
6061
debug
62+
matrix
6163
priority_queue_cxx
6264
pry
6365
rake

2023/ruby/day14.rb

Lines changed: 75 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,14 @@ class Day14 < Day # >
55
# @example
66
# day.part1 #=> 136
77
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
3112
end
3213

33-
# example
34-
# day.part2 #=> 'how are you'
14+
# example 1_000_000_000 cycles
15+
# day.part2 #=> 64
3516
def part2
3617
end
3718

@@ -47,4 +28,73 @@ def part2
4728
#....###..
4829
#OO..#....
4930
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
50100
end

0 commit comments

Comments
 (0)