-
Notifications
You must be signed in to change notification settings - Fork 0
/
day08.dart
117 lines (96 loc) · 3.51 KB
/
day08.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
import 'package:adventofcode2022/day.dart';
import 'package:adventofcode2022/helper/string_extensions.dart';
import 'package:adventofcode2022/helper/table.dart';
import 'helper/cell.dart';
class Day8 implements Day {
@override
int get dayNumber => 8;
@override
String solveFirstPuzzle(String puzzleInput) {
final treeRows = puzzleInput.splitPerLine().map((e) => e.split('').map((e) => int.parse(e)));
final table = Table(treeRows);
final columns = table.cellsInColumns;
final rows = table.cellsInRows;
var visibleTrees = 0;
visibleTrees += (2 * table.rowLength);
visibleTrees += (2 * (columns.length - 2));
List<Cell<int>> trees = [];
findVisibleTrees(columns, trees);
findVisibleTrees(rows, trees);
visibleTrees += trees.length;
return visibleTrees.toString();
}
@override
String solveSecondPuzzle(String puzzleInput) {
final treeRows = puzzleInput.splitPerLine().map((e) => e.split('').map((e) => int.parse(e)));
final table = Table(treeRows);
List<int> scenicScores = [];
for (var tree in table.asIterableCells()) {
if (tree.x == 0 ||
tree.y == 0 ||
tree.x == table.columnsLength - 1 ||
tree.y == table.rowLength - 1) {
continue;
}
var up = upViewingDistance(tree, table);
var down = downViewingDistance(tree, table);
var left = leftViewingDistance(tree, table);
var right = rightViewingDistance(tree, table);
var scenicScore = up * down * left * right;
scenicScores.add(scenicScore);
}
scenicScores.sort();
return scenicScores.last.toString();
}
void findVisibleTrees(List<Iterable<Cell<int>>> listOfListOfTrees, List<Cell<int>> visibleTrees) {
for (var j = 1; j < listOfListOfTrees.length - 1; j++) {
var listOfTrees = listOfListOfTrees[j].toList();
findVisibleTreeInList(listOfTrees, visibleTrees);
findVisibleTreeInList(listOfTrees.reversed.toList(), visibleTrees);
}
}
void findVisibleTreeInList(List<Cell<int>> trees, List<Cell<int>> visibleTrees) {
for (var i = 1; i < trees.length - 1; i++) {
var tree = trees[i];
if (tree.value > trees.first.value &&
trees.sublist(1, i).every((element) => element.value < tree.value) &&
!visibleTrees.contains(tree)) {
visibleTrees.add(tree);
}
}
}
int upViewingDistance(Cell<int> tree, Table<int> table) {
return calculateViewingDistance(
tree, table, (distance) => table.getValue(tree.y + distance, tree.x));
}
int downViewingDistance(Cell<int> tree, Table<int> table) {
return calculateViewingDistance(
tree, table, (distance) => table.getValue(tree.y - distance, tree.x));
}
int leftViewingDistance(Cell<int> tree, Table<int> table) {
return calculateViewingDistance(
tree, table, (distance) => table.getValue(tree.y, tree.x + distance));
}
int rightViewingDistance(Cell<int> tree, Table<int> table) {
return calculateViewingDistance(
tree, table, (distance) => table.getValue(tree.y, tree.x - distance));
}
int calculateViewingDistance(
Cell<int> tree, Table<int> table, int Function(int distance) getNeighborTreeSizeInDistance) {
bool lookUp = true;
int viewDistance = 1;
try {
while (lookUp) {
var treeSize = getNeighborTreeSizeInDistance(viewDistance);
if (treeSize >= tree.value) {
lookUp = false;
} else {
viewDistance++;
}
}
} catch (e) {
viewDistance--;
}
return viewDistance;
}
}