aboutsummaryrefslogtreecommitdiff
path: root/src/2022/day11/aoc.cpp
blob: b92d1a13bb4bab0b98f3536ead3b226ea2bd30fa (plain)
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
#include "aoc.h"
#include <algorithm>

namespace aoc2022 {
static int lcm = 1;

static void lcmf(int is[], int n) {
  for (int i = 0; i < n; i++) {
    lcm *= is[i];
  }
  int x = is[0];
  for (int i = 1; i < n; i++) {
    x = gcd(x, is[i]);
  }
  lcm /= x;
}

static size_t op1(size_t n) {
  return n / 3;
}

static size_t op2(size_t n) {
  return n % lcm;
}

static void round(func f, monkey* ms) {
  for(int i = 0; i < 8; i++) {
    monkey* m = ms + i;
    m->transfer(ms, f);
  }
}

static size_t two(monkey* ms) {
  std::sort(ms, ms+8, [](monkey& m1, monkey& m2){
    return m1.count > m2.count;
  });
  return (size_t) ms[0].count * (size_t) ms[1].count;
}

std::pair<size_t, size_t> day11(line_view file) {
  std::vector<monkey> vs1;

  const char *p = file.line;
  const char *p0 = p;
  while (p < file.line + file.length) {
    if (*p == '\n' && *(p+1) == '\n'){
      vs1.emplace_back(line_view{p0, p});
      p0 = p + 2;
    }
    p++;
  }
  std::vector<monkey> vs2 = vs1;
  monkey* ms1 = vs1.data();
  monkey* ms2 = vs2.data();

  for (int i = 0; i < 20; i++) {
    round(op1, ms1);
  }

  int mods[8];
  for (int i = 0; i < 8; i++) {
    mods[i] = vs2[i].mod;
  }
  lcmf(mods, 8);
  for (int i = 0; i < 10000; i++) {
    round(op2, ms2);
  }
  return {two(ms1), two(ms2)};
}

}