aboutsummaryrefslogtreecommitdiff
path: root/src/2022/day5/aoc.h
blob: 1014bb7a813d0250744b455c7c59e92294dec736 (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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include "common.h"
#include <stack>

namespace aoc2022 {

struct crate {
  static crate* cs[9];

  char value;
  crate* prev = nullptr;
  crate* next = nullptr;

  static void init() {
    for (int i = 0; i < 9; i++) {
      cs[i] = new crate;
      cs[i]->value = 0;
      cs[i]->prev = cs[i];
      cs[i]->next = cs[i];
    }
  }

  static crate* make(line_view lv) {
    crate* c = new crate;
    c->value = *(lv.line + 1);
    return c;
  }

  static crate* take(int i) {
    crate* c = cs[i]->next;
    c->next->prev = cs[i];
    cs[i]->next = c->next;
    return c;
  }

  static void print(int i) {
    printf("%d: \"",i);

    crate* c = cs[i]->prev;
    while (c != cs[i]) {
      printf("%c", c->value);
      c = c->prev;
    }
    printf("\"");

    // c = cs[i]->next;
    // while (c != cs[i]) {
    //   printf("%c", c->value);
    //   c = c->next;
    // }
    printf("\n");
  }

  static void add(crate* c, int i) {
    if (c->value >= 'A' && c->value <= 'Z') {
      cs[i]->prev->next = c;
      c->prev = cs[i]->prev;
      c->next = cs[i];
      cs[i]->prev = c;
      // printf("add %c on %d\n", c->value, i);
    }
  }

  static void put(crate* c, int i) {
    if (c->value >= 'A' && c->value <= 'Z') {
      cs[i]->next->prev = c;
      c->next = cs[i]->next;
      c->prev = cs[i];
      cs[i]->next = c;
    }
  }

  static void message(char *m) {
    for (int i = 0; i < 9; i++) {
      *m = cs[i]->next->value;
      m++;
    }
  }

  static void move(line_view lv, int mode) {
    int d[3] = {0};
    int* p = d;
    const char *p0 = lv.line + 5;
    while (p0 < lv.line + lv.length) {
      if (*p0 >= '0' && *p0 <= '9') {
        *p = *p * 10 + *p0 - '0';
      }
      else {
        char c = *(p0 - 1);
        if (c >= '0' && c <= '9') {
          p++;
        }
      }
      p0++;
    }

    d[1] -= 1;
    d[2] -= 1;

    if (mode == 1) {
      while (d[0]-- > 0) {
        crate* c = take(d[1]);
        put(c, d[2]);
      }
    }
    if (mode == 2) {
      std::stack<crate*> dx;
      while(d[0]-- > 0) {
        dx.push(take(d[1]));
      }
      while(!dx.empty()) {
        put(dx.top(), d[2]);
        dx.pop();
      }
    }
  }
};

void day5(line_view file, char* msg, int mode);

}