Skip to content

Commit 232ce12

Browse files
author
Robb Kidd
committed
Day 13, part 1
1 parent 25d4efa commit 232ce12

File tree

1 file changed

+128
-0
lines changed

1 file changed

+128
-0
lines changed

2023/ruby/day13.rb

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
require_relative 'day'
2+
3+
class Day13 < Day # >
4+
5+
# @example
6+
# day.part1 #=> 405
7+
def part1
8+
@patterns ||=
9+
input
10+
.split("\n\n")
11+
.map { |stanza| Pattern.new(stanza) }
12+
13+
@patterns
14+
.map { |pattern| pattern.summarize }
15+
.reduce(&:+)
16+
end
17+
18+
# example
19+
# day.part2 #=> 'how are you'
20+
def part2
21+
end
22+
23+
EXAMPLE_INPUT = <<~INPUT
24+
#.##..##.
25+
..#.##.#.
26+
##......#
27+
##......#
28+
..#.##.#.
29+
..##..##.
30+
#.#.##.#.
31+
32+
#...##..#
33+
#....#..#
34+
..##..###
35+
#####.##.
36+
#####.##.
37+
..##..###
38+
#....#..#
39+
INPUT
40+
41+
FIRST_PATTERN = EXAMPLE_INPUT.split("\n\n").first
42+
SECOND_PATTERN = EXAMPLE_INPUT.split("\n\n").last
43+
end
44+
45+
class Pattern
46+
attr_reader :rows, :columns
47+
48+
# @example
49+
# p = new(Day13::FIRST_PATTERN)
50+
# p.rows.first #=> "#.##..##."
51+
# p.columns.first #=> '#.##..#'
52+
def initialize(input)
53+
@input = input
54+
@rows = input.split("\n")
55+
@columns = @rows.map(&:chars).transpose.map(&:join)
56+
end
57+
58+
# @example 1st
59+
# p = new(Day13::FIRST_PATTERN)
60+
# p.summarize #=> 5
61+
# @example 2nd
62+
# p = new(Day13::SECOND_PATTERN)
63+
# p.summarize #=> 400
64+
def summarize
65+
if row_reflection = line_of_reflection(rows)
66+
return row_reflection * 100
67+
end
68+
69+
line_of_reflection(columns)
70+
end
71+
72+
def row_reflection
73+
line_of_reflection(rows) *
74+
case reflection.length
75+
when 0
76+
return nil
77+
when 1
78+
return reflection.first[1] # the index of the second row in the line of reflection accounts for the 1-index of the puzzle
79+
else
80+
raise("more than one line of reflection for rows. wat?")
81+
end
82+
end
83+
84+
# @example 1st_rows
85+
# p = new(Day13::FIRST_PATTERN)
86+
# p.line_of_reflection(p.rows) #=> nil
87+
# @example 1st_columns
88+
# p = new(Day13::FIRST_PATTERN)
89+
# p.line_of_reflection(p.columns) #=> 5
90+
# @example 2nd_rows
91+
# p = new(Day13::SECOND_PATTERN)
92+
# p.line_of_reflection(p.rows) #=> 4
93+
# @example 2nd_columns
94+
# p = new(Day13::SECOND_PATTERN)
95+
# p.line_of_reflection(p.columns) #=> nil
96+
def line_of_reflection(dimension)
97+
reflections ||=
98+
reflection_candidates(dimension)
99+
.select { |candidate|
100+
candidate[0].downto(0)
101+
.zip(candidate[1].upto(dimension.length-1))
102+
.select { |pair| pair.all? }
103+
.all? { |left, right| dimension[left] == dimension[right] }
104+
}
105+
case reflections.length
106+
when 0
107+
return nil
108+
when 1
109+
# account for the 1-index of the puzzle by returning the second index of a line of reflection
110+
return reflections.first[1]
111+
else
112+
raise("more than one line of reflection. wat?")
113+
end
114+
end
115+
116+
# @example
117+
# p = new(Day13::FIRST_PATTERN)
118+
# p.reflection_candidates(p.rows) #=> [[2,3]]
119+
# p.reflection_candidates(p.columns) #=> [[4,5]]
120+
def reflection_candidates(dimension)
121+
dimension
122+
.map.with_index
123+
.each_cons(2)
124+
.select { |left, right| left[0] == right[0] }
125+
.map { |left, right| [left[1], right[1]] }
126+
end
127+
128+
end

0 commit comments

Comments
 (0)