-
Notifications
You must be signed in to change notification settings - Fork 0
/
day09.dart
101 lines (78 loc) · 2.33 KB
/
day09.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
import 'dart:math';
import 'package:adventofcode2022/day.dart';
import 'package:adventofcode2022/helper/string_extensions.dart';
class Day9 implements Day {
@override
int get dayNumber => 9;
@override
String solveFirstPuzzle(String puzzleInput) {
final headMovements = parseHeadMovementsAsPoints(puzzleInput);
Point head = const Point(0, 0);
Point tail = const Point(0, 0);
List<Point> tailPositions = [tail];
for (var movement in headMovements) {
head = moveHead(movement, head);
tail = moveTail(head, tail);
if (!tailPositions.contains(tail)) {
tailPositions.add(tail);
}
}
return tailPositions.length.toString();
}
@override
String solveSecondPuzzle(String puzzleInput) {
final headMovements = parseHeadMovementsAsPoints(puzzleInput);
Point head = const Point(0, 0);
List<Point> tails = List.filled(9, const Point(0, 0));
List<Point> tailPositions = [tails.last];
for (var movements in headMovements) {
head = moveHead(movements, head);
tails[0] = moveTail(head, tails.first);
for (var i = 1; i < tails.length; i++) {
final tail = tails[i];
var newTail = moveTail(tails[i - 1], tail);
tails[i] = newTail;
}
if (!tailPositions.contains(tails.last)) {
tailPositions.add(tails.last);
}
}
return tailPositions.length.toString();
}
}
Iterable<Point> parseHeadMovementsAsPoints(String puzzleInput) {
return puzzleInput.splitPerLine().map((e) {
final parts = e.split(' ');
final directions = List.filled(int.parse(parts[1]), movementAsPoint(parts[0]));
return directions;
}).expand((element) => element);
}
Point movementAsPoint(String rawDirection) {
if (rawDirection == 'U') {
return const Point(0, 1);
}
if (rawDirection == 'D') {
return const Point(0, -1);
}
if (rawDirection == 'R') {
return const Point(1, 0);
}
if (rawDirection == 'L') {
return const Point(-1, 0);
}
throw ArgumentError();
}
Point<num> moveHead(Point direction, Point<num> head) {
return head + direction;
}
Point moveTail(Point head, Point tail) {
num x = tail.x;
num y = tail.y;
var difference = head - tail;
if (difference.x.abs() <= 1 && difference.y.abs() <= 1) {
return tail;
}
x += difference.x.sign;
y += difference.y.sign;
return Point(x, y);
}