Day 14: Restroom Redoubt
Megathread guidelines
- Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
- You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL
FAQ
- What is this?: Here is a post with a large amount of details: https://programming.dev/post/6637268
- Where do I participate?: https://adventofcode.com/
- Is there a leaderboard for the community?: We have a programming.dev leaderboard with the info on how to join in this post: https://programming.dev/post/6631465
Dart
Took far too long to work out a really stupidly simple method of finding the tree – I ended up just checking the first height*width time slots to find when the most bots appear in any given row/column. The framing around the Christmas tree accidentally made this foolproof :-). Add a bit of Chinese Remainder Theorem and we’re golden. (edit: forgot to mention that it’s Dart code)
import 'dart:math'; import 'package:collection/collection.dart'; import 'package:more/more.dart'; List<List<Point<num>>> getBots(List<String> lines) { var bots = lines .map((e) => RegExp(r'(-?\d+)') .allMatches(e) .map((m) => int.parse(m.group(0)!)) .toList()) .map((p) => [Point<num>(p[0], p[1]), Point<num>(p[2], p[3])]) .toList(); return bots; } // Solve system of congruences using the Chinese Remainder Theorem int crt(int r1, int m1, int r2, int m2) { int inv = m1.modInverse(m2); int solution = (r1 + m1 * ((r2 - r1) % m2) * inv) % (m1 * m2); return (solution + (m1 * m2)) % (m1 * m2); // Ensure the result is positive } void moveBy(List<List<Point<num>>> bots, int t, int w, int h) { for (var b in bots) { b.first += b.last * t; b.first = Point(b.first.x % w, b.first.y % h); } } part1(List<String> lines, [width = 11, height = 7]) { var bots = getBots(lines); moveBy(bots, 100, width, height); var w = width ~/ 2, h = height ~/ 2; var quads = Multiset.fromIterable( bots.map((b) => (b.first.x.compareTo(w), b.first.y.compareTo(h)))); return [(-1, -1), (-1, 1), (1, -1), (1, 1)] .map((k) => quads[k]) .reduce((s, t) => s * t); } part2(List<String> lines, [width = 101, height = 103]) { var bots = getBots(lines); var t = 0; int rmax = 0, cmax = 0, rt = 0, ct = 0; while (t < width * height) { t += 1; moveBy(bots, 1, width, height); var r = Multiset.fromIterable(bots.map((e) => e.first.x)).counts.max; var c = Multiset.fromIterable(bots.map((e) => e.first.y)).counts.max; if (r > rmax) (rmax, rt) = (r, t); if (c > cmax) (cmax, ct) = (c, t); } t = crt(rt, width, ct, height); bots = getBots(lines); moveBy(bots, t, width, height); // printGrid(height, width, bots); return t; }