day 18: more code cleanup/comments

This commit is contained in:
2022-01-11 19:46:27 +01:00
parent a0b094aa61
commit cd4a21380d
2 changed files with 65 additions and 107 deletions

View File

@@ -227,5 +227,5 @@ aoc-c : res=3987
context-switch: 0+1, page-faults: 0+98 context-switch: 0+1, page-faults: 0+98
aoc-c : res=4500 aoc-c : res=4500
time: 0:00.04 real, 0.03 user, 0.00 sys time: 0:00.03 real, 0.03 user, 0.00 sys
context-switch: 1+1, page-faults: 0+97 context-switch: 0+1, page-faults: 0+97

View File

@@ -16,59 +16,26 @@
#include "pool.h" #include "pool.h"
#include "debug.h" #include "debug.h"
#include "bits.h"
#include "list.h" #include "list.h"
#define LEFT 0
#define RIGHT 1
static pool_t *pool_nodes; static pool_t *pool_nodes;
#define MAX_LINES 128 #define MAX_LINES 128 /* I know, I know... */
static char *lines[MAX_LINES]; static char *lines[MAX_LINES];
static int nlines; static int nlines;
#define LEFT 0
#define RIGHT 1
#define IS_LEAF(node) (!(node)->tree[LEFT])
typedef struct node { typedef struct node {
s64 val; int val;
struct node *tree[2]; /* left & right */ struct node *tree[2]; /* left & right subtrees */
struct list_head leaf_list; /* head is tree root */ struct list_head leaf_list; /* tree root is list head */
} node_t; } node_t;
#ifdef DEBUG /* get a node from memory pool
/* print leaves list
*/ */
static void leaves_print(node_t *root)
{
node_t *list_cur;
log_i(2, "leaves:");
list_for_each_entry(list_cur, &root->leaf_list, leaf_list) {
log_i(2, " %d", list_cur->val);
}
log_i(2, "\n");
}
/* print node tree
*/
static void node_print(node_t *node, int depth)
{
if (!depth)
log_f(1, "");
if (!node->tree[LEFT]) { /* leaf */
log(1, "%ld", node->val);
} else {
log(1, "[");
node_print(node->tree[LEFT], depth + 1);
log(1, ",");
node_print(node->tree[RIGHT], depth + 1);
log(1, "]");
}
if (!depth) {
log(1, "\n");
leaves_print(node);
}
}
#endif
static inline node_t *node_get() static inline node_t *node_get()
{ {
node_t *node = pool_get(pool_nodes); node_t *node = pool_get(pool_nodes);
@@ -78,9 +45,11 @@ static inline node_t *node_get()
return node; return node;
} }
/* recursive cleanup of node
*/
static inline void node_free(node_t *node) static inline void node_free(node_t *node)
{ {
if (node->tree[LEFT]) { if (!IS_LEAF(node)) {
node_free(node->tree[LEFT]); node_free(node->tree[LEFT]);
node_free(node->tree[RIGHT]); node_free(node->tree[RIGHT]);
} }
@@ -92,11 +61,8 @@ static inline void node_free(node_t *node)
*/ */
static int node_split(node_t *node) static int node_split(node_t *node)
{ {
if (node->tree[LEFT]) { if (IS_LEAF(node)) {
if (node_split(node->tree[LEFT]) || node_split(node->tree[RIGHT])) if (node->val >= 10) { /* eligible leaf */
return 1;
} else {
if (node->val >= 10) { /* eligible leaf */
node_t *left, *right; node_t *left, *right;
/* create and populate new nodes */ /* create and populate new nodes */
@@ -115,6 +81,8 @@ static int node_split(node_t *node)
list_del(&node->leaf_list); list_del(&node->leaf_list);
return 1; return 1;
} }
} else {
return node_split(node->tree[LEFT]) || node_split(node->tree[RIGHT]);
} }
return 0; return 0;
} }
@@ -125,61 +93,50 @@ static int node_split(node_t *node)
static int node_explode(node_t *node, int depth) static int node_explode(node_t *node, int depth)
{ {
static node_t *root; static node_t *root;
node_t *left, *right;
if (!(left = node->tree[LEFT]))
return 0;
right = node->tree[RIGHT];
/* Need to keep leaves list head */
if (depth == 0) if (depth == 0)
root = node; root = node;
if (depth == 4) { if (depth == 4) {
node_t *left = node->tree[LEFT], *right = node->tree[RIGHT]; /* increment left and right leaves values */
if (!list_is_first(&left->leaf_list, &root->leaf_list))
/* skip leaves */ list_prev_entry(left, leaf_list)->val += left->val;
if (!left) if (!list_is_last(&right->leaf_list, &root->leaf_list))
return 0; list_next_entry(right, leaf_list)->val += right->val;
/* increment left leaf */
if (!list_is_first(&left->leaf_list, &root->leaf_list)) {
node_t *tmpnode = list_prev_entry(left, leaf_list);
tmpnode->val += left->val;
}
/* increment right leaf */
if (!list_is_last(&right->leaf_list, &root->leaf_list)) {
node_t *tmpnode = list_next_entry(right, leaf_list);
tmpnode->val += right->val;
}
/* node becomes a leaf */
node->val = 0; node->val = 0;
list_add(&node->leaf_list, &left->leaf_list);
list_del(&left->leaf_list);
pool_add(pool_nodes, left);
list_del(&right->leaf_list);
pool_add(pool_nodes, right);
/* remove childs links */
node->tree[LEFT] = NULL; node->tree[LEFT] = NULL;
node->tree[RIGHT] = NULL; node->tree[RIGHT] = NULL;
list_add(&node->leaf_list, &left->leaf_list);
/* remove children from leaves list, and put back in mem pool */
list_del(&left->leaf_list);
list_del(&right->leaf_list);
pool_add(pool_nodes, left);
pool_add(pool_nodes, right);
return 1; return 1;
} else { } else {
if (node->tree[LEFT]) { return node_explode(left, depth + 1) ||
if (node_explode(node->tree[LEFT], depth + 1) || node_explode(right, depth + 1);
node_explode(node->tree[RIGHT], depth + 1))
return 1;
}
} }
return 0;
} }
/* node reduce:
*/
static node_t *node_reduce(node_t *node) static node_t *node_reduce(node_t *node)
{ {
while (1) { while (1) {
if (node_explode(node, 0)) if (!node_explode(node, 0) && !node_split(node))
continue; return node;
if (node_split(node))
continue;
break;
} }
return node;
} }
/* add 2 nodes /* add 2 nodes
@@ -216,12 +173,12 @@ static inline node_t *_node_read(char **p, int depth)
switch (**p) { switch (**p) {
case '[': case '[':
(*p)++; (*p)++; /* skip left bracket */
node->tree[LEFT] = _node_read(p, depth + 1); node->tree[LEFT] = _node_read(p, depth + 1);
(*p)++; (*p)++; /* skip comma */
node->tree[RIGHT] = _node_read(p, depth + 1); node->tree[RIGHT] = _node_read(p, depth + 1);
break; break;
default: /* number */ default: /* number: add to tail list */
node->val = **p - '0'; node->val = **p - '0';
list_add_tail(&node->leaf_list, &root->leaf_list); list_add_tail(&node->leaf_list, &root->leaf_list);
} }
@@ -229,6 +186,8 @@ static inline node_t *_node_read(char **p, int depth)
return node; return node;
} }
/* wrapper for recursive function
*/
static inline node_t *node_read(char *p) static inline node_t *node_read(char *p)
{ {
char *tmp = p; char *tmp = p;
@@ -237,7 +196,7 @@ static inline node_t *node_read(char *p)
/* read input /* read input
*/ */
static int read_lines() static void read_lines()
{ {
size_t alloc = 0; size_t alloc = 0;
ssize_t buflen; ssize_t buflen;
@@ -246,8 +205,7 @@ static int read_lines()
lines[nlines][--buflen] = 0; lines[nlines][--buflen] = 0;
nlines++; nlines++;
} }
free(lines[nlines]); /* EOF */ free(lines[nlines]); /* EOF, need to be freed */
return nlines;
} }
/* free lines memory /* free lines memory
@@ -258,7 +216,7 @@ static void free_lines()
free(lines[i]); free(lines[i]);
} }
static inline s64 node_magnitude(node_t *node) static inline int node_magnitude(node_t *node)
{ {
if (!node->tree[LEFT]) if (!node->tree[LEFT])
return node->val; return node->val;
@@ -266,10 +224,10 @@ static inline s64 node_magnitude(node_t *node)
2 * node_magnitude(node->tree[RIGHT]); 2 * node_magnitude(node->tree[RIGHT]);
} }
static s64 part1() static int part1()
{ {
node_t *head = NULL, *next = NULL; node_t *head, *next;
s64 res; int res;
head = node_read(lines[0]); head = node_read(lines[0]);
for (int i = 1; i < nlines; ++i) { for (int i = 1; i < nlines; ++i) {
@@ -281,21 +239,21 @@ static s64 part1()
return res; return res;
} }
static s64 part2() static int part2()
{ {
node_t *list; node_t *list;
s64 max = 0, cur; int max = 0, cur;
/* calculate magnitude for any combination of two snailfish numbers */
for (int i = 0; i < nlines; ++i) { for (int i = 0; i < nlines; ++i) {
for (int j = 0; j < nlines; ++j) { for (int j = 0; j < nlines; ++j) {
if (j == i) if (j != i) {
continue; list = node_reduce(node_add(node_read(lines[i]),
list = node_reduce(node_add(node_read(lines[i]), node_read(lines[j])));
node_read(lines[j]))); if ((cur = node_magnitude(list)) > max)
cur = node_magnitude(list); max = cur;
if (cur > max) node_free(list);
max = cur; }
node_free(list);
} }
} }
return max; return max;
@@ -331,7 +289,7 @@ int main(int ac, char **av)
if (!(pool_nodes = pool_create("nodes", 1024, sizeof(node_t)))) if (!(pool_nodes = pool_create("nodes", 1024, sizeof(node_t))))
exit(1); exit(1);
read_lines(); read_lines();
printf("%s : res=%ld\n", *av, part == 1? part1(): part2()); printf("%s : res=%d\n", *av, part == 1? part1(): part2());
free_lines(); free_lines();
pool_destroy(pool_nodes); pool_destroy(pool_nodes);
exit(0); exit(0);