Skip to content

Instantly share code, notes, and snippets.

@mykdavies
Last active November 23, 2023 11:48
Show Gist options
  • Save mykdavies/5c5cc4b78c1b541159db97f34a5b389a to your computer and use it in GitHub Desktop.
Save mykdavies/5c5cc4b78c1b541159db97f34a5b389a to your computer and use it in GitHub Desktop.
AOC day23
// AOC 2022, Day 23: Unstable Diffusion
// Move some elves around according to odd rules
// 1) See how much they spread out after 10 moves.
// 2) How long does it take for them to all get stuck?
// https://dartpad.dev/?id=5c5cc4b78c1b541159db97f34a5b389a
import 'dart:math';
import 'package:collection/collection.dart';
extension IntegerRangeExtension on int {
List<int> to(int end, {int step = 1}) =>
List.generate((end - this + (step - 1)) ~/ step, (i) => i * step + this);
}
const headings = {
'NW': Point(-1, -1),
'N': Point(0, -1),
'NE': Point(1, -1),
'W': Point(-1, 0),
'E': Point(1, 0),
'SW': Point(-1, 1),
'S': Point(0, 1),
'SE': Point(1, 1)
};
var n8 = headings.values;
const rules = {
'N': ['N', 'NE', 'NW'],
'S': ['S', 'SE', 'SW'],
'W': ['W', 'NW', 'SW'],
'E': ['E', 'NE', 'SE'],
};
var looks = rules.keys.toList();
late Set<Point<int>> elfPositions;
Set<Point<int>> positionElves(List<String> lines) => lines.indexed
.map((r) => r.$2
.split('')
.indexed
.where((c) => c.$2 == '#')
.map((c) => Point(c.$1, r.$1)))
.flattened
.toSet();
bool moveElves(int dir) {
// planned location is the key, old location is the value.
var moves = <Point<int>, Point<int>>{};
var badMoves = <Point<int>>{};
for (var pos in elfPositions
.where((e) => n8.any((n) => elfPositions.contains(n + e)))) {
for (var offset in 0.to(4)) {
var look = looks[(dir + offset) % 4];
if (rules[look]!.any((e) => elfPositions.contains(pos + headings[e]!))) {
continue;
}
var np = pos + headings[look]!;
if (moves.containsKey(np)) {
badMoves.add(np);
} else {
moves[np] = pos;
}
break;
}
}
var goodMoves = moves.entries.where((m) => !badMoves.contains(m.key));
for (var m in goodMoves) {
elfPositions
..remove(m.value)
..add(m.key);
}
return goodMoves.isNotEmpty;
}
part1(List<String> lines) {
elfPositions = positionElves(lines);
0.to(10).forEach((dir) => moveElves(dir % 4));
var xs = elfPositions.map((e) => e.x);
var ys = elfPositions.map((e) => e.y);
return (1 + xs.max - xs.min) * (1 + ys.max - ys.min) - elfPositions.length;
}
part2(List<String> lines) {
elfPositions = positionElves(lines);
for (var round in 0.to(9999)) {
if (!moveElves(round % 4)) return round + 1;
}
return -1;
}
const testdata = [
"..............",
"..............",
".......#......",
".....###.#....",
"...#...#.#....",
"....#...##....",
"...#.###......",
"...##.#.##....",
"....#..#......",
"..............",
"..............",
".............."
];
void main(List<String> args) {
var dt = DateTime.now();
assert(part1(testdata) == 110);
assert(part2(testdata) == 20);
var rt = DateTime.now().difference(dt).inMilliseconds;
print('tests succeeded in $rt ms');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment