/
day_3.rb
82 lines (68 loc) · 1.92 KB
/
day_3.rb
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
class Claim
attr_reader :id, :pos_from_left, :pos_from_top, :width, :height, :occupied_coordinates
def initialize(claim)
parsed = /^#(\d+) @ (\d+),(\d+): (\d+)x(\d+)$/.match(claim)
@id = parsed[1]
@pos_from_left = parsed[2].to_i
@pos_from_top = parsed[3].to_i
@width = parsed[4].to_i
@height = parsed[5].to_i
end
def occupied_coordinates
@occupied_coordinates ||= begin
coordinates = {}
starting_x = pos_from_left + 1
ending_x = pos_from_left + width
starting_y = pos_from_top + 1
ending_y = pos_from_top + height
(starting_x..ending_x).each do |x|
(starting_y..ending_y).each do |y|
coordinates["(#{x},#{y})"] = 1
end
end
coordinates
end
end
def uncontested_coordinates(contested_coordinates)
occupied_coordinates.dup.delete_if { |k, v| contested_coordinates.include?(k) }
end
end
class Grid
attr_reader :occupied_coordinates, :contested_coordinates
attr_accessor :claims
def initialize(claims = [])
@claims = claims
end
def add_claims(claims)
@claims += Array(claims)
end
def occupied_coordinates
@occupied_coordinates ||= begin
coordinates = Hash.new(0)
@claims.each do |claim|
coordinates.merge!(claim.occupied_coordinates) { |key, v1, v2| v1 + v2 }
end
coordinates
end
end
def contested_coordinates
@contested_coordinates ||= begin
occupied_coordinates.dup.keep_if {|k, v| v > 1}
end
end
def contested_coordinates_count
contested_coordinates.count
end
def uncontested_claim
claims.each do |claim|
if claim.uncontested_coordinates(contested_coordinates) == claim.occupied_coordinates
return claim
end
end
nil
end
end
claims = File.readlines('inputs/day_3.txt').map { |line| Claim.new(line.strip) }
grid = Grid.new(claims)
# puts grid.contested_coordinates_count
puts grid.uncontested_claim.id