this post was submitted on 14 Dec 2024
15 points (100.0% liked)

Advent Of Code

995 readers
4 users here now

An unofficial home for the advent of code community on programming.dev!

Advent of Code is an annual Advent calendar of small programming puzzles for a variety of skill sets and skill levels that can be solved in any programming language you like.

AoC 2024

Solution Threads

M T W T F S S
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

Rules/Guidelines

Relevant Communities

Relevant Links

Credits

Icon base by Lorc under CC BY 3.0 with modifications to add a gradient

console.log('Hello World')

founded 1 year ago
MODERATORS
15
submitted 2 weeks ago* (last edited 2 weeks ago) by CameronDev to c/advent_of_code
 

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

you are viewing a single comment's thread
view the rest of the comments
[โ€“] [email protected] 2 points 2 weeks ago* (last edited 2 weeks ago)

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;
}