-
Notifications
You must be signed in to change notification settings - Fork 1
/
day10_maze.dart
108 lines (91 loc) · 2.63 KB
/
day10_maze.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
import 'dart:collection';
import 'dart:core';
import 'dart:io';
import '../aoc/utilities.dart';
void main() {
// Sample data
String sampleInput = File('data/day10_sample.txt').readAsStringSync();
Grid sampleGrid = Grid.fromPuzzleInput(sampleInput);
assert(sampleGrid.part1() == 4);
sampleInput = File('data/day10_sample2.txt').readAsStringSync();
sampleGrid = Grid.fromPuzzleInput(sampleInput);
assert(sampleGrid.part1() == 8);
String puzzleInput = File('data/day10_input.txt').readAsStringSync();
// part 1
final stopwatchPart1 = Stopwatch()..start();
Grid grid = Grid.fromPuzzleInput(puzzleInput);
print("part 1: ${grid.part1()}");
stopwatchPart1.stop();
print("Elapsed time: ${stopwatchPart1.elapsed}");
}
class Grid {
Map<Point, Set<Point>> pipeMap;
Point start;
Grid(this.pipeMap, this.start);
int part1() {
return findLoopSize() ~/ 2;
}
int findLoopSize() {
Set<Point> visited = {};
Queue<Point> toVisit = Queue<Point>();
int step = 0;
visited.add(start);
toVisit.add(pipeMap[start]!.first);
while (toVisit.length != 0) {
var currPoint = toVisit.removeFirst();
visited.add(currPoint);
step++;
toVisit.addAll(pipeMap[currPoint]!
.toList()
.where((point) => !visited.contains(point)));
}
return step + 1;
}
factory Grid.fromPuzzleInput(String input) {
Map<Point, Set<Point>> pipeMap = {};
Point start = Point(-1, -1);
input
.split("\n")
.where((line) => line.length != 0)
.toList()
.asMap()
.entries
.forEach((entry) {
var y = entry.key;
var line = entry.value;
line.split("").asMap().entries.forEach((entry) {
var x = entry.key;
Point p = Point(x, y);
switch (entry.value) {
case '|':
pipeMap[p] = {p.north(), p.south()};
break;
case '-':
pipeMap[p] = {p.east(), p.west()};
break;
case 'L':
pipeMap[p] = {p.north(), p.east()};
break;
case 'J':
pipeMap[p] = {p.north(), p.west()};
break;
case '7':
pipeMap[p] = {p.south(), p.west()};
break;
case 'F':
pipeMap[p] = {p.south(), p.east()};
break;
case 'S':
start = p;
break;
}
});
});
// add start's neighbours to pipe map
var startNeighbours = pipeMap.entries
.where((entry) => entry.value.contains(start))
.map((entry) => entry.key);
pipeMap[start] = Set.from(startNeighbours);
return Grid(pipeMap, start);
}
}