day14_part2.carbon 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. // https://adventofcode.com/2024/day/14
  5. import Core library "io";
  6. import Core library "range";
  7. import library "day14_common";
  8. import library "io_utils";
  9. // Returns m and n so that am + bn = gcd.
  10. fn Euclid(a: i32, b: i32) -> {.m: i32, .n: i32, .gcd: i32} {
  11. if (a < b) {
  12. let reverse: {.m: i32, .n: i32, .gcd: i32} = Euclid(b, a);
  13. return {.m = reverse.n, .n = reverse.m, .gcd = reverse.gcd};
  14. }
  15. if (b == 0) {
  16. return {.m = 1, .n = 0, .gcd = a};
  17. }
  18. let next: {.m: i32, .n: i32, .gcd: i32} = Euclid(b, a % b);
  19. return {.m = next.n, .n = next.m - next.n * (a / b), .gcd = next.gcd};
  20. }
  21. // Uses Chinese remainder theorem to find the least positive x that solves
  22. // x = a mod p
  23. // x = b mod q
  24. // modulo pq / gcd(p,q), if one exists (if a = b mod gcd(p,q)).
  25. fn CRT(a: i32, b: i32, p: i32, q: i32) -> i32 {
  26. let e: {.m: i32, .n: i32, .gcd: i32} = Euclid(p, q);
  27. let x: i32 = a * (q / e.gcd) * e.n + b * (p / e.gcd) * e.m;
  28. return Mod(x, p * (q / e.gcd));
  29. }
  30. fn PrintState(r: array(Robot, 500), t: i32) {
  31. var display: array(array(char, 101), 103);
  32. for (y: i32 in Core.Range(103)) {
  33. for (x: i32 in Core.Range(101)) {
  34. display[y][x] = '.';
  35. }
  36. }
  37. for (ri: Robot in r) {
  38. let xy: (i32, i32) = ri.Pos(t);
  39. display[xy.1][xy.0] = '#';
  40. }
  41. for (y: i32 in Core.Range(103)) {
  42. for (x: i32 in Core.Range(101)) {
  43. Core.PrintChar(display[y][x]);
  44. }
  45. Core.PrintChar('\n');
  46. }
  47. }
  48. fn Run() {
  49. var r: array(Robot, 500);
  50. for (i: i32 in Core.Range(500)) {
  51. r[i] = Robot.Read();
  52. }
  53. let first_match_x: i32 = 28;
  54. let first_match_y: i32 = 84;
  55. var t: i32 = CRT(first_match_x, first_match_y, 101, 103);
  56. Core.Print(t);
  57. PrintState(r, t);
  58. }