Skip to content

Commit ea096dc

Browse files
committed
Day 12 part 1 Ruby solution
1 parent 35e01b0 commit ea096dc

File tree

1 file changed

+101
-0
lines changed

1 file changed

+101
-0
lines changed

12-1.rb

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#!/usr/bin/env ruby
2+
3+
require 'numo/narray'
4+
5+
class Map
6+
attr_reader :map, :regions
7+
8+
def initialize(input)
9+
@height = input.size
10+
@width = input[0].size
11+
@map = Numo::UInt8.zeros(@height, @width)
12+
@height.times do |y|
13+
@width.times do |x|
14+
@map[y, x] = input[y][x].codepoints[0]
15+
end
16+
end
17+
@handled = Numo::UInt8.zeros(@height, @width)
18+
@regions = nil
19+
end
20+
21+
def flood_fill!(y, x)
22+
plant = @map[y, x]
23+
region = []
24+
queue = [[y, x]]
25+
until queue.empty?
26+
cell = queue.shift
27+
next unless @map[cell[0], cell[1]] == plant
28+
next unless @handled[cell[0], cell[1]].zero?
29+
30+
region << cell
31+
@handled[cell[0], cell[1]] = 1
32+
33+
queue << [cell[0] - 1, cell[1]] if cell[0] > 0
34+
queue << [cell[0] + 1, cell[1]] if cell[0] < (@height - 1)
35+
queue << [cell[0], cell[1] - 1] if cell[1] > 0
36+
queue << [cell[0], cell[1] + 1] if cell[1] < (@width - 1)
37+
end
38+
39+
region
40+
end
41+
42+
def split!
43+
@regions = []
44+
@height.times do |y|
45+
@width.times do |x|
46+
next if @handled[y, x] == 1
47+
48+
@regions << flood_fill!(y, x)
49+
end
50+
end
51+
end
52+
53+
def score
54+
@regions.map do |region|
55+
area = region.size
56+
perimeter = region.map do |plot|
57+
p = 0
58+
p += 1 unless region.include? [plot[0] - 1, plot[1]]
59+
p += 1 unless region.include? [plot[0] + 1, plot[1]]
60+
p += 1 unless region.include? [plot[0], plot[1] - 1]
61+
p += 1 unless region.include? [plot[0], plot[1] + 1]
62+
p
63+
end.sum
64+
area * perimeter
65+
end.sum
66+
end
67+
68+
def inspect
69+
to_s
70+
end
71+
72+
def to_s
73+
s = "<#{self.class}:\n"
74+
@height.times do |y|
75+
@width.times do |x|
76+
s << @map[y, x]
77+
end
78+
s += "\n"
79+
end
80+
s += "\nUsed:\n"
81+
@height.times do |y|
82+
@width.times do |x|
83+
s << case @handled[y, x]
84+
when 0
85+
'.'
86+
when 1
87+
'#'
88+
end
89+
end
90+
s += "\n"
91+
end
92+
s += "\n"
93+
s += "#{@regions.size} regions\n" if @regions
94+
s += '>'
95+
s
96+
end
97+
end
98+
99+
map = Map.new File.read('12.input').lines.map(&:strip)
100+
map.split!
101+
puts map.score

0 commit comments

Comments
 (0)