Skip to content

Commit 3ee2877

Browse files
committed
Day 03
1 parent 3433e80 commit 3ee2877

File tree

2 files changed

+279
-0
lines changed

2 files changed

+279
-0
lines changed

day03.groovy

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import groovy.transform.TupleConstructor;
2+
3+
4+
def input = new File("input/day03.txt").readLines();
5+
6+
@TupleConstructor
7+
class PartNumber {
8+
Schematic schematic;
9+
int x;
10+
int y;
11+
int len;
12+
int value;
13+
14+
boolean isValid() {
15+
int x0 = Math.max(0, x - 1);
16+
int x1 = Math.min(schematic.width - 1, x + len + 1);
17+
int y0 = Math.max(0, y - 1);
18+
int y1 = Math.min(schematic.height - 1, y + 1);
19+
for (int j in y0..y1) {
20+
for (int i in x0..x1) {
21+
char c = schematic.get(i, j);
22+
if (!c.isDigit() && c != '.') {
23+
return true;
24+
}
25+
}
26+
}
27+
28+
return false;
29+
}
30+
31+
boolean includes(int px, int py) {
32+
int x0 = Math.max(0, x - 1);
33+
int x1 = Math.min(schematic.width - 1, x + len + 1);
34+
int y0 = Math.max(0, y - 1);
35+
int y1 = Math.min(schematic.height - 1, y + 1);
36+
37+
return x0 <= px && px <= x1 && y0 <= py && py <= y1;
38+
}
39+
40+
String toString() {
41+
int x0 = Math.max(0, x - 1);
42+
int x1 = Math.min(schematic.width - 1, x + len + 1);
43+
int y0 = Math.max(0, y - 1);
44+
int y1 = Math.min(schematic.height - 1, y + 1);
45+
46+
def result = "";
47+
for (int j in y0..y1) {
48+
for (int i in x0..x1) {
49+
result += schematic.get(i, j);
50+
}
51+
result += "\n";
52+
}
53+
return result;
54+
}
55+
}
56+
57+
class Schematic {
58+
private final char[] arr;
59+
final int width;
60+
final int height;
61+
62+
private def partNumbersCache;
63+
64+
Schematic(List<String> input) {
65+
arr = input.join("").toCharArray();
66+
width = input[0].size();
67+
height = input.size();
68+
}
69+
70+
def get(int x, int y) {
71+
int pos = x + y * width;
72+
return arr[pos];
73+
}
74+
75+
def getPartNumbers() {
76+
if (partNumbersCache != null) {
77+
return partNumbersCache;
78+
}
79+
80+
def result = [];
81+
82+
def numberIndices = arr.findIndexValues { it.isDigit() };
83+
84+
int pnStart = numberIndices[0];
85+
int curr, next;
86+
for (int i = 0; i < numberIndices.size(); i++) {
87+
curr = numberIndices[i];
88+
next = numberIndices[i + 1] ?: -1;
89+
if (next - curr == 1) {
90+
continue;
91+
}
92+
93+
int pnX = pnStart % width;
94+
int pnY = Math.floor(pnStart / width);
95+
def pnEnd = curr;
96+
def pnLength = pnEnd - pnStart;
97+
result << new PartNumber(this, pnX, pnY, pnLength, arr[pnStart..pnEnd].join("").toInteger());
98+
99+
pnStart = next;
100+
}
101+
102+
partNumbersCache = result;
103+
return result;
104+
}
105+
106+
def getGears() {
107+
def gearIndices = arr.findIndexValues { it == '*' };
108+
return gearIndices.collect {
109+
int gX = it % width;
110+
int gY = Math.floor(it / width);
111+
return getPartNumbers().findAll { pn ->
112+
return pn.includes(gX, gY);
113+
};
114+
}.findAll { pnc -> pnc.size() == 2 };
115+
}
116+
117+
String toString() {
118+
def result = "";
119+
for (int y = 0; y < height; y++) {
120+
for (int x = 0; x < width; x++) {
121+
result += this.get(x, y);
122+
}
123+
result += "\n";
124+
}
125+
return result;
126+
}
127+
}
128+
129+
def schematic = new Schematic(input);
130+
131+
def partNumberSum = schematic.getPartNumbers().inject(0) { acc, it ->
132+
return it.isValid() ? acc + it.value : acc;
133+
};
134+
println(partNumberSum);
135+
136+
def gearRatioSum = schematic.getGears().inject(0) { acc, it ->
137+
return acc + (it[0].value * it[1].value);
138+
};
139+
println(gearRatioSum);

0 commit comments

Comments
 (0)