-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathday03_engine.dart
130 lines (109 loc) · 3.64 KB
/
day03_engine.dart
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import 'dart:core';
import 'dart:convert';
import 'dart:io';
import '../aoc/utilities.dart';
void main() {
String sampleInput = File('data/day03_sample.txt').readAsStringSync();
String puzzleInput = File('data/day03_input.txt').readAsStringSync();
// part 1
Engine engineSampleData = Engine(sampleInput);
assert(engineSampleData.part1() == 4361);
final stopwatchPart1 = Stopwatch()..start();
Engine engine = Engine(puzzleInput);
print("part 1: ${engine.part1()}");
stopwatchPart1.stop();
print("Elapsed time: ${stopwatchPart1.elapsed}");
// part 2
assert(engineSampleData.part2() == 467835);
final stopwatchPart2 = Stopwatch()..start();
print("part 2: ${engine.part2()}");
stopwatchPart2.stop();
print("Elapsed time: ${stopwatchPart2.elapsed}");
}
// https://stackoverflow.com/questions/24085385/checking-if-string-is-numeric-in-dart
isInt(string) => int.tryParse(string) != null;
class Engine {
late Map<Point, String> symbolLocations = {};
late Map<Point, int> pointToClusterId = {};
late Map<int, int> clusterInformation = {};
int part1() {
Set<int> clustersFound = {};
symbolLocations.keys.forEach((symbolLocation) {
symbolLocation.adjacent8().forEach((pointToCheck) {
if (pointToClusterId.containsKey(pointToCheck)) {
clustersFound.add(pointToClusterId[pointToCheck]!);
}
});
});
int sumPartNumbers = 0;
clustersFound.forEach((element) {
sumPartNumbers = sumPartNumbers + clusterInformation[element]!;
});
return sumPartNumbers;
}
int part2() {
Map<Point, Set<int>> gearClusters = {};
symbolLocations.entries.forEach((symbolLocation) {
if (symbolLocation.value == "*") {
symbolLocation.key.adjacent8().forEach((pointToCheck) {
if (pointToClusterId.containsKey(pointToCheck)) {
if (!gearClusters.containsKey(symbolLocation.key)) {
gearClusters[symbolLocation.key] = {};
}
gearClusters[symbolLocation.key]!
.add(pointToClusterId[pointToCheck]!);
}
});
}
});
gearClusters.removeWhere((key, value) => value.length != 2);
int sumGearRatios = 0;
gearClusters.forEach((key, value) {
int gearRatio = 1;
value.forEach((element) {
gearRatio = gearRatio * clusterInformation[element]!;
});
sumGearRatios += gearRatio;
});
return sumGearRatios;
}
Engine(String input) {
LineSplitter ls = new LineSplitter();
List<String> lines = ls.convert(input);
int clusterCounter = 1;
for (final (y, line) in lines.indexed) {
bool parsingNumber = false;
String currentNumber = "";
int startX = 0;
for (final (x, value) in line.split("").indexed) {
// check if number
if (isInt(value)) {
currentNumber += value;
if (!parsingNumber) {
parsingNumber = true;
startX = x;
}
if (!(x == line.length - 1)) continue;
}
// if we are parsing number, check more things
if (parsingNumber) {
int partNumber = int.parse(currentNumber);
for (var newX = startX; newX < x; newX++) {
pointToClusterId[Point(newX, y)] = clusterCounter;
}
if (x == line.length - 1) {
pointToClusterId[Point(x, y)] = clusterCounter;
}
clusterInformation[clusterCounter] = partNumber;
currentNumber = "";
clusterCounter += 1;
parsingNumber = false;
}
// handle symbols
if ((value != ".") & !isInt(value)) {
symbolLocations[Point(x, y)] = value;
}
}
}
}
}