Compare commits
25 Commits
f54479189b
...
main
Author | SHA1 | Date | |
---|---|---|---|
ad6a39e82a | |||
3a857e4d53 | |||
f80a051177 | |||
129fa07787 | |||
1472082c86 | |||
e8bed49e13 | |||
83d70dcc7a | |||
56d2e63fac | |||
5c91de5d40 | |||
40a9c7b12e | |||
34b6cd7b57 | |||
5ad5c87fd8 | |||
11e7b45676 | |||
3f2a5648df | |||
0a3b404c4c | |||
a214d2b70d | |||
f490c2353e | |||
2ed6284bcd | |||
5fc204744a | |||
d1cf8d96b8 | |||
b285f74997 | |||
c949c64da2 | |||
357e8ce087 | |||
5cde9051ec | |||
111fde4fbd |
@@ -273,3 +273,45 @@ aoc.bash: res=399
|
|||||||
aoc-c: res=399
|
aoc-c: res=399
|
||||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||||
context-switch: 0+1, page-faults: 0+171
|
context-switch: 0+1, page-faults: 0+171
|
||||||
|
|
||||||
|
=========================================
|
||||||
|
================= day13 =================
|
||||||
|
=========================================
|
||||||
|
|
||||||
|
+++++++++++++++++ part 1
|
||||||
|
aoc-c: res=5843
|
||||||
|
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||||
|
context-switch: 0+1, page-faults: 0+192
|
||||||
|
|
||||||
|
+++++++++++++++++ part 2
|
||||||
|
aoc-c: res=26289
|
||||||
|
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||||
|
context-switch: 1+1, page-faults: 0+190
|
||||||
|
|
||||||
|
=========================================
|
||||||
|
================= day14 =================
|
||||||
|
=========================================
|
||||||
|
|
||||||
|
+++++++++++++++++ part 1
|
||||||
|
aoc-c: res=665
|
||||||
|
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||||
|
context-switch: 0+1, page-faults: 0+109
|
||||||
|
|
||||||
|
+++++++++++++++++ part 2
|
||||||
|
aoc-c: res=25434
|
||||||
|
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||||
|
context-switch: 0+1, page-faults: 0+121
|
||||||
|
|
||||||
|
=========================================
|
||||||
|
================= day15 =================
|
||||||
|
=========================================
|
||||||
|
|
||||||
|
+++++++++++++++++ part 1
|
||||||
|
aoc-c: res=5176944
|
||||||
|
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||||
|
context-switch: 0+1, page-faults: 0+152
|
||||||
|
|
||||||
|
+++++++++++++++++ part 2
|
||||||
|
aoc-c: res=13350458933732
|
||||||
|
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||||
|
context-switch: 0+1, page-faults: 0+88
|
||||||
|
@@ -70,12 +70,12 @@ cpp: aoc-c.i
|
|||||||
assembly: aoc-c.s
|
assembly: aoc-c.s
|
||||||
|
|
||||||
part1: aoc-c
|
part1: aoc-c
|
||||||
@$(TIME) aoc.bash -p 1 < $(INPUT) 2>&1
|
@#$(TIME) aoc.bash -p 1 < $(INPUT) 2>&1
|
||||||
@#$(TIME) aoc-c -p 1 < $(INPUT)
|
@$(TIME) aoc-c -p 1 < $(INPUT)
|
||||||
|
|
||||||
part2: aoc-c
|
part2: aoc-c
|
||||||
@$(TIME) aoc.bash -p 2 < $(INPUT) 2>&1
|
@#$(TIME) aoc.bash -p 2 < $(INPUT) 2>&1
|
||||||
@#$(TIME) aoc-c -p 2 < $(INPUT)
|
@$(TIME) aoc-c -p 2 < $(INPUT)
|
||||||
|
|
||||||
ccls: $(CCLSFILE)
|
ccls: $(CCLSFILE)
|
||||||
|
|
||||||
|
@@ -144,8 +144,6 @@ is the sum of the indices of those pairs?/
|
|||||||
|
|
||||||
Your puzzle answer was =5843=.
|
Your puzzle answer was =5843=.
|
||||||
|
|
||||||
The first half of this puzzle is complete! It provides one gold star: *
|
|
||||||
|
|
||||||
** --- Part Two ---
|
** --- Part Two ---
|
||||||
Now, you just need to put /all/ of the packets in the right order.
|
Now, you just need to put /all/ of the packets in the right order.
|
||||||
Disregard the blank lines in your list of received packets.
|
Disregard the blank lines in your list of received packets.
|
||||||
@@ -195,3 +193,5 @@ the divider packets are /10th/ and /14th/, and so the decoder key is
|
|||||||
|
|
||||||
Organize all of the packets into the correct order. /What is the decoder
|
Organize all of the packets into the correct order. /What is the decoder
|
||||||
key for the distress signal?/
|
key for the distress signal?/
|
||||||
|
|
||||||
|
Your puzzle answer was =26289=.
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/* aoc-c.c: Advent of Code 2022, day 13
|
/* aoc-c.c: Advent of Code 2022, day 13
|
||||||
*
|
*
|
||||||
* Copyright (C) 2022 Bruno Raoult ("br")
|
* Copyright (C) 2022-2023 Bruno Raoult ("br")
|
||||||
* Licensed under the GNU General Public License v3.0 or later.
|
* Licensed under the GNU General Public License v3.0 or later.
|
||||||
* Some rights reserved. See COPYING.
|
* Some rights reserved. See COPYING.
|
||||||
*
|
*
|
||||||
@@ -14,234 +14,157 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "br.h"
|
#include "br.h"
|
||||||
#include "debug.h"
|
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "pool.h"
|
#include "pool.h"
|
||||||
|
|
||||||
#include "aoc.h"
|
#include "aoc.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum { SUBLIST, INT } type_t;
|
||||||
NIL,
|
|
||||||
LIST,
|
|
||||||
//SUBLIST,
|
|
||||||
INT
|
|
||||||
} type_t;
|
|
||||||
|
|
||||||
char *types[] = {
|
typedef struct node { /* node */
|
||||||
"NIL",
|
|
||||||
"LIST",
|
|
||||||
//"SUBLIST",
|
|
||||||
"INT"
|
|
||||||
};
|
|
||||||
|
|
||||||
struct node;
|
|
||||||
typedef struct cons {
|
|
||||||
type_t type;
|
|
||||||
union {
|
|
||||||
//struct list_head node; /* same level node */
|
|
||||||
struct node *sub;
|
|
||||||
int value;
|
|
||||||
};
|
|
||||||
} cons_t;
|
|
||||||
|
|
||||||
#define CAR 0 /* always NUM or SUBLIST */
|
|
||||||
#define CDR 1 /* always LIST */
|
|
||||||
|
|
||||||
typedef struct node {
|
|
||||||
type_t car_t;
|
type_t car_t;
|
||||||
union {
|
union { /* CAR */
|
||||||
struct list_head sub;
|
struct list_head sub; /* sublist */
|
||||||
int value;
|
int value; /* value */
|
||||||
} car;
|
};
|
||||||
struct list_head cdr;
|
struct list_head cdr; /* CDR */
|
||||||
//cons_t cons[2];
|
|
||||||
} node_t;
|
} node_t;
|
||||||
|
|
||||||
typedef struct line {
|
typedef struct { /* packets ordered list */
|
||||||
int pos; /* position to parse */
|
struct list_head node; /* packet head */
|
||||||
char *s;
|
struct list_head list; /* packets lists */
|
||||||
} line_t;
|
} packets_t;
|
||||||
|
LIST_HEAD(packets);
|
||||||
|
|
||||||
pool_t *pool_nodes;
|
/* dummy node for integer vs list */
|
||||||
|
static struct list_head dummy_list; /* tentative definition */
|
||||||
|
static node_t dummy = {
|
||||||
|
.car_t = INT, .value = 0, .cdr = LIST_HEAD_INIT(dummy_list)
|
||||||
|
};
|
||||||
|
static struct list_head dummy_list = LIST_HEAD_INIT(dummy.cdr);
|
||||||
|
|
||||||
static node_t *getnode()
|
pool_t *pool_node, *pool_packets;
|
||||||
|
|
||||||
|
/* int getnode - allocate and initialize a new node
|
||||||
|
* @type: The node type_t (INT/LIST)
|
||||||
|
* @val: The value if @type is INT
|
||||||
|
*
|
||||||
|
* Return: The new node.
|
||||||
|
*/
|
||||||
|
static node_t *getnode(type_t type, int val)
|
||||||
{
|
{
|
||||||
node_t *node = pool_get(pool_nodes);
|
node_t *node = pool_get(pool_node);
|
||||||
node->car_t = NIL;
|
node->car_t = type;
|
||||||
INIT_LIST_HEAD(&node->cdr);
|
INIT_LIST_HEAD(&node->cdr);
|
||||||
log_f(4, "\n");
|
if (type == INT)
|
||||||
|
node->value = val;
|
||||||
|
else
|
||||||
|
INIT_LIST_HEAD(&node->sub);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_tree(struct list_head *head, int level)
|
/* int compare tree - compare two packets trees
|
||||||
{
|
* @h1: The first packet list head
|
||||||
struct node *cur;
|
* @h2: The second packet list head
|
||||||
log_f(4, "head=%p lev=%d\n", head, level);
|
*
|
||||||
printf("( ");
|
* Return: 1 if h1 and h2 are ordered, -1 if not ordered, 0 if undecided
|
||||||
//if (!list_empty(&node->cdr)) {
|
*/
|
||||||
list_for_each_entry(cur, head, cdr) {
|
|
||||||
if (cur->car_t == INT)
|
|
||||||
printf("%d ", cur->car.value);
|
|
||||||
else if (cur->car_t == NIL)
|
|
||||||
printf("ERROR ");
|
|
||||||
else
|
|
||||||
print_tree(&cur->car.sub, level + 2);
|
|
||||||
}
|
|
||||||
//} else {
|
|
||||||
//printf("nil ");
|
|
||||||
//}
|
|
||||||
printf(") ");
|
|
||||||
if (!level)
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static int compare_tree(struct list_head *h1, struct list_head *h2)
|
static int compare_tree(struct list_head *h1, struct list_head *h2)
|
||||||
{
|
{
|
||||||
struct list_head *cur1, *cur2;
|
struct list_head *cur1, *cur2;
|
||||||
//struct list_head *h1, *h2;
|
node_t *n1, *n2;
|
||||||
node_t *tmp, *n1, *n2;
|
|
||||||
int res;
|
int res;
|
||||||
log_f(3, "h1=%p h2=%p\n", h1, h2);
|
|
||||||
|
|
||||||
/* check for NIL */
|
|
||||||
/*
|
|
||||||
* if (n1->car_t == NIL) {
|
|
||||||
* log(3, "n1 is NIL\n");
|
|
||||||
* return n2->car_t == NIL? 0: 1;
|
|
||||||
* }
|
|
||||||
* if (n2->car_t == NIL) {
|
|
||||||
* log(3, "n2 is NIL\n");
|
|
||||||
* return -1;
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
|
|
||||||
//h1 = &n1->cdr;
|
|
||||||
//h2 = &n2->cdr;
|
|
||||||
/* get lists first entries */
|
/* get lists first entries */
|
||||||
cur1 = h1->next;
|
cur1 = h1->next;
|
||||||
cur2 = h2->next;
|
cur2 = h2->next;
|
||||||
|
|
||||||
//if (!list_empty(h1) && !list_empty(h2)) {
|
while (cur1 != h1 && cur2 != h2) {
|
||||||
while (cur1 != h1 && cur2 != h2) {
|
|
||||||
n1 = container_of(cur1, node_t, cdr);
|
n1 = container_of(cur1, node_t, cdr);
|
||||||
n2 = container_of(cur2, node_t, cdr);
|
n2 = container_of(cur2, node_t, cdr);
|
||||||
|
|
||||||
if (n1->car_t == n2->car_t) {
|
if (n1->car_t == n2->car_t) {
|
||||||
if (n1->car_t == INT) {
|
if (n1->car_t == INT) {
|
||||||
if (n1->car.value < n2->car.value) {
|
if (n1->value < n2->value) {
|
||||||
log(3, "car1=%d < car2=%d, returning 1\n", n1->car.value,
|
|
||||||
n2->car.value);
|
|
||||||
return 1;
|
return 1;
|
||||||
} else if (n1->car.value > n2->car.value) {
|
} else if (n1->value > n2->value) {
|
||||||
log(3, "car1=%d > car2=%d, returning -1\n", n1->car.value,
|
|
||||||
n2->car.value);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
log(3, "car1 == car2 == %d, skipping\n", n1->car.value);
|
|
||||||
} else { /* both sublists */
|
} else { /* both sublists */
|
||||||
res = compare_tree(&n1->car.sub, &n2->car.sub);
|
if ((res = compare_tree(&n1->sub, &n2->sub)))
|
||||||
if (res)
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
} else { /* one number, one list */
|
} else { /* one number, one list */
|
||||||
tmp = getnode();
|
|
||||||
//INIT_LIST_HEAD(&tmp->car.sub);
|
|
||||||
tmp->car_t = INT;
|
|
||||||
if (n1->car_t == INT) {
|
if (n1->car_t == INT) {
|
||||||
log(3, "car1 == INT, adding a node\n");
|
dummy.value = n1->value;
|
||||||
tmp->car.value = n1->car.value;
|
res = compare_tree(&dummy_list, &n2->sub);
|
||||||
n1->car_t = LIST;
|
|
||||||
INIT_LIST_HEAD(&n1->car.sub);
|
|
||||||
list_add(&tmp->cdr, &n1->car.sub);
|
|
||||||
//n1->car.sub = tmp;
|
|
||||||
//print_tree()
|
|
||||||
} else {
|
} else {
|
||||||
log(3, "car2 == INT, adding a node\n");
|
dummy.value = n2->value;
|
||||||
tmp->car.value = n2->car.value;
|
res = compare_tree(&n1->sub, &dummy_list);
|
||||||
n2->car_t = LIST;
|
|
||||||
INIT_LIST_HEAD(&n2->car.sub);
|
|
||||||
list_add(&tmp->cdr, &n2->car.sub);
|
|
||||||
//n2->car.sub = tmp;
|
|
||||||
}
|
}
|
||||||
res = compare_tree(&n1->car.sub, &n2->car.sub);
|
|
||||||
if (res)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
//continue;
|
|
||||||
}
|
}
|
||||||
//next:
|
|
||||||
cur1 = cur1->next;
|
cur1 = cur1->next;
|
||||||
cur2 = cur2->next;
|
cur2 = cur2->next;
|
||||||
}
|
}
|
||||||
//} else {
|
|
||||||
// log(3, "some list empty\n");
|
|
||||||
//}
|
|
||||||
/* at least one list came to end */
|
/* at least one list came to end */
|
||||||
if (cur1 == h1 && cur2 == h2) { /* both are ending */
|
if (cur1 == h1 && cur2 == h2) /* both are ending */
|
||||||
log(3, "Both sides Left side ran out of items, undecided\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
} else if (cur1 == h1) { /* first list did end */
|
else if (cur1 == h1) /* first list did end */
|
||||||
log(3, "Left side ran out of items, so inputs are in the right order\n");
|
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
else
|
||||||
log(3, "Right side ran out of items, so inputs are not in the right order\n");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct list_head *create_tree(char *s, int *consumed, int level, struct list_head *head)
|
/* int add_node - add a packet to the sorted packets list
|
||||||
|
* @new: The new packets list head
|
||||||
|
*
|
||||||
|
* Return: The new packet position in list (first is 1)
|
||||||
|
*/
|
||||||
|
static int add_node(packets_t *new)
|
||||||
|
{
|
||||||
|
packets_t *first, *iter;
|
||||||
|
struct list_head *node_next = &packets;
|
||||||
|
int num = 1;
|
||||||
|
|
||||||
|
if (list_empty(&packets))
|
||||||
|
goto ins_node;
|
||||||
|
first = iter = list_first_entry(&packets, packets_t, list);
|
||||||
|
do {
|
||||||
|
if (compare_tree(&new->node, &iter->node) > 0) {
|
||||||
|
node_next = &iter->list;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
iter = list_entry(iter->list.next, packets_t, list);
|
||||||
|
num++;
|
||||||
|
} while (iter != first);
|
||||||
|
ins_node:
|
||||||
|
list_add_tail(&new->list, node_next);
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct list_head *create_tree(char *s, int *consumed, struct list_head *head)
|
||||||
{
|
{
|
||||||
node_t *node = NULL;
|
node_t *node = NULL;
|
||||||
LIST_HEAD(sub);
|
LIST_HEAD(sub);
|
||||||
int num = 0, val, depth = 0, subconsumed;
|
int val, depth = 0, subconsumed;
|
||||||
//LIST_HEAD(head);
|
|
||||||
*consumed = 1;
|
*consumed = 1;
|
||||||
if (*s != '[') {
|
|
||||||
printf("error 0\n");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
INIT_LIST_HEAD(head);
|
INIT_LIST_HEAD(head);
|
||||||
//head = getnode();
|
|
||||||
log_f(3, "create_tree(%s)\n", s);
|
|
||||||
for (; *s; s++, (*consumed)++) {
|
for (; *s; s++, (*consumed)++) {
|
||||||
log(4, "L=%d examining %c num=%d depth=%d\n", level, *s, num, depth);
|
|
||||||
val = 0;
|
|
||||||
switch (*s) {
|
switch (*s) {
|
||||||
case '[':
|
case '[':
|
||||||
switch (++depth) {
|
if (++depth == 2) { /* we skip first depth level */
|
||||||
case 1: /* first level */
|
node = getnode(SUBLIST, 0);
|
||||||
break;
|
list_add_tail(&node->cdr, head);
|
||||||
case 2: /* second level (nested list) */
|
create_tree(s, &subconsumed, &node->sub);
|
||||||
node = getnode();
|
s += subconsumed - 1;
|
||||||
node->car_t = LIST;
|
*consumed += subconsumed - 1;
|
||||||
INIT_LIST_HEAD(&node->car.sub);
|
depth--;
|
||||||
create_tree(s, &subconsumed, level + 1, &node->car.sub);
|
|
||||||
s += subconsumed - 1;
|
|
||||||
*consumed += subconsumed - 1;
|
|
||||||
log(4, "after create_tree: cons=%d s=%s\n", subconsumed, s);
|
|
||||||
//if (num == 0) {
|
|
||||||
// head->car_t = SUBLIST;
|
|
||||||
// head->car.sub = sub;
|
|
||||||
//} else {
|
|
||||||
//list_add(&sub, &node->car.sub); /* add sublist to new node */
|
|
||||||
list_add_tail(&node->cdr, head); /* add node to current level */
|
|
||||||
puts("ZOBI");
|
|
||||||
print_tree(&node->car.sub, 0);
|
|
||||||
puts("ZOBa");
|
|
||||||
//sleep(1);
|
|
||||||
print_tree(head, 0);
|
|
||||||
//}
|
|
||||||
depth--;
|
|
||||||
num++;
|
|
||||||
break;
|
|
||||||
default: /* should not happen */
|
|
||||||
printf("error 1\n");
|
|
||||||
exit(0);
|
|
||||||
break; /* not reached */
|
|
||||||
}
|
}
|
||||||
//num++;
|
|
||||||
break;
|
break;
|
||||||
case ',':
|
case ',':
|
||||||
break;
|
break;
|
||||||
@@ -253,23 +176,12 @@ static struct list_head *create_tree(char *s, int *consumed, int level, struct l
|
|||||||
sscanf(s, "%d%n", &val, &subconsumed);
|
sscanf(s, "%d%n", &val, &subconsumed);
|
||||||
*consumed += subconsumed - 1;
|
*consumed += subconsumed - 1;
|
||||||
s += subconsumed - 1;
|
s += subconsumed - 1;
|
||||||
log(4, "got integer=%d num=%d depth=%d chars=%d\n", val, num, depth, subconsumed);
|
node = getnode(INT, val);
|
||||||
//if (num == 0) {
|
|
||||||
// head->car_t = INT;
|
|
||||||
// head->car.value = val;
|
|
||||||
//} else {
|
|
||||||
node = getnode();
|
|
||||||
node->car_t = INT;
|
|
||||||
node->car.value = val;
|
|
||||||
list_add_tail(&node->cdr, head);
|
list_add_tail(&node->cdr, head);
|
||||||
//}
|
|
||||||
//print_tree(head, 0);
|
|
||||||
num++;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end:
|
end:
|
||||||
log(4, "returning from create_tree, consumed=%d head=%p\n", *consumed, head);
|
|
||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,77 +190,51 @@ static int parse()
|
|||||||
size_t alloc = 0;
|
size_t alloc = 0;
|
||||||
ssize_t buflen;
|
ssize_t buflen;
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
int i = 0;
|
packets_t *head[2];
|
||||||
struct list_head head[2];
|
int i = 0, dummy, res = 0;
|
||||||
int consumed;
|
|
||||||
int group = 1, res = 0, tmp;
|
|
||||||
//line_t line;
|
|
||||||
|
|
||||||
while ((buflen = getline(&buf, &alloc, stdin)) > 0) {
|
while ((buflen = getline(&buf, &alloc, stdin)) > 0) {
|
||||||
buf[--buflen] = 0;
|
buf[--buflen] = 0;
|
||||||
if (!buflen) {
|
if (buflen > 0) { /* non empty line */
|
||||||
//i = 0;
|
head[i % 2] = pool_get(pool_packets);
|
||||||
//printf("++++ node 1 = %p\n", node[1]);
|
create_tree(buf, &dummy, &head[i % 2]->node);
|
||||||
printf("++++ node 0 = %p\n", &head[0]);
|
add_node(head[i % 2]);
|
||||||
print_tree(&head[0], 0);
|
}
|
||||||
printf("++++ node 1 = %p\n", &head[1]);
|
if (buflen != 0) { /* non empty line or EOF */
|
||||||
print_tree(&head[1], 0);
|
if (i % 2 && compare_tree(&head[0]->node, &head[1]->node) == 1)
|
||||||
tmp = compare_tree(&head[0], &head[1]);
|
res += (i >> 1) + 1; /* (i / 2) + 1 */
|
||||||
printf("group = %d compare_tree() = %d\n", group, tmp);
|
|
||||||
if (tmp == 1) {
|
|
||||||
res += group;
|
|
||||||
printf("group = %d: right order res:%d -> %d\n", group, res - group, res);
|
|
||||||
}
|
|
||||||
group++;
|
|
||||||
printf("\n\n");
|
|
||||||
//pool_add(pool_nodes, node[0]);
|
|
||||||
//pool_add(pool_nodes, node[1]);
|
|
||||||
//node[0] = node[1] = NULL;
|
|
||||||
//exit(0);
|
|
||||||
} else {
|
|
||||||
//node[i % 2] = getnode();
|
|
||||||
create_tree(buf, &consumed, 0, &head[i % 2]);
|
|
||||||
printf("setting node %d\n\n", i%2);
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("++++ node 0 = %p\n", &head[0]);
|
return res;
|
||||||
print_tree(&head[0], 0);
|
}
|
||||||
printf("++++ node 1 = %p\n", &head[1]);
|
|
||||||
print_tree(&head[1], 0);
|
static int part1()
|
||||||
tmp = compare_tree(&head[0], &head[1]);
|
{
|
||||||
printf("group = %d compare_tree() = %d\n", group, tmp);
|
return parse();
|
||||||
if (tmp == 1) {
|
}
|
||||||
res += group;
|
|
||||||
printf("group = %d: right order res:%d -> %d\n", group, res - group, res);
|
static int part2()
|
||||||
|
{
|
||||||
|
char *dividers[] = { "[[2]]", "[[6]]" };
|
||||||
|
int dummy, res = 1;
|
||||||
|
parse();
|
||||||
|
for (ulong i = 0; i < ARRAY_SIZE(dividers); ++i) {
|
||||||
|
packets_t *h = pool_get(pool_packets);
|
||||||
|
create_tree(dividers[i], &dummy, &h->node);
|
||||||
|
res *= add_node(h);
|
||||||
}
|
}
|
||||||
printf("\n\n");
|
return res;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static u64 doit()
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u64 part1()
|
|
||||||
{
|
|
||||||
return doit();
|
|
||||||
}
|
|
||||||
|
|
||||||
static u64 part2()
|
|
||||||
{
|
|
||||||
return doit();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(int ac, char **av)
|
int main(int ac, char **av)
|
||||||
{
|
{
|
||||||
int part = parseargs(ac, av);
|
int part = parseargs(ac, av);
|
||||||
pool_nodes = pool_create("nodes", 512, sizeof(node_t));
|
pool_node = pool_create("node", 512, sizeof(node_t));
|
||||||
//u32 foo=0x12345678;
|
pool_packets = pool_create("packets", 512, sizeof(packets_t));
|
||||||
parse();
|
|
||||||
printf("%s: res=%lu\n", *av, part == 1? part1(): part2());
|
printf("%s: res=%d\n", *av, part == 1? part1(): part2());
|
||||||
pool_destroy(pool_nodes);
|
pool_destroy(pool_node);
|
||||||
|
pool_destroy(pool_packets);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
111
2022/day14/Makefile
Normal file
111
2022/day14/Makefile
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
# AOC daily Makefile - GNU make only.
|
||||||
|
#
|
||||||
|
# Copyright (C) 2021-2022 Bruno Raoult ("br")
|
||||||
|
# Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
# Some rights reserved. See COPYING.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along with this
|
||||||
|
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
#
|
||||||
|
|
||||||
|
INPUT := input/input.txt
|
||||||
|
SHELL := /bin/bash
|
||||||
|
|
||||||
|
CC := gcc
|
||||||
|
BEAR := bear
|
||||||
|
CCLSFILE:= compile_commands.json
|
||||||
|
|
||||||
|
LIB := aoc_$(shell uname -m)
|
||||||
|
INCDIR := ../include
|
||||||
|
LIBDIR := ../lib
|
||||||
|
LDFLAGS := -L$(LIBDIR)
|
||||||
|
#LDLIB := -l$(LIB) -lm
|
||||||
|
LDLIB := -l$(LIB)
|
||||||
|
|
||||||
|
export LD_LIBRARY_PATH = $(LIBDIR)
|
||||||
|
|
||||||
|
CFLAGS += -std=gnu11
|
||||||
|
CFLAGS += -O2
|
||||||
|
CFLAGS += -g
|
||||||
|
# for gprof
|
||||||
|
# CFLAGS += -pg
|
||||||
|
CFLAGS += -Wall
|
||||||
|
CFLAGS += -Wextra
|
||||||
|
CFLAGS += -march=native
|
||||||
|
# Next one may be useful for valgrind (some invalid instructions)
|
||||||
|
# CFLAGS += -mno-tbm
|
||||||
|
CFLAGS += -Wmissing-declarations
|
||||||
|
CFLAGS += -Wno-unused-result
|
||||||
|
|
||||||
|
CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
|
||||||
|
CFLAGS += -DDEBUG_POOL # memory pools management
|
||||||
|
|
||||||
|
VALGRIND := valgrind
|
||||||
|
VALGRINDFLAGS := --leak-check=full --show-leak-kinds=all --track-origins=yes \
|
||||||
|
--sigill-diagnostics=yes --quiet --show-error-list=yes
|
||||||
|
|
||||||
|
|
||||||
|
TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n"
|
||||||
|
export PATH := .:$(PATH)
|
||||||
|
|
||||||
|
.PHONY: clean all compile assembly memcheck memcheck1 memcheck2 part1 part2 ccls bear org
|
||||||
|
|
||||||
|
all: README.org ccls part1 part2
|
||||||
|
|
||||||
|
memcheck: memcheck1 memcheck2
|
||||||
|
|
||||||
|
memcheck1: aoc-c
|
||||||
|
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 1 < $(INPUT)
|
||||||
|
|
||||||
|
memcheck2: aoc-c
|
||||||
|
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 2 < $(INPUT)
|
||||||
|
@#@valgrind -s --track-origins=yes aoc-c -p 2 < $(INPUT)
|
||||||
|
|
||||||
|
compile: aoc-c
|
||||||
|
|
||||||
|
cpp: aoc-c.i
|
||||||
|
|
||||||
|
assembly: aoc-c.s
|
||||||
|
|
||||||
|
part1: aoc-c
|
||||||
|
@#$(TIME) aoc.bash -p 1 < $(INPUT) 2>&1
|
||||||
|
@$(TIME) aoc-c -p 1 < $(INPUT)
|
||||||
|
|
||||||
|
part2: aoc-c
|
||||||
|
@#$(TIME) aoc.bash -p 2 < $(INPUT) 2>&1
|
||||||
|
@$(TIME) aoc-c -p 2 < $(INPUT)
|
||||||
|
|
||||||
|
ccls: $(CCLSFILE)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -f aoc-c core* vgcore* gmon.out aoc-c.s aoc-c.i README.html compile_commands.json
|
||||||
|
|
||||||
|
aoc-c: aoc-c.c common.c
|
||||||
|
@echo compiling $<
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $^ $(LDLIB) -o $@
|
||||||
|
|
||||||
|
# generate pre-processed file (.i) and assembler (.s)
|
||||||
|
%.i: %.c
|
||||||
|
@echo generating $@
|
||||||
|
@$(CC) -E $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||||
|
|
||||||
|
%.s: %.c
|
||||||
|
@echo generating $@
|
||||||
|
@$(CC) -S -fverbose-asm $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||||
|
|
||||||
|
# generate README.org from README.html (must cleanup !)
|
||||||
|
org: README.org
|
||||||
|
|
||||||
|
%.org: %.html
|
||||||
|
@echo generating $@. Cleanup before commit !
|
||||||
|
@pandoc $< -o $@
|
||||||
|
|
||||||
|
# generate compile_commands.json
|
||||||
|
$(CCLSFILE): aoc-c.c Makefile
|
||||||
|
$(BEAR) -- make clean compile
|
||||||
|
|
||||||
|
bear: clean
|
||||||
|
@touch .ccls-root
|
||||||
|
@$(BEAR) -- make compile
|
232
2022/day14/README.org
Normal file
232
2022/day14/README.org
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
** --- Day 14: Regolith Reservoir ---
|
||||||
|
The distress signal leads you to a giant waterfall! Actually, hang on -
|
||||||
|
the signal seems like it's coming from the waterfall itself, and that
|
||||||
|
doesn't make any sense. However, you do notice a little path that leads
|
||||||
|
/behind/ the waterfall.
|
||||||
|
|
||||||
|
Correction: the distress signal leads you behind a giant waterfall!
|
||||||
|
There seems to be a large cave system here, and the signal definitely
|
||||||
|
leads further inside.
|
||||||
|
|
||||||
|
As you begin to make your way deeper underground, you feel the ground
|
||||||
|
rumble for a moment. Sand begins pouring into the cave! If you don't
|
||||||
|
quickly figure out where the sand is going, you could quickly become
|
||||||
|
trapped!
|
||||||
|
|
||||||
|
Fortunately, your [[/2018/day/17][familiarity]] with analyzing the path
|
||||||
|
of falling material will come in handy here. You scan a two-dimensional
|
||||||
|
vertical slice of the cave above you (your puzzle input) and discover
|
||||||
|
that it is mostly /air/ with structures made of /rock/.
|
||||||
|
|
||||||
|
Your scan traces the path of each solid rock structure and reports the
|
||||||
|
=x,y= coordinates that form the shape of the path, where =x= represents
|
||||||
|
distance to the right and =y= represents distance down. Each path
|
||||||
|
appears as a single line of text in your scan. After the first point of
|
||||||
|
each path, each point indicates the end of a straight horizontal or
|
||||||
|
vertical line to be drawn from the previous point. For example:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
498,4 -> 498,6 -> 496,6
|
||||||
|
503,4 -> 502,4 -> 502,9 -> 494,9
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
This scan means that there are two paths of rock; the first path
|
||||||
|
consists of two straight lines, and the second path consists of three
|
||||||
|
straight lines. (Specifically, the first path consists of a line of rock
|
||||||
|
from =498,4= through =498,6= and another line of rock from =498,6=
|
||||||
|
through =496,6=.)
|
||||||
|
|
||||||
|
The sand is pouring into the cave from point =500,0=.
|
||||||
|
|
||||||
|
Drawing rock as =#=, air as =.=, and the source of the sand as =+=, this
|
||||||
|
becomes:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
4 5 5
|
||||||
|
9 0 0
|
||||||
|
4 0 3
|
||||||
|
0 ......+...
|
||||||
|
1 ..........
|
||||||
|
2 ..........
|
||||||
|
3 ..........
|
||||||
|
4 ....#...##
|
||||||
|
5 ....#...#.
|
||||||
|
6 ..###...#.
|
||||||
|
7 ........#.
|
||||||
|
8 ........#.
|
||||||
|
9 #########.
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
Sand is produced /one unit at a time/, and the next unit of sand is not
|
||||||
|
produced until the previous unit of sand /comes to rest/. A unit of sand
|
||||||
|
is large enough to fill one tile of air in your scan.
|
||||||
|
|
||||||
|
A unit of sand always falls /down one step/ if possible. If the tile
|
||||||
|
immediately below is blocked (by rock or sand), the unit of sand
|
||||||
|
attempts to instead move diagonally /one step down and to the left/. If
|
||||||
|
that tile is blocked, the unit of sand attempts to instead move
|
||||||
|
diagonally /one step down and to the right/. Sand keeps moving as long
|
||||||
|
as it is able to do so, at each step trying to move down, then
|
||||||
|
down-left, then down-right. If all three possible destinations are
|
||||||
|
blocked, the unit of sand /comes to rest/ and no longer moves, at which
|
||||||
|
point the next unit of sand is created back at the source.
|
||||||
|
|
||||||
|
So, drawing sand that has come to rest as =o=, the first unit of sand
|
||||||
|
simply falls straight down and then stops:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
......+...
|
||||||
|
..........
|
||||||
|
..........
|
||||||
|
..........
|
||||||
|
....#...##
|
||||||
|
....#...#.
|
||||||
|
..###...#.
|
||||||
|
........#.
|
||||||
|
......o.#.
|
||||||
|
#########.
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
The second unit of sand then falls straight down, lands on the first
|
||||||
|
one, and then comes to rest to its left:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
......+...
|
||||||
|
..........
|
||||||
|
..........
|
||||||
|
..........
|
||||||
|
....#...##
|
||||||
|
....#...#.
|
||||||
|
..###...#.
|
||||||
|
........#.
|
||||||
|
.....oo.#.
|
||||||
|
#########.
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
After a total of five units of sand have come to rest, they form this
|
||||||
|
pattern:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
......+...
|
||||||
|
..........
|
||||||
|
..........
|
||||||
|
..........
|
||||||
|
....#...##
|
||||||
|
....#...#.
|
||||||
|
..###...#.
|
||||||
|
......o.#.
|
||||||
|
....oooo#.
|
||||||
|
#########.
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
After a total of 22 units of sand:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
......+...
|
||||||
|
..........
|
||||||
|
......o...
|
||||||
|
.....ooo..
|
||||||
|
....#ooo##
|
||||||
|
....#ooo#.
|
||||||
|
..###ooo#.
|
||||||
|
....oooo#.
|
||||||
|
...ooooo#.
|
||||||
|
#########.
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
Finally, only two more units of sand can possibly come to rest:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
......+...
|
||||||
|
..........
|
||||||
|
......o...
|
||||||
|
.....ooo..
|
||||||
|
....#ooo##
|
||||||
|
...o#ooo#.
|
||||||
|
..###ooo#.
|
||||||
|
....oooo#.
|
||||||
|
.o.ooooo#.
|
||||||
|
#########.
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
Once all =24= units of sand shown above have come to rest, all further
|
||||||
|
sand flows out the bottom, falling into the endless void. Just for fun,
|
||||||
|
the path any new sand takes before falling forever is shown here with
|
||||||
|
=~=:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
.......+...
|
||||||
|
.......~...
|
||||||
|
......~o...
|
||||||
|
.....~ooo..
|
||||||
|
....~#ooo##
|
||||||
|
...~o#ooo#.
|
||||||
|
..~###ooo#.
|
||||||
|
..~..oooo#.
|
||||||
|
.~o.ooooo#.
|
||||||
|
~#########.
|
||||||
|
~..........
|
||||||
|
~..........
|
||||||
|
~..........
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
Using your scan, simulate the falling sand. /How many units of sand come
|
||||||
|
to rest before sand starts flowing into the abyss below?/
|
||||||
|
|
||||||
|
Your puzzle answer was =665=.
|
||||||
|
|
||||||
|
** --- Part Two ---
|
||||||
|
You realize you misread the scan. There isn't an endless void at the
|
||||||
|
bottom of the scan - there's floor, and you're standing on it!
|
||||||
|
|
||||||
|
You don't have time to scan the floor, so assume the floor is an
|
||||||
|
infinite horizontal line with a =y= coordinate equal to /two plus the
|
||||||
|
highest =y= coordinate/ of any point in your scan.
|
||||||
|
|
||||||
|
In the example above, the highest =y= coordinate of any point is =9=,
|
||||||
|
and so the floor is at =y=11=. (This is as if your scan contained one
|
||||||
|
extra rock path like =-infinity,11 -> infinity,11=.) With the added
|
||||||
|
floor, the example above now looks like this:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
...........+........
|
||||||
|
....................
|
||||||
|
....................
|
||||||
|
....................
|
||||||
|
.........#...##.....
|
||||||
|
.........#...#......
|
||||||
|
.......###...#......
|
||||||
|
.............#......
|
||||||
|
.............#......
|
||||||
|
.....#########......
|
||||||
|
....................
|
||||||
|
<-- etc #################### etc -->
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
To find somewhere safe to stand, you'll need to simulate falling sand
|
||||||
|
until a unit of sand comes to rest at =500,0=, blocking the source
|
||||||
|
entirely and stopping the flow of sand into the cave. In the example
|
||||||
|
above, the situation finally looks like this after =93= units of sand
|
||||||
|
come to rest:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
............o............
|
||||||
|
...........ooo...........
|
||||||
|
..........ooooo..........
|
||||||
|
.........ooooooo.........
|
||||||
|
........oo#ooo##o........
|
||||||
|
.......ooo#ooo#ooo.......
|
||||||
|
......oo###ooo#oooo......
|
||||||
|
.....oooo.oooo#ooooo.....
|
||||||
|
....oooooooooo#oooooo....
|
||||||
|
...ooo#########ooooooo...
|
||||||
|
..ooooo.......ooooooooo..
|
||||||
|
#########################
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
Using your scan, simulate the falling sand until the source of the sand
|
||||||
|
becomes blocked. /How many units of sand come to rest?/
|
||||||
|
|
||||||
|
Your puzzle answer was =25434=.
|
||||||
|
|
||||||
|
Both parts of this puzzle are complete! They provide two gold stars: **
|
194
2022/day14/aoc-c.c
Normal file
194
2022/day14/aoc-c.c
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
/* aoc-c.c: Advent of Code 2022, day 14
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022-2023 Bruno Raoult ("br")
|
||||||
|
* Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
* Some rights reserved. See COPYING.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this
|
||||||
|
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "br.h"
|
||||||
|
#include "list.h"
|
||||||
|
#include "pool.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
#include "aoc.h"
|
||||||
|
|
||||||
|
pool_t *pool_segment;
|
||||||
|
|
||||||
|
#define INF (-1) /* found infinite fall position */
|
||||||
|
|
||||||
|
typedef enum { /* map cells */
|
||||||
|
EMPTY = '.',
|
||||||
|
STONE = '#',
|
||||||
|
SAND = 'o',
|
||||||
|
} type_t;
|
||||||
|
|
||||||
|
typedef struct segment {
|
||||||
|
int x1, y1, x2, y2;
|
||||||
|
struct list_head list;
|
||||||
|
} segment_t;
|
||||||
|
|
||||||
|
LIST_HEAD(segments);
|
||||||
|
|
||||||
|
typedef struct map {
|
||||||
|
int xmin, xmax, ymin, ymax;
|
||||||
|
int size_x, size_y;
|
||||||
|
int deltax, deltay;
|
||||||
|
int dropcol; /* drop sand here */
|
||||||
|
int dropped; /* number of sand units */
|
||||||
|
char *m;
|
||||||
|
} map_t;
|
||||||
|
|
||||||
|
#define XY(m, x, y) ((y) * m->size_x + (x))
|
||||||
|
#define P(m, x, y) (m->m[XY(m, (x), (y))])
|
||||||
|
|
||||||
|
static int drop_sand(struct map *m, int x, int y)
|
||||||
|
{
|
||||||
|
int ret = 0, tmp;
|
||||||
|
|
||||||
|
if (y >= m->ymax) /* part 1: nothing left under */
|
||||||
|
return INF;
|
||||||
|
|
||||||
|
if (P(m, x, y+1) == EMPTY) { /* down */
|
||||||
|
if ((tmp = drop_sand(m, x, y+1)) < 0)
|
||||||
|
return INF;
|
||||||
|
ret += tmp;
|
||||||
|
}
|
||||||
|
if (P(m, x-1, y+1) == EMPTY) { /* left */
|
||||||
|
if ((tmp = drop_sand(m, x-1, y+1)) < 0)
|
||||||
|
return INF;
|
||||||
|
ret += tmp;
|
||||||
|
}
|
||||||
|
if (P(m, x+1, y+1) == EMPTY) { /* right */
|
||||||
|
if ((tmp = drop_sand(m, x+1, y+1)) < 0)
|
||||||
|
return INF;
|
||||||
|
ret += tmp;
|
||||||
|
}
|
||||||
|
/* the 3 lower adjacent cells are filled */
|
||||||
|
P(m, x, y) = SAND;
|
||||||
|
m->dropped++;
|
||||||
|
if (y == 0) /* part 2 */
|
||||||
|
return INF;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct map *gen_map(struct map *m, int part)
|
||||||
|
{
|
||||||
|
segment_t *cur;
|
||||||
|
|
||||||
|
if (part == 1) {
|
||||||
|
m->size_x = (m->xmax - m->xmin) + 3;
|
||||||
|
m->size_y = m->ymax + 1;
|
||||||
|
m->deltax = m->xmin - 1;
|
||||||
|
} else {
|
||||||
|
m->ymax += 2;
|
||||||
|
m->xmin = 500 - m->ymax - 1;
|
||||||
|
m->xmax = 500 + m->ymax + 1;
|
||||||
|
m->deltax = m->xmin;
|
||||||
|
m->size_x = (m->xmax - m->xmin);
|
||||||
|
m->size_y = m->ymax + 3;
|
||||||
|
}
|
||||||
|
m->dropcol = 500 - m->deltax;
|
||||||
|
m->dropped = 0;
|
||||||
|
|
||||||
|
m->m = malloc(m->size_x * m->size_y);
|
||||||
|
memset(m->m, '.', m->size_x * m->size_y);
|
||||||
|
list_for_each_entry(cur, &segments, list) {
|
||||||
|
int x1 = cur->x1 - m->deltax, y1 = cur->y1 - m->deltay,
|
||||||
|
x2 = cur->x2 - m->deltax, y2 = cur->y2 - m->deltay;
|
||||||
|
int dx = 0, dy = 0;
|
||||||
|
if (x1 == x2)
|
||||||
|
dy = y2 - y1 > 0 ? 1 : -1;
|
||||||
|
else
|
||||||
|
dx = x2 - x1 > 0 ? 1 : -1;
|
||||||
|
do {
|
||||||
|
P(m, x1, y1) = '#';
|
||||||
|
x1 += dx, y1 += dy;
|
||||||
|
} while (x1 != x2 || y1 != y2);
|
||||||
|
P(m, x2, y2) = '#';
|
||||||
|
}
|
||||||
|
if (part == 2)
|
||||||
|
for (int i = 0; i < m->size_x; ++i)
|
||||||
|
P(m, m->xmin - m->deltax + i, m->ymax) = STONE;
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct map *parse(map_t *m)
|
||||||
|
{
|
||||||
|
size_t alloc = 0;
|
||||||
|
ssize_t buflen;
|
||||||
|
char *buf = NULL, *cur;
|
||||||
|
int i, scanned;
|
||||||
|
int x1, y1, x2, y2, x, y, n;
|
||||||
|
segment_t *segment;
|
||||||
|
|
||||||
|
while ((buflen = getline(&buf, &alloc, stdin)) > 0) {
|
||||||
|
i = 0;
|
||||||
|
buf[--buflen] = 0;
|
||||||
|
cur = buf;
|
||||||
|
while (1) {
|
||||||
|
scanned = sscanf(cur, "%d,%d ->%n", &x, &y, &n);
|
||||||
|
if (scanned != 2)
|
||||||
|
break;
|
||||||
|
m->xmin = min(x, m->xmin);
|
||||||
|
m->xmax = max(x, m->xmax);
|
||||||
|
m->ymin = min(y, m->ymin);
|
||||||
|
m->ymax = max(y, m->ymax);
|
||||||
|
if (i) {
|
||||||
|
x1 = x2;
|
||||||
|
y1 = y2;
|
||||||
|
}
|
||||||
|
x2 = x;
|
||||||
|
y2 = y;
|
||||||
|
if (!i) /* first point */
|
||||||
|
goto next;
|
||||||
|
segment = pool_get(pool_segment);
|
||||||
|
segment->x1 = x1;
|
||||||
|
segment->y1 = y1;
|
||||||
|
segment->x2 = x2;
|
||||||
|
segment->y2 = y2;
|
||||||
|
list_add_tail(&segment->list, &segments);
|
||||||
|
next:
|
||||||
|
i++;
|
||||||
|
cur += n;
|
||||||
|
if (cur - buf >= buflen)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(buf);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int doit(map_t *m, int part)
|
||||||
|
{
|
||||||
|
m = gen_map(parse(m), part);
|
||||||
|
drop_sand(m, m->dropcol, 0);
|
||||||
|
return m->dropped;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int ac, char **av)
|
||||||
|
{
|
||||||
|
int part = parseargs(ac, av);
|
||||||
|
static map_t m;
|
||||||
|
m.xmin = INT_MAX; m.xmax = INT_MIN;
|
||||||
|
m.ymin = INT_MAX, m.ymax = INT_MIN;
|
||||||
|
|
||||||
|
pool_segment = pool_create("segment", 512, sizeof(segment_t));
|
||||||
|
|
||||||
|
printf("%s: res=%d\n", *av, doit(&m, part));
|
||||||
|
free(m.m);
|
||||||
|
pool_destroy(pool_segment);
|
||||||
|
exit(0);
|
||||||
|
}
|
17
2022/day14/aoc.h
Normal file
17
2022/day14/aoc.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/* aoc.c: Advent of Code 2022
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 Bruno Raoult ("br")
|
||||||
|
* Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
* Some rights reserved. See COPYING.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this
|
||||||
|
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
*/
|
||||||
|
#ifndef _AOC_H_
|
||||||
|
#define _AOC_H_
|
||||||
|
|
||||||
|
extern int parseargs(int ac, char**av);
|
||||||
|
|
||||||
|
#endif /* _AOC_H_ */
|
68
2022/day14/common.bash
Normal file
68
2022/day14/common.bash
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# common.bash: Advent of Code 2022, common bash functions
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Bruno Raoult ("br")
|
||||||
|
# Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
# Some rights reserved. See COPYING.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along with this
|
||||||
|
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
|
||||||
|
# shellcheck disable=2034
|
||||||
|
export cmdname=${0##*/}
|
||||||
|
export debug=0
|
||||||
|
export res
|
||||||
|
export LANG=C
|
||||||
|
|
||||||
|
shopt -s extglob
|
||||||
|
set -o noglob
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
printf "usage: %s [-d DEBUG] [-p PART]\n" "$cmdname"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
checkargs() {
|
||||||
|
local part=1
|
||||||
|
while getopts p:d: todo; do
|
||||||
|
case "$todo" in
|
||||||
|
d)
|
||||||
|
if [[ "$OPTARG" =~ ^[[:digit:]+]$ ]]; then
|
||||||
|
debug="$OPTARG"
|
||||||
|
else
|
||||||
|
printf "%s: illegal [%s] debug level.\n" "$CMD" "$OPTARG"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
p)
|
||||||
|
if [[ "$OPTARG" =~ ^[12]$ ]]; then
|
||||||
|
part="$OPTARG"
|
||||||
|
else
|
||||||
|
printf "%s: illegal [%s] part.\n" "$CMD" "$OPTARG"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
# Now check remaining argument (backup directory)
|
||||||
|
shift $((OPTIND - 1))
|
||||||
|
|
||||||
|
(( $# > 1 )) && usage
|
||||||
|
return "$part"
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
local -i part
|
||||||
|
|
||||||
|
checkargs "$@"
|
||||||
|
part=$?
|
||||||
|
parse "$part"
|
||||||
|
solve "$part"
|
||||||
|
printf "%s: res=%s\n" "$cmdname" "$res"
|
||||||
|
}
|
49
2022/day14/common.c
Normal file
49
2022/day14/common.c
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/* common.c: Advent of Code 2022, common functions
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 Bruno Raoult ("br")
|
||||||
|
* Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
* Some rights reserved. See COPYING.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this
|
||||||
|
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "aoc.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
static int usage(char *prg)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: %s [-d debug_level] [-p part] [-i input]\n", prg);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int parseargs(int ac, char **av)
|
||||||
|
{
|
||||||
|
int opt, part = 1;
|
||||||
|
|
||||||
|
while ((opt = getopt(ac, av, "d:p:")) != -1) {
|
||||||
|
switch (opt) {
|
||||||
|
case 'd':
|
||||||
|
debug_level_set(atoi(optarg));
|
||||||
|
break;
|
||||||
|
case 'p': /* 1 or 2 */
|
||||||
|
part = atoi(optarg);
|
||||||
|
if (part < 1 || part > 2)
|
||||||
|
return usage(*av);
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
|
||||||
|
default:
|
||||||
|
return usage(*av);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (optind < ac)
|
||||||
|
return usage(*av);
|
||||||
|
return part;
|
||||||
|
}
|
2
2022/day14/input/example.txt
Normal file
2
2022/day14/input/example.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
498,4 -> 498,6 -> 496,6
|
||||||
|
503,4 -> 502,4 -> 502,9 -> 494,9
|
168
2022/day14/input/input.txt
Normal file
168
2022/day14/input/input.txt
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
490,15 -> 501,15 -> 501,14
|
||||||
|
503,68 -> 508,68
|
||||||
|
513,60 -> 513,61 -> 523,61 -> 523,60
|
||||||
|
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||||
|
524,136 -> 529,136
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
509,64 -> 514,64
|
||||||
|
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||||
|
518,46 -> 522,46
|
||||||
|
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
521,71 -> 521,73 -> 514,73 -> 514,79 -> 527,79 -> 527,73 -> 525,73 -> 525,71
|
||||||
|
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||||
|
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||||
|
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||||
|
518,82 -> 518,83 -> 529,83 -> 529,82
|
||||||
|
530,124 -> 535,124
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||||
|
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||||
|
542,112 -> 547,112
|
||||||
|
536,118 -> 541,118
|
||||||
|
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||||
|
528,139 -> 528,141 -> 521,141 -> 521,146 -> 534,146 -> 534,141 -> 531,141 -> 531,139
|
||||||
|
534,133 -> 539,133
|
||||||
|
543,118 -> 548,118
|
||||||
|
508,49 -> 508,52 -> 504,52 -> 504,55 -> 516,55 -> 516,52 -> 514,52 -> 514,49
|
||||||
|
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||||
|
508,49 -> 508,52 -> 504,52 -> 504,55 -> 516,55 -> 516,52 -> 514,52 -> 514,49
|
||||||
|
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||||
|
500,18 -> 500,20 -> 496,20 -> 496,24 -> 511,24 -> 511,20 -> 504,20 -> 504,18
|
||||||
|
530,130 -> 535,130
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
508,49 -> 508,52 -> 504,52 -> 504,55 -> 516,55 -> 516,52 -> 514,52 -> 514,49
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||||
|
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||||
|
546,115 -> 551,115
|
||||||
|
524,46 -> 528,46
|
||||||
|
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
521,71 -> 521,73 -> 514,73 -> 514,79 -> 527,79 -> 527,73 -> 525,73 -> 525,71
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||||
|
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||||
|
537,124 -> 542,124
|
||||||
|
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||||
|
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||||
|
528,139 -> 528,141 -> 521,141 -> 521,146 -> 534,146 -> 534,141 -> 531,141 -> 531,139
|
||||||
|
500,18 -> 500,20 -> 496,20 -> 496,24 -> 511,24 -> 511,20 -> 504,20 -> 504,18
|
||||||
|
539,115 -> 544,115
|
||||||
|
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||||
|
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||||
|
521,71 -> 521,73 -> 514,73 -> 514,79 -> 527,79 -> 527,73 -> 525,73 -> 525,71
|
||||||
|
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
533,127 -> 538,127
|
||||||
|
518,82 -> 518,83 -> 529,83 -> 529,82
|
||||||
|
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||||
|
506,66 -> 511,66
|
||||||
|
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||||
|
535,161 -> 535,162 -> 544,162 -> 544,161
|
||||||
|
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||||
|
500,18 -> 500,20 -> 496,20 -> 496,24 -> 511,24 -> 511,20 -> 504,20 -> 504,18
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||||
|
490,15 -> 501,15 -> 501,14
|
||||||
|
535,161 -> 535,162 -> 544,162 -> 544,161
|
||||||
|
508,49 -> 508,52 -> 504,52 -> 504,55 -> 516,55 -> 516,52 -> 514,52 -> 514,49
|
||||||
|
518,82 -> 518,83 -> 529,83 -> 529,82
|
||||||
|
513,66 -> 518,66
|
||||||
|
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||||
|
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||||
|
558,124 -> 563,124
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||||
|
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||||
|
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||||
|
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||||
|
528,139 -> 528,141 -> 521,141 -> 521,146 -> 534,146 -> 534,141 -> 531,141 -> 531,139
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
554,121 -> 559,121
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
508,49 -> 508,52 -> 504,52 -> 504,55 -> 516,55 -> 516,52 -> 514,52 -> 514,49
|
||||||
|
540,121 -> 545,121
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||||
|
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||||
|
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||||
|
547,121 -> 552,121
|
||||||
|
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||||
|
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||||
|
500,18 -> 500,20 -> 496,20 -> 496,24 -> 511,24 -> 511,20 -> 504,20 -> 504,18
|
||||||
|
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||||
|
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||||
|
512,46 -> 516,46
|
||||||
|
544,124 -> 549,124
|
||||||
|
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||||
|
521,71 -> 521,73 -> 514,73 -> 514,79 -> 527,79 -> 527,73 -> 525,73 -> 525,71
|
||||||
|
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||||
|
528,139 -> 528,141 -> 521,141 -> 521,146 -> 534,146 -> 534,141 -> 531,141 -> 531,139
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
528,139 -> 528,141 -> 521,141 -> 521,146 -> 534,146 -> 534,141 -> 531,141 -> 531,139
|
||||||
|
533,121 -> 538,121
|
||||||
|
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||||
|
521,43 -> 525,43
|
||||||
|
500,18 -> 500,20 -> 496,20 -> 496,24 -> 511,24 -> 511,20 -> 504,20 -> 504,18
|
||||||
|
527,133 -> 532,133
|
||||||
|
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||||
|
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||||
|
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
531,136 -> 536,136
|
||||||
|
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||||
|
515,43 -> 519,43
|
||||||
|
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||||
|
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||||
|
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||||
|
521,71 -> 521,73 -> 514,73 -> 514,79 -> 527,79 -> 527,73 -> 525,73 -> 525,71
|
||||||
|
521,71 -> 521,73 -> 514,73 -> 514,79 -> 527,79 -> 527,73 -> 525,73 -> 525,71
|
||||||
|
513,60 -> 513,61 -> 523,61 -> 523,60
|
||||||
|
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||||
|
537,130 -> 542,130
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
508,49 -> 508,52 -> 504,52 -> 504,55 -> 516,55 -> 516,52 -> 514,52 -> 514,49
|
||||||
|
545,136 -> 550,136
|
||||||
|
538,136 -> 543,136
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||||
|
528,139 -> 528,141 -> 521,141 -> 521,146 -> 534,146 -> 534,141 -> 531,141 -> 531,139
|
||||||
|
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||||
|
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||||
|
508,49 -> 508,52 -> 504,52 -> 504,55 -> 516,55 -> 516,52 -> 514,52 -> 514,49
|
||||||
|
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||||
|
503,37 -> 503,31 -> 503,37 -> 505,37 -> 505,29 -> 505,37 -> 507,37 -> 507,29 -> 507,37 -> 509,37 -> 509,29 -> 509,37 -> 511,37 -> 511,32 -> 511,37 -> 513,37 -> 513,29 -> 513,37 -> 515,37 -> 515,34 -> 515,37 -> 517,37 -> 517,36 -> 517,37 -> 519,37 -> 519,36 -> 519,37
|
||||||
|
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||||
|
510,68 -> 515,68
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
550,118 -> 555,118
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
528,139 -> 528,141 -> 521,141 -> 521,146 -> 534,146 -> 534,141 -> 531,141 -> 531,139
|
||||||
|
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||||
|
532,109 -> 532,103 -> 532,109 -> 534,109 -> 534,106 -> 534,109 -> 536,109 -> 536,102 -> 536,109 -> 538,109 -> 538,107 -> 538,109 -> 540,109 -> 540,107 -> 540,109 -> 542,109 -> 542,100 -> 542,109 -> 544,109 -> 544,106 -> 544,109
|
||||||
|
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||||
|
521,71 -> 521,73 -> 514,73 -> 514,79 -> 527,79 -> 527,73 -> 525,73 -> 525,71
|
||||||
|
541,133 -> 546,133
|
||||||
|
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
513,60 -> 513,61 -> 523,61 -> 523,60
|
||||||
|
518,40 -> 522,40
|
||||||
|
517,68 -> 522,68
|
||||||
|
500,18 -> 500,20 -> 496,20 -> 496,24 -> 511,24 -> 511,20 -> 504,20 -> 504,18
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
520,96 -> 520,92 -> 520,96 -> 522,96 -> 522,86 -> 522,96 -> 524,96 -> 524,92 -> 524,96 -> 526,96 -> 526,93 -> 526,96 -> 528,96 -> 528,95 -> 528,96 -> 530,96 -> 530,88 -> 530,96 -> 532,96 -> 532,88 -> 532,96 -> 534,96 -> 534,91 -> 534,96 -> 536,96 -> 536,92 -> 536,96 -> 538,96 -> 538,88 -> 538,96
|
||||||
|
529,159 -> 529,153 -> 529,159 -> 531,159 -> 531,151 -> 531,159 -> 533,159 -> 533,156 -> 533,159 -> 535,159 -> 535,152 -> 535,159 -> 537,159 -> 537,154 -> 537,159 -> 539,159 -> 539,156 -> 539,159
|
||||||
|
535,161 -> 535,162 -> 544,162 -> 544,161
|
||||||
|
551,124 -> 556,124
|
||||||
|
500,18 -> 500,20 -> 496,20 -> 496,24 -> 511,24 -> 511,20 -> 504,20 -> 504,18
|
111
2022/day15/Makefile
Normal file
111
2022/day15/Makefile
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
# AOC daily Makefile - GNU make only.
|
||||||
|
#
|
||||||
|
# Copyright (C) 2021-2022 Bruno Raoult ("br")
|
||||||
|
# Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
# Some rights reserved. See COPYING.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along with this
|
||||||
|
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
#
|
||||||
|
|
||||||
|
INPUT := input/input.txt
|
||||||
|
SHELL := /bin/bash
|
||||||
|
|
||||||
|
CC := gcc
|
||||||
|
BEAR := bear
|
||||||
|
CCLSFILE:= compile_commands.json
|
||||||
|
|
||||||
|
LIB := aoc_$(shell uname -m)
|
||||||
|
INCDIR := ../include
|
||||||
|
LIBDIR := ../lib
|
||||||
|
LDFLAGS := -L$(LIBDIR)
|
||||||
|
#LDLIB := -l$(LIB) -lm
|
||||||
|
LDLIB := -l$(LIB)
|
||||||
|
|
||||||
|
export LD_LIBRARY_PATH = $(LIBDIR)
|
||||||
|
|
||||||
|
CFLAGS += -std=gnu11
|
||||||
|
CFLAGS += -O2
|
||||||
|
CFLAGS += -g
|
||||||
|
# for gprof
|
||||||
|
# CFLAGS += -pg
|
||||||
|
CFLAGS += -Wall
|
||||||
|
CFLAGS += -Wextra
|
||||||
|
CFLAGS += -march=native
|
||||||
|
# Next one may be useful for valgrind (some invalid instructions)
|
||||||
|
# CFLAGS += -mno-tbm
|
||||||
|
CFLAGS += -Wmissing-declarations
|
||||||
|
CFLAGS += -Wno-unused-result
|
||||||
|
|
||||||
|
CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
|
||||||
|
CFLAGS += -DDEBUG_POOL # memory pools management
|
||||||
|
|
||||||
|
VALGRIND := valgrind
|
||||||
|
VALGRINDFLAGS := --leak-check=full --show-leak-kinds=all --track-origins=yes \
|
||||||
|
--sigill-diagnostics=yes --quiet --show-error-list=yes
|
||||||
|
|
||||||
|
|
||||||
|
TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n"
|
||||||
|
export PATH := .:$(PATH)
|
||||||
|
|
||||||
|
.PHONY: clean all compile assembly memcheck memcheck1 memcheck2 part1 part2 ccls bear org
|
||||||
|
|
||||||
|
all: README.org ccls part1 part2
|
||||||
|
|
||||||
|
memcheck: memcheck1 memcheck2
|
||||||
|
|
||||||
|
memcheck1: aoc-c
|
||||||
|
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 1 < $(INPUT)
|
||||||
|
|
||||||
|
memcheck2: aoc-c
|
||||||
|
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 2 < $(INPUT)
|
||||||
|
@#@valgrind -s --track-origins=yes aoc-c -p 2 < $(INPUT)
|
||||||
|
|
||||||
|
compile: aoc-c
|
||||||
|
|
||||||
|
cpp: aoc-c.i
|
||||||
|
|
||||||
|
assembly: aoc-c.s
|
||||||
|
|
||||||
|
part1: aoc-c
|
||||||
|
@#$(TIME) aoc.bash -p 1 < $(INPUT) 2>&1
|
||||||
|
@$(TIME) aoc-c -p 1 < $(INPUT)
|
||||||
|
|
||||||
|
part2: aoc-c
|
||||||
|
@#$(TIME) aoc.bash -p 2 < $(INPUT) 2>&1
|
||||||
|
@$(TIME) aoc-c -p 2 < $(INPUT)
|
||||||
|
|
||||||
|
ccls: $(CCLSFILE)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -f aoc-c core* vgcore* gmon.out aoc-c.s aoc-c.i README.html compile_commands.json
|
||||||
|
|
||||||
|
aoc-c: aoc-c.c common.c
|
||||||
|
@echo compiling $<
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $^ $(LDLIB) -o $@
|
||||||
|
|
||||||
|
# generate pre-processed file (.i) and assembler (.s)
|
||||||
|
%.i: %.c
|
||||||
|
@echo generating $@
|
||||||
|
@$(CC) -E $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||||
|
|
||||||
|
%.s: %.c
|
||||||
|
@echo generating $@
|
||||||
|
@$(CC) -S -fverbose-asm $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||||
|
|
||||||
|
# generate README.org from README.html (must cleanup !)
|
||||||
|
org: README.org
|
||||||
|
|
||||||
|
%.org: %.html
|
||||||
|
@echo generating $@. Cleanup before commit !
|
||||||
|
@pandoc $< -o $@
|
||||||
|
|
||||||
|
# generate compile_commands.json
|
||||||
|
$(CCLSFILE): aoc-c.c Makefile
|
||||||
|
$(BEAR) -- make clean compile
|
||||||
|
|
||||||
|
bear: clean
|
||||||
|
@touch .ccls-root
|
||||||
|
@$(BEAR) -- make compile
|
163
2022/day15/README.org
Normal file
163
2022/day15/README.org
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
** --- Day 15: Beacon Exclusion Zone ---
|
||||||
|
You feel the ground rumble again as the distress signal leads you to a
|
||||||
|
large network of subterranean tunnels. You don't have time to search
|
||||||
|
them all, but you don't need to: your pack contains a set of deployable
|
||||||
|
/sensors/ that you imagine were originally built to locate lost Elves.
|
||||||
|
|
||||||
|
The sensors aren't very powerful, but that's okay; your handheld device
|
||||||
|
indicates that you're close enough to the source of the distress signal
|
||||||
|
to use them. You pull the emergency sensor system out of your pack, hit
|
||||||
|
the big button on top, and the sensors zoom off down the tunnels.
|
||||||
|
|
||||||
|
Once a sensor finds a spot it thinks will give it a good reading, it
|
||||||
|
attaches itself to a hard surface and begins monitoring for the nearest
|
||||||
|
signal source /beacon/. Sensors and beacons always exist at integer
|
||||||
|
coordinates. Each sensor knows its own position and can /determine the
|
||||||
|
position of a beacon precisely/; however, sensors can only lock on to
|
||||||
|
the one beacon /closest to the sensor/ as measured by the
|
||||||
|
[[https://en.wikipedia.org/wiki/Taxicab_geometry][Manhattan distance]].
|
||||||
|
(There is never a tie where two beacons are the same distance to a
|
||||||
|
sensor.)
|
||||||
|
|
||||||
|
It doesn't take long for the sensors to report back their positions and
|
||||||
|
closest beacons (your puzzle input). For example:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
Sensor at x=2, y=18: closest beacon is at x=-2, y=15
|
||||||
|
Sensor at x=9, y=16: closest beacon is at x=10, y=16
|
||||||
|
Sensor at x=13, y=2: closest beacon is at x=15, y=3
|
||||||
|
Sensor at x=12, y=14: closest beacon is at x=10, y=16
|
||||||
|
Sensor at x=10, y=20: closest beacon is at x=10, y=16
|
||||||
|
Sensor at x=14, y=17: closest beacon is at x=10, y=16
|
||||||
|
Sensor at x=8, y=7: closest beacon is at x=2, y=10
|
||||||
|
Sensor at x=2, y=0: closest beacon is at x=2, y=10
|
||||||
|
Sensor at x=0, y=11: closest beacon is at x=2, y=10
|
||||||
|
Sensor at x=20, y=14: closest beacon is at x=25, y=17
|
||||||
|
Sensor at x=17, y=20: closest beacon is at x=21, y=22
|
||||||
|
Sensor at x=16, y=7: closest beacon is at x=15, y=3
|
||||||
|
Sensor at x=14, y=3: closest beacon is at x=15, y=3
|
||||||
|
Sensor at x=20, y=1: closest beacon is at x=15, y=3
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
So, consider the sensor at =2,18=; the closest beacon to it is at
|
||||||
|
=-2,15=. For the sensor at =9,16=, the closest beacon to it is at
|
||||||
|
=10,16=.
|
||||||
|
|
||||||
|
Drawing sensors as =S= and beacons as =B=, the above arrangement of
|
||||||
|
sensors and beacons looks like this:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
1 1 2 2
|
||||||
|
0 5 0 5 0 5
|
||||||
|
0 ....S.......................
|
||||||
|
1 ......................S.....
|
||||||
|
2 ...............S............
|
||||||
|
3 ................SB..........
|
||||||
|
4 ............................
|
||||||
|
5 ............................
|
||||||
|
6 ............................
|
||||||
|
7 ..........S.......S.........
|
||||||
|
8 ............................
|
||||||
|
9 ............................
|
||||||
|
10 ....B.......................
|
||||||
|
11 ..S.........................
|
||||||
|
12 ............................
|
||||||
|
13 ............................
|
||||||
|
14 ..............S.......S.....
|
||||||
|
15 B...........................
|
||||||
|
16 ...........SB...............
|
||||||
|
17 ................S..........B
|
||||||
|
18 ....S.......................
|
||||||
|
19 ............................
|
||||||
|
20 ............S......S........
|
||||||
|
21 ............................
|
||||||
|
22 .......................B....
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
This isn't necessarily a comprehensive map of all beacons in the area,
|
||||||
|
though. Because each sensor only identifies its closest beacon, if a
|
||||||
|
sensor detects a beacon, you know there are no other beacons that close
|
||||||
|
or closer to that sensor. There could still be beacons that just happen
|
||||||
|
to not be the closest beacon to any sensor. Consider the sensor at
|
||||||
|
=8,7=:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
1 1 2 2
|
||||||
|
0 5 0 5 0 5
|
||||||
|
-2 ..........#.................
|
||||||
|
-1 .........###................
|
||||||
|
0 ....S...#####...............
|
||||||
|
1 .......#######........S.....
|
||||||
|
2 ......#########S............
|
||||||
|
3 .....###########SB..........
|
||||||
|
4 ....#############...........
|
||||||
|
5 ...###############..........
|
||||||
|
6 ..#################.........
|
||||||
|
7 .#########S#######S#........
|
||||||
|
8 ..#################.........
|
||||||
|
9 ...###############..........
|
||||||
|
10 ....B############...........
|
||||||
|
11 ..S..###########............
|
||||||
|
12 ......#########.............
|
||||||
|
13 .......#######..............
|
||||||
|
14 ........#####.S.......S.....
|
||||||
|
15 B........###................
|
||||||
|
16 ..........#SB...............
|
||||||
|
17 ................S..........B
|
||||||
|
18 ....S.......................
|
||||||
|
19 ............................
|
||||||
|
20 ............S......S........
|
||||||
|
21 ............................
|
||||||
|
22 .......................B....
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
This sensor's closest beacon is at =2,10=, and so you know there are no
|
||||||
|
beacons that close or closer (in any positions marked =#=).
|
||||||
|
|
||||||
|
None of the detected beacons seem to be producing the distress signal,
|
||||||
|
so you'll need to work out where the distress beacon is by working out
|
||||||
|
where it /isn't/. For now, keep things simple by counting the positions
|
||||||
|
where a beacon cannot possibly be along just a single row.
|
||||||
|
|
||||||
|
So, suppose you have an arrangement of beacons and sensors like in the
|
||||||
|
example above and, just in the row where =y=10=, you'd like to count the
|
||||||
|
number of positions a beacon cannot possibly exist. The coverage from
|
||||||
|
all sensors near that row looks like this:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
1 1 2 2
|
||||||
|
0 5 0 5 0 5
|
||||||
|
9 ...#########################...
|
||||||
|
10 ..####B######################..
|
||||||
|
11 .###S#############.###########.
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
In this example, in the row where =y=10=, there are =26= positions where
|
||||||
|
a beacon cannot be present.
|
||||||
|
|
||||||
|
Consult the report from the sensors you just deployed. /In the row where
|
||||||
|
=y=2000000=, how many positions cannot contain a beacon?/
|
||||||
|
|
||||||
|
Your puzzle answer was =5176944=.
|
||||||
|
|
||||||
|
** --- Part Two ---
|
||||||
|
Your handheld device indicates that the distress signal is coming from a
|
||||||
|
beacon nearby. The distress beacon is not detected by any sensor, but
|
||||||
|
the distress beacon must have =x= and =y= coordinates each no lower than
|
||||||
|
=0= and no larger than =4000000=.
|
||||||
|
|
||||||
|
To isolate the distress beacon's signal, you need to determine its
|
||||||
|
/tuning frequency/, which can be found by multiplying its =x= coordinate
|
||||||
|
by =4000000= and then adding its =y= coordinate.
|
||||||
|
|
||||||
|
In the example above, the search space is smaller: instead, the =x= and
|
||||||
|
=y= coordinates can each be at most =20=. With this reduced search area,
|
||||||
|
there is only a single position that could have a beacon: =x=14, y=11=.
|
||||||
|
The tuning frequency for this distress beacon is =56000011=.
|
||||||
|
|
||||||
|
Find the only possible position for the distress beacon. /What is its
|
||||||
|
tuning frequency?/
|
||||||
|
|
||||||
|
Your puzzle answer was =13350458933732=.
|
||||||
|
|
||||||
|
Both parts of this puzzle are complete! They provide two gold stars: **
|
408
2022/day15/aoc-c.c
Normal file
408
2022/day15/aoc-c.c
Normal file
@@ -0,0 +1,408 @@
|
|||||||
|
/* aoc-c.c: Advent of Code 2022, day 15
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022-2023 Bruno Raoult ("br")
|
||||||
|
* Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
* Some rights reserved. See COPYING.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this
|
||||||
|
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "br.h"
|
||||||
|
#include "list.h"
|
||||||
|
#include "pool.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
#include "aoc.h"
|
||||||
|
|
||||||
|
static pool_t *pool_segment, *pool_pair;
|
||||||
|
|
||||||
|
#define HBITS 20 /* 20 bits: 1,048,576 buckets */
|
||||||
|
struct coord {
|
||||||
|
int x, y;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TOP 0
|
||||||
|
#define RIGHT 1
|
||||||
|
#define BOTTOM 2
|
||||||
|
#define LEFT 3
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct pair - input file pair list
|
||||||
|
* @sensor, @beacon: struct coord sensor and beacon coordinates.
|
||||||
|
* @manhattan: manhattan distance between sensor and beacon.
|
||||||
|
* @parity: beacon coordinates parity (as bishop color in chess).
|
||||||
|
* @corners: coordinates of rhombus immediately out of sensor range (clockwise).
|
||||||
|
* @list: list of pairs.
|
||||||
|
*/
|
||||||
|
struct pair {
|
||||||
|
struct coord sensor, beacon;
|
||||||
|
int manhattan;
|
||||||
|
int parity;
|
||||||
|
struct coord corners[4];
|
||||||
|
struct list_head list;
|
||||||
|
};
|
||||||
|
LIST_HEAD(pairs_head);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct row - row description
|
||||||
|
* @row: row number.
|
||||||
|
* @segments: segments list.
|
||||||
|
* @hlist: htable bucket list.
|
||||||
|
*/
|
||||||
|
struct row {
|
||||||
|
int row;
|
||||||
|
int beacons[64];
|
||||||
|
int nbeacons;
|
||||||
|
struct list_head segments;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct map - full map
|
||||||
|
* @min, @max: map's min and max coordinates.
|
||||||
|
* @hash: rows hash table
|
||||||
|
*/
|
||||||
|
static struct map {
|
||||||
|
struct coord min, max;
|
||||||
|
struct row row; /* for part 1 */
|
||||||
|
//hlist_head *hash;
|
||||||
|
} map = {
|
||||||
|
.min = { INT_MIN, INT_MIN }, .max = {INT_MAX, INT_MAX },
|
||||||
|
.row = { 0, {0}, 0, LIST_HEAD_INIT(map.row.segments) }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct segment - The main segment structure
|
||||||
|
* @row: the row number
|
||||||
|
* @start, @end: segment start and end
|
||||||
|
* @list: sorted row's segments list
|
||||||
|
*
|
||||||
|
* If a row contains 2 segments 1-3 and 7-8, it would be represented as:
|
||||||
|
* +----------+ +----------+
|
||||||
|
* | start: 1 |<------>| start: 7 |
|
||||||
|
* | end: 3 | | end: 8 |
|
||||||
|
* +----------+ +----------+
|
||||||
|
*
|
||||||
|
* This implies adding a segment must manage merging. For example, adding
|
||||||
|
* segment 2-4 above would change the first segment to 1-4, or adding 0-9
|
||||||
|
* should change the first segment to 0-9 and remove the second one.
|
||||||
|
*/
|
||||||
|
struct segment {
|
||||||
|
int row;
|
||||||
|
int start, end;
|
||||||
|
struct list_head list;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct segment *get_segment(int row, int start, int end)
|
||||||
|
{
|
||||||
|
struct segment *new = pool_get(pool_segment);
|
||||||
|
|
||||||
|
log_f(5, "alloc segment (%d,%d) on row (%d)\n", start, end, row);
|
||||||
|
new->row=row;
|
||||||
|
new->start=start;
|
||||||
|
new->end=end;
|
||||||
|
INIT_LIST_HEAD(&new->list);
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void merge_segment(int start, int end)
|
||||||
|
{
|
||||||
|
struct segment *seg, *new;
|
||||||
|
struct list_head *cur, *tmp;
|
||||||
|
static int l = 9;
|
||||||
|
|
||||||
|
new = get_segment(map.row.row, start, end);
|
||||||
|
if (list_empty(&map.row.segments)) {
|
||||||
|
list_add(&new->list, &map.row.segments);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
list_for_each_safe(cur, tmp, &map.row.segments) {
|
||||||
|
seg = list_entry(cur, struct segment, list);
|
||||||
|
|
||||||
|
/* 1) check for disjoint segments */
|
||||||
|
if (start > seg->end + 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (end < seg->start - 1) {
|
||||||
|
list_add_tail(&new->list, &seg->list);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2) new is inside cur: do nothing */
|
||||||
|
if (start >= seg->start && end <= seg->end) {
|
||||||
|
log_f(l, " overlap IN, do nothing\n");
|
||||||
|
pool_add(pool_segment, new);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
/* 3) cur inside new: remove cur */
|
||||||
|
if (start <= seg->start && end >= seg->end) {
|
||||||
|
log_f(l, " overlap OUT, remove current\n");
|
||||||
|
// TODO: avoid this
|
||||||
|
list_del(cur);
|
||||||
|
pool_add(pool_segment, seg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 4) new segment start is within current one */
|
||||||
|
if (start >= seg->start && start <= seg->end + 1) {
|
||||||
|
new->start = seg->start;
|
||||||
|
list_del(cur);
|
||||||
|
pool_add(pool_segment, seg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 5) new segment is left-adjacent to current */
|
||||||
|
if (end == seg->start - 1) {
|
||||||
|
seg->start = start;
|
||||||
|
pool_add(pool_segment, new);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* from here, we know there is an overlap */
|
||||||
|
|
||||||
|
/* 6) adjust new start to current start */
|
||||||
|
if (start >= seg->start)
|
||||||
|
new->start = seg->start;
|
||||||
|
|
||||||
|
/* 7) remove current if covered by new */
|
||||||
|
if (end >= seg->end){
|
||||||
|
list_del(cur);
|
||||||
|
pool_add(pool_segment, seg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* 8) replace current with new - finished */
|
||||||
|
new->end = seg->end;
|
||||||
|
list_add_tail(&new->list, cur);
|
||||||
|
list_del(cur);
|
||||||
|
pool_add(pool_segment, seg);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
list_add_tail(&new->list, &map.row.segments);
|
||||||
|
end:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __always_inline void add_beacon(int bx)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < map.row.nbeacons; ++i) {
|
||||||
|
if (map.row.beacons[i] == bx)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
map.row.beacons[map.row.nbeacons++] = bx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* is_off_range() - test if a point is off range from all sensors.
|
||||||
|
*/
|
||||||
|
static __always_inline int is_off_range(struct coord *point)
|
||||||
|
{
|
||||||
|
struct pair *pair;
|
||||||
|
|
||||||
|
/* reverse loop, because higher manhattan means higher chances to fail */
|
||||||
|
list_for_each_entry_reverse(pair, &pairs_head, list) {
|
||||||
|
if ((abs(point->x - pair->sensor.x) +
|
||||||
|
abs(point->y - pair->sensor.y)) <= pair->manhattan)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct pair *parse()
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct pair *pair = NULL, *cur;
|
||||||
|
struct coord sensor, beacon;
|
||||||
|
|
||||||
|
ret = scanf("%*[^-0-9]%d%*[^-0-9]%d%*[^-0-9]%d%*[^-0-9]%d",
|
||||||
|
&sensor.x, &sensor.y, &beacon.x, &beacon.y);
|
||||||
|
if (ret == 4) {
|
||||||
|
pair = pool_get(pool_pair);
|
||||||
|
pair->sensor = sensor;
|
||||||
|
pair->beacon = beacon;
|
||||||
|
pair->manhattan = abs(beacon.x - sensor.x) + abs(beacon.y - sensor.y);
|
||||||
|
pair->parity = (pair->beacon.x + pair->beacon.y) % 2;
|
||||||
|
pair->corners[TOP] = (struct coord) {
|
||||||
|
sensor.x, sensor.y - pair->manhattan - 1
|
||||||
|
};
|
||||||
|
pair->corners[BOTTOM] = (struct coord) {
|
||||||
|
sensor.x, sensor.y + pair->manhattan + 1
|
||||||
|
};
|
||||||
|
pair->corners[RIGHT] = (struct coord) {
|
||||||
|
sensor.x + pair->manhattan + 1, sensor.y
|
||||||
|
};
|
||||||
|
pair->corners[LEFT] = (struct coord) {
|
||||||
|
sensor.x - pair->manhattan - 1, sensor.y
|
||||||
|
};
|
||||||
|
|
||||||
|
/* keep list ordered by manhattan */
|
||||||
|
if (!list_empty(&pairs_head)) {
|
||||||
|
list_for_each_entry(cur, &pairs_head, list) {
|
||||||
|
if (cur->manhattan > pair->manhattan) {
|
||||||
|
list_add_tail(&pair->list, &cur->list);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list_add_tail(&pair->list, &pairs_head);
|
||||||
|
}
|
||||||
|
end:
|
||||||
|
return pair;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* /#\
|
||||||
|
* /#\ /# #\
|
||||||
|
* /# #\ /# #\
|
||||||
|
* /# #\O/# <--- O is a possible point
|
||||||
|
* #X#
|
||||||
|
* rhomb A /#\ rhom B
|
||||||
|
* /# #\
|
||||||
|
* /# #\
|
||||||
|
* /# #\
|
||||||
|
* /# #\
|
||||||
|
* /# rhombs #\
|
||||||
|
* A & B
|
||||||
|
* (intersection)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* intersect() - find intersection of two segments
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static __always_inline struct coord *intersect(struct coord *p1, struct coord *p2,
|
||||||
|
struct coord *q1, struct coord *q2,
|
||||||
|
struct coord *ret)
|
||||||
|
{
|
||||||
|
int a1, a2, b1, b2, x, y;
|
||||||
|
|
||||||
|
/* a1, b1, a2, b2 are the formulas of (p1, p2) and (q1, q2), such as:
|
||||||
|
* y = ax + b
|
||||||
|
* a = (y2 - y1) / (x2 - x1) x2 ≠ x1
|
||||||
|
* b = y - a * x We can take either p1 or p2 coordinates
|
||||||
|
*/
|
||||||
|
a1 = (p2->y - p1->y) / (p2->x - p1->x);
|
||||||
|
b1 = p1->y - p1->x * a1;
|
||||||
|
a2 = (q2->y - q1->y) / (q2->x - q1->x);
|
||||||
|
b2 = q1->y - q1->x * a2;
|
||||||
|
|
||||||
|
/* Lines intersection (x,y) is at:
|
||||||
|
* (a1 * x) + b1 = (a2 * x) + b2
|
||||||
|
* x * (a1 - a2) = b2 - b1
|
||||||
|
* x = (b2 - b1) / (a1 - a2) a2 ≠ a1
|
||||||
|
* Then we find y = ax + b
|
||||||
|
*/
|
||||||
|
x = (b2 - b1) / (a1 - a2);
|
||||||
|
y = a1 * x + b1;
|
||||||
|
|
||||||
|
/* check if intersection is:
|
||||||
|
* 1) Within p1-p2 and q1-q2 segments
|
||||||
|
* 2) Within map area
|
||||||
|
*/
|
||||||
|
if (x >= min(min(p1->x, p2->x), min(q1->x, q2->x)) &&
|
||||||
|
x <= max(max(p1->x, p2->x), max(q1->x, q2->x)) &&
|
||||||
|
y >= min(min(p1->y, p2->y), min(q1->y, q2->y)) &&
|
||||||
|
y <= max(max(p1->y, p2->y), max(q1->y, q2->y)) &&
|
||||||
|
x >= map.min.x && x <= map.max.x &&
|
||||||
|
y >= map.min.y && y <= map.max.y) {
|
||||||
|
*ret = (struct coord) {x, y};
|
||||||
|
} else {
|
||||||
|
ret = NULL;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define T_R(p) &p->corners[TOP], &p->corners[RIGHT]
|
||||||
|
#define R_B(p) &p->corners[RIGHT], &p->corners[BOTTOM]
|
||||||
|
#define B_L(p) &p->corners[BOTTOM], &p->corners[LEFT]
|
||||||
|
#define L_T(p) &p->corners[LEFT], &p->corners[TOP]
|
||||||
|
|
||||||
|
static struct coord *check_intersect(struct coord *ret)
|
||||||
|
{
|
||||||
|
struct pair *pair, *second;
|
||||||
|
|
||||||
|
list_for_each_entry(pair, &pairs_head, list) {
|
||||||
|
second = list_prepare_entry(pair, &pairs_head, list);
|
||||||
|
list_for_each_entry_continue(second, &pairs_head, list) {
|
||||||
|
if (second->parity == pair->parity) {
|
||||||
|
/* top right segment */
|
||||||
|
if ((intersect(T_R(pair), R_B(second), ret) && is_off_range(ret)) ||
|
||||||
|
(intersect(T_R(pair), L_T(second), ret) && is_off_range(ret)))
|
||||||
|
return ret;
|
||||||
|
/* bottom left segment */
|
||||||
|
if ((intersect(B_L(pair), R_B(second), ret) && is_off_range(ret)) ||
|
||||||
|
(intersect(B_L(pair), L_T(second), ret) && is_off_range(ret)))
|
||||||
|
return ret;
|
||||||
|
/* right bottom segment */
|
||||||
|
if ((intersect(R_B(pair), T_R(second), ret) && is_off_range(ret)) ||
|
||||||
|
(intersect(R_B(pair), B_L(second), ret) && is_off_range(ret)))
|
||||||
|
return ret;
|
||||||
|
/* left top segment */
|
||||||
|
if ((intersect(L_T(pair), T_R(second), ret) && is_off_range(ret)) ||
|
||||||
|
(intersect(L_T(pair), B_L(second), ret) && is_off_range(ret)))
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u64 part1(void)
|
||||||
|
{
|
||||||
|
u64 res = 0;
|
||||||
|
struct pair *pair;
|
||||||
|
struct segment *cur;
|
||||||
|
|
||||||
|
map.row.row = map.min.y = map.max.y = testmode() ? 10: 2000000;
|
||||||
|
|
||||||
|
while ((pair = parse())) {
|
||||||
|
if (map.row.row >= pair->sensor.y - pair->manhattan &&
|
||||||
|
map.row.row <= pair->sensor.y + pair->manhattan) {
|
||||||
|
int half = pair->manhattan - abs(map.row.row - pair->sensor.y);
|
||||||
|
int x1 = max(pair->sensor.x - half, map.min.x);
|
||||||
|
int x2 = max(pair->sensor.x + half, map.min.x);
|
||||||
|
merge_segment(x1, x2);
|
||||||
|
if (map.row.row == pair->beacon.y)
|
||||||
|
add_beacon(pair->beacon.x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list_for_each_entry(cur, &map.row.segments, list)
|
||||||
|
res += cur->end - cur->start + 1;
|
||||||
|
return res - map.row.nbeacons;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u64 part2()
|
||||||
|
{
|
||||||
|
u64 res = 0;
|
||||||
|
struct coord result = {0, 0};
|
||||||
|
|
||||||
|
map.min.x = map.min.y = 0;
|
||||||
|
map.max.x = map.max.y = testmode()? 20: 4000000;
|
||||||
|
|
||||||
|
while (parse())
|
||||||
|
;
|
||||||
|
check_intersect(&result);
|
||||||
|
res = ((u64)result.x) * 4000000UL + (u64)result.y;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int ac, char **av)
|
||||||
|
{
|
||||||
|
int part = parseargs(ac, av);
|
||||||
|
|
||||||
|
pool_segment = pool_create("segments", 8192, sizeof(struct segment));
|
||||||
|
pool_pair = pool_create("pair", 32, sizeof(struct pair));
|
||||||
|
|
||||||
|
printf("%s: res=%lu\n", *av, part == 1? part1(): part2());
|
||||||
|
pool_destroy(pool_segment);
|
||||||
|
pool_destroy(pool_pair);
|
||||||
|
exit(0);
|
||||||
|
}
|
17
2022/day15/aoc.h
Normal file
17
2022/day15/aoc.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/* aoc.c: Advent of Code 2022
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 Bruno Raoult ("br")
|
||||||
|
* Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
* Some rights reserved. See COPYING.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this
|
||||||
|
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
*/
|
||||||
|
#ifndef _AOC_H_
|
||||||
|
#define _AOC_H_
|
||||||
|
|
||||||
|
extern int parseargs(int ac, char**av);
|
||||||
|
extern int testmode(void);
|
||||||
|
#endif /* _AOC_H_ */
|
68
2022/day15/common.bash
Normal file
68
2022/day15/common.bash
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# common.bash: Advent of Code 2022, common bash functions
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Bruno Raoult ("br")
|
||||||
|
# Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
# Some rights reserved. See COPYING.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along with this
|
||||||
|
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
|
||||||
|
# shellcheck disable=2034
|
||||||
|
export cmdname=${0##*/}
|
||||||
|
export debug=0
|
||||||
|
export res
|
||||||
|
export LANG=C
|
||||||
|
|
||||||
|
shopt -s extglob
|
||||||
|
set -o noglob
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
printf "usage: %s [-d DEBUG] [-p PART]\n" "$cmdname"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
checkargs() {
|
||||||
|
local part=1
|
||||||
|
while getopts p:d: todo; do
|
||||||
|
case "$todo" in
|
||||||
|
d)
|
||||||
|
if [[ "$OPTARG" =~ ^[[:digit:]+]$ ]]; then
|
||||||
|
debug="$OPTARG"
|
||||||
|
else
|
||||||
|
printf "%s: illegal [%s] debug level.\n" "$CMD" "$OPTARG"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
p)
|
||||||
|
if [[ "$OPTARG" =~ ^[12]$ ]]; then
|
||||||
|
part="$OPTARG"
|
||||||
|
else
|
||||||
|
printf "%s: illegal [%s] part.\n" "$CMD" "$OPTARG"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
# Now check remaining argument (backup directory)
|
||||||
|
shift $((OPTIND - 1))
|
||||||
|
|
||||||
|
(( $# > 1 )) && usage
|
||||||
|
return "$part"
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
local -i part
|
||||||
|
|
||||||
|
checkargs "$@"
|
||||||
|
part=$?
|
||||||
|
parse "$part"
|
||||||
|
solve "$part"
|
||||||
|
printf "%s: res=%s\n" "$cmdname" "$res"
|
||||||
|
}
|
59
2022/day15/common.c
Normal file
59
2022/day15/common.c
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/* common.c: Advent of Code 2022, common functions
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 Bruno Raoult ("br")
|
||||||
|
* Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
* Some rights reserved. See COPYING.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this
|
||||||
|
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "aoc.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
static int _testmode = 0;
|
||||||
|
|
||||||
|
static int usage(char *prg)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: %s [-t][-d debug_level] [-p part] [-i input]\n", prg);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int testmode(void)
|
||||||
|
{
|
||||||
|
return _testmode;
|
||||||
|
}
|
||||||
|
|
||||||
|
int parseargs(int ac, char **av)
|
||||||
|
{
|
||||||
|
int opt, part = 1;
|
||||||
|
|
||||||
|
while ((opt = getopt(ac, av, "td:p:")) != -1) {
|
||||||
|
switch (opt) {
|
||||||
|
case 't':
|
||||||
|
_testmode = 1;
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
debug_level_set(atoi(optarg));
|
||||||
|
break;
|
||||||
|
case 'p': /* 1 or 2 */
|
||||||
|
part = atoi(optarg);
|
||||||
|
if (part < 1 || part > 2)
|
||||||
|
return usage(*av);
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
|
||||||
|
default:
|
||||||
|
return usage(*av);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (optind < ac)
|
||||||
|
return usage(*av);
|
||||||
|
return part;
|
||||||
|
}
|
14
2022/day15/input/example.txt
Normal file
14
2022/day15/input/example.txt
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
Sensor at x=2, y=18: closest beacon is at x=-2, y=15
|
||||||
|
Sensor at x=9, y=16: closest beacon is at x=10, y=16
|
||||||
|
Sensor at x=13, y=2: closest beacon is at x=15, y=3
|
||||||
|
Sensor at x=12, y=14: closest beacon is at x=10, y=16
|
||||||
|
Sensor at x=10, y=20: closest beacon is at x=10, y=16
|
||||||
|
Sensor at x=14, y=17: closest beacon is at x=10, y=16
|
||||||
|
Sensor at x=8, y=7: closest beacon is at x=2, y=10
|
||||||
|
Sensor at x=2, y=0: closest beacon is at x=2, y=10
|
||||||
|
Sensor at x=0, y=11: closest beacon is at x=2, y=10
|
||||||
|
Sensor at x=20, y=14: closest beacon is at x=25, y=17
|
||||||
|
Sensor at x=17, y=20: closest beacon is at x=21, y=22
|
||||||
|
Sensor at x=16, y=7: closest beacon is at x=15, y=3
|
||||||
|
Sensor at x=14, y=3: closest beacon is at x=15, y=3
|
||||||
|
Sensor at x=20, y=1: closest beacon is at x=15, y=3
|
26
2022/day15/input/input.txt
Normal file
26
2022/day15/input/input.txt
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
Sensor at x=3999724, y=2000469: closest beacon is at x=4281123, y=2282046
|
||||||
|
Sensor at x=3995530, y=8733: closest beacon is at x=3321979, y=-692911
|
||||||
|
Sensor at x=3016889, y=2550239: closest beacon is at x=2408038, y=2645605
|
||||||
|
Sensor at x=3443945, y=3604888: closest beacon is at x=3610223, y=3768674
|
||||||
|
Sensor at x=168575, y=491461: closest beacon is at x=1053731, y=-142061
|
||||||
|
Sensor at x=2820722, y=3865596: closest beacon is at x=3191440, y=3801895
|
||||||
|
Sensor at x=2329102, y=2456329: closest beacon is at x=2408038, y=2645605
|
||||||
|
Sensor at x=3889469, y=3781572: closest beacon is at x=3610223, y=3768674
|
||||||
|
Sensor at x=3256726, y=3882107: closest beacon is at x=3191440, y=3801895
|
||||||
|
Sensor at x=3729564, y=3214899: closest beacon is at x=3610223, y=3768674
|
||||||
|
Sensor at x=206718, y=2732608: closest beacon is at x=-152842, y=3117903
|
||||||
|
Sensor at x=2178192, y=2132103: closest beacon is at x=2175035, y=2000000
|
||||||
|
Sensor at x=1884402, y=214904: closest beacon is at x=1053731, y=-142061
|
||||||
|
Sensor at x=3060435, y=980430: closest beacon is at x=2175035, y=2000000
|
||||||
|
Sensor at x=3998355, y=3965954: closest beacon is at x=3610223, y=3768674
|
||||||
|
Sensor at x=3704399, y=3973731: closest beacon is at x=3610223, y=3768674
|
||||||
|
Sensor at x=1421672, y=3446889: closest beacon is at x=2408038, y=2645605
|
||||||
|
Sensor at x=3415633, y=3916020: closest beacon is at x=3191440, y=3801895
|
||||||
|
Sensor at x=2408019, y=2263990: closest beacon is at x=2408038, y=2645605
|
||||||
|
Sensor at x=3735247, y=2533767: closest beacon is at x=4281123, y=2282046
|
||||||
|
Sensor at x=1756494, y=1928662: closest beacon is at x=2175035, y=2000000
|
||||||
|
Sensor at x=780161, y=1907142: closest beacon is at x=2175035, y=2000000
|
||||||
|
Sensor at x=3036853, y=3294727: closest beacon is at x=3191440, y=3801895
|
||||||
|
Sensor at x=53246, y=3908582: closest beacon is at x=-152842, y=3117903
|
||||||
|
Sensor at x=2110517, y=2243287: closest beacon is at x=2175035, y=2000000
|
||||||
|
Sensor at x=3149491, y=3998374: closest beacon is at x=3191440, y=3801895
|
111
2022/day16/Makefile
Normal file
111
2022/day16/Makefile
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
# AOC daily Makefile - GNU make only.
|
||||||
|
#
|
||||||
|
# Copyright (C) 2021-2023 Bruno Raoult ("br")
|
||||||
|
# Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
# Some rights reserved. See COPYING.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along with this
|
||||||
|
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
#
|
||||||
|
|
||||||
|
INPUT := input/input.txt
|
||||||
|
SHELL := /bin/bash
|
||||||
|
|
||||||
|
CC := gcc
|
||||||
|
BEAR := bear
|
||||||
|
CCLSFILE:= compile_commands.json
|
||||||
|
|
||||||
|
LIB := aoc_$(shell uname -m)
|
||||||
|
INCDIR := ../include
|
||||||
|
LIBDIR := ../lib
|
||||||
|
LDFLAGS := -L$(LIBDIR)
|
||||||
|
#LDLIB := -l$(LIB) -lm
|
||||||
|
LDLIB := -l$(LIB)
|
||||||
|
|
||||||
|
export LD_LIBRARY_PATH = $(LIBDIR)
|
||||||
|
|
||||||
|
CFLAGS += -std=gnu11
|
||||||
|
CFLAGS += -O2
|
||||||
|
CFLAGS += -g
|
||||||
|
# for gprof
|
||||||
|
# CFLAGS += -pg
|
||||||
|
CFLAGS += -Wall
|
||||||
|
CFLAGS += -Wextra
|
||||||
|
CFLAGS += -march=native
|
||||||
|
# Next one may be useful for valgrind (some invalid instructions)
|
||||||
|
# CFLAGS += -mno-tbm
|
||||||
|
CFLAGS += -Wmissing-declarations
|
||||||
|
CFLAGS += -Wno-unused-result
|
||||||
|
|
||||||
|
CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
|
||||||
|
CFLAGS += -DDEBUG_POOL # memory pools management
|
||||||
|
|
||||||
|
VALGRIND := valgrind
|
||||||
|
VALGRINDFLAGS := --leak-check=full --show-leak-kinds=all --track-origins=yes \
|
||||||
|
--sigill-diagnostics=yes --quiet --show-error-list=yes
|
||||||
|
|
||||||
|
|
||||||
|
TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n"
|
||||||
|
export PATH := .:$(PATH)
|
||||||
|
|
||||||
|
.PHONY: clean all compile assembly memcheck memcheck1 memcheck2 part1 part2 ccls bear org
|
||||||
|
|
||||||
|
all: README.org ccls part1 part2
|
||||||
|
|
||||||
|
memcheck: memcheck1 memcheck2
|
||||||
|
|
||||||
|
memcheck1: aoc-c
|
||||||
|
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 1 < $(INPUT)
|
||||||
|
|
||||||
|
memcheck2: aoc-c
|
||||||
|
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 2 < $(INPUT)
|
||||||
|
@#@valgrind -s --track-origins=yes aoc-c -p 2 < $(INPUT)
|
||||||
|
|
||||||
|
compile: aoc-c
|
||||||
|
|
||||||
|
cpp: aoc-c.i
|
||||||
|
|
||||||
|
assembly: aoc-c.s
|
||||||
|
|
||||||
|
part1: aoc-c
|
||||||
|
@#$(TIME) aoc.bash -p 1 < $(INPUT) 2>&1
|
||||||
|
@$(TIME) aoc-c -p 1 < $(INPUT)
|
||||||
|
|
||||||
|
part2: aoc-c
|
||||||
|
@#$(TIME) aoc.bash -p 2 < $(INPUT) 2>&1
|
||||||
|
@$(TIME) aoc-c -p 2 < $(INPUT)
|
||||||
|
|
||||||
|
ccls: $(CCLSFILE)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -f aoc-c core* vgcore* gmon.out aoc-c.s aoc-c.i README.html compile_commands.json
|
||||||
|
|
||||||
|
aoc-c: aoc-c.c common.c
|
||||||
|
@echo compiling $<
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $^ $(LDLIB) -o $@
|
||||||
|
|
||||||
|
# generate pre-processed file (.i) and assembler (.s)
|
||||||
|
%.i: %.c
|
||||||
|
@echo generating $@
|
||||||
|
@$(CC) -E $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||||
|
|
||||||
|
%.s: %.c
|
||||||
|
@echo generating $@
|
||||||
|
@$(CC) -S -fverbose-asm $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||||
|
|
||||||
|
# generate README.org from README.html (must cleanup !)
|
||||||
|
org: README.org
|
||||||
|
|
||||||
|
%.org: %.html
|
||||||
|
@echo generating $@. Cleanup before commit !
|
||||||
|
@pandoc $< -o $@
|
||||||
|
|
||||||
|
# generate compile_commands.json
|
||||||
|
$(CCLSFILE): aoc-c.c Makefile
|
||||||
|
$(BEAR) -- make clean compile
|
||||||
|
|
||||||
|
bear: clean
|
||||||
|
@touch .ccls-root
|
||||||
|
@$(BEAR) -- make compile
|
275
2022/day16/README.org
Normal file
275
2022/day16/README.org
Normal file
@@ -0,0 +1,275 @@
|
|||||||
|
** --- Day 16: Proboscidea Volcanium ---
|
||||||
|
The sensors have led you to the origin of the distress signal: yet
|
||||||
|
another handheld device, just like the one the Elves gave you. However,
|
||||||
|
you don't see any Elves around; instead, the device is surrounded by
|
||||||
|
elephants! They must have gotten lost in these tunnels, and one of the
|
||||||
|
elephants apparently figured out how to turn on the distress signal.
|
||||||
|
|
||||||
|
The ground rumbles again, much stronger this time. What kind of cave is
|
||||||
|
this, exactly? You scan the cave with your handheld device; it reports
|
||||||
|
mostly igneous rock, some ash, pockets of pressurized gas, magma... this
|
||||||
|
isn't just a cave, it's a volcano!
|
||||||
|
|
||||||
|
You need to get the elephants out of here, quickly. Your device
|
||||||
|
estimates that you have /30 minutes/ before the volcano erupts, so you
|
||||||
|
don't have time to go back out the way you came in.
|
||||||
|
|
||||||
|
You scan the cave for other options and discover a network of pipes and
|
||||||
|
pressure-release /valves/. You aren't sure how such a system got into a
|
||||||
|
volcano, but you don't have time to complain; your device produces a
|
||||||
|
report (your puzzle input) of each valve's /flow rate/ if it were opened
|
||||||
|
(in pressure per minute) and the tunnels you could use to move between
|
||||||
|
the valves.
|
||||||
|
|
||||||
|
There's even a valve in the room you and the elephants are currently
|
||||||
|
standing in labeled =AA=. You estimate it will take you one minute to
|
||||||
|
open a single valve and one minute to follow any tunnel from one valve
|
||||||
|
to another. What is the most pressure you could release?
|
||||||
|
|
||||||
|
For example, suppose you had the following scan output:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
Valve AA has flow rate=0; tunnels lead to valves DD, II, BB
|
||||||
|
Valve BB has flow rate=13; tunnels lead to valves CC, AA
|
||||||
|
Valve CC has flow rate=2; tunnels lead to valves DD, BB
|
||||||
|
Valve DD has flow rate=20; tunnels lead to valves CC, AA, EE
|
||||||
|
Valve EE has flow rate=3; tunnels lead to valves FF, DD
|
||||||
|
Valve FF has flow rate=0; tunnels lead to valves EE, GG
|
||||||
|
Valve GG has flow rate=0; tunnels lead to valves FF, HH
|
||||||
|
Valve HH has flow rate=22; tunnel leads to valve GG
|
||||||
|
Valve II has flow rate=0; tunnels lead to valves AA, JJ
|
||||||
|
Valve JJ has flow rate=21; tunnel leads to valve II
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
All of the valves begin /closed/. You start at valve =AA=, but it must
|
||||||
|
be damaged or jammed or something: its flow rate is =0=, so there's no
|
||||||
|
point in opening it. However, you could spend one minute moving to valve
|
||||||
|
=BB= and another minute opening it; doing so would release pressure
|
||||||
|
during the remaining /28 minutes/ at a flow rate of =13=, a total
|
||||||
|
eventual pressure release of =28 * 13 = 364=. Then, you could spend your
|
||||||
|
third minute moving to valve =CC= and your fourth minute opening it,
|
||||||
|
providing an additional /26 minutes/ of eventual pressure release at a
|
||||||
|
flow rate of =2=, or =52= total pressure released by valve =CC=.
|
||||||
|
|
||||||
|
Making your way through the tunnels like this, you could probably open
|
||||||
|
many or all of the valves by the time 30 minutes have elapsed. However,
|
||||||
|
you need to release as much pressure as possible, so you'll need to be
|
||||||
|
methodical. Instead, consider this approach:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
== Minute 1 ==
|
||||||
|
No valves are open.
|
||||||
|
You move to valve DD.
|
||||||
|
|
||||||
|
== Minute 2 ==
|
||||||
|
No valves are open.
|
||||||
|
You open valve DD.
|
||||||
|
|
||||||
|
== Minute 3 ==
|
||||||
|
Valve DD is open, releasing 20 pressure.
|
||||||
|
You move to valve CC.
|
||||||
|
|
||||||
|
== Minute 4 ==
|
||||||
|
Valve DD is open, releasing 20 pressure.
|
||||||
|
You move to valve BB.
|
||||||
|
|
||||||
|
== Minute 5 ==
|
||||||
|
Valve DD is open, releasing 20 pressure.
|
||||||
|
You open valve BB.
|
||||||
|
|
||||||
|
== Minute 6 ==
|
||||||
|
Valves BB and DD are open, releasing 33 pressure.
|
||||||
|
You move to valve AA.
|
||||||
|
|
||||||
|
== Minute 7 ==
|
||||||
|
Valves BB and DD are open, releasing 33 pressure.
|
||||||
|
You move to valve II.
|
||||||
|
|
||||||
|
== Minute 8 ==
|
||||||
|
Valves BB and DD are open, releasing 33 pressure.
|
||||||
|
You move to valve JJ.
|
||||||
|
|
||||||
|
== Minute 9 ==
|
||||||
|
Valves BB and DD are open, releasing 33 pressure.
|
||||||
|
You open valve JJ.
|
||||||
|
|
||||||
|
== Minute 10 ==
|
||||||
|
Valves BB, DD, and JJ are open, releasing 54 pressure.
|
||||||
|
You move to valve II.
|
||||||
|
|
||||||
|
== Minute 11 ==
|
||||||
|
Valves BB, DD, and JJ are open, releasing 54 pressure.
|
||||||
|
You move to valve AA.
|
||||||
|
|
||||||
|
== Minute 12 ==
|
||||||
|
Valves BB, DD, and JJ are open, releasing 54 pressure.
|
||||||
|
You move to valve DD.
|
||||||
|
|
||||||
|
== Minute 13 ==
|
||||||
|
Valves BB, DD, and JJ are open, releasing 54 pressure.
|
||||||
|
You move to valve EE.
|
||||||
|
|
||||||
|
== Minute 14 ==
|
||||||
|
Valves BB, DD, and JJ are open, releasing 54 pressure.
|
||||||
|
You move to valve FF.
|
||||||
|
|
||||||
|
== Minute 15 ==
|
||||||
|
Valves BB, DD, and JJ are open, releasing 54 pressure.
|
||||||
|
You move to valve GG.
|
||||||
|
|
||||||
|
== Minute 16 ==
|
||||||
|
Valves BB, DD, and JJ are open, releasing 54 pressure.
|
||||||
|
You move to valve HH.
|
||||||
|
|
||||||
|
== Minute 17 ==
|
||||||
|
Valves BB, DD, and JJ are open, releasing 54 pressure.
|
||||||
|
You open valve HH.
|
||||||
|
|
||||||
|
== Minute 18 ==
|
||||||
|
Valves BB, DD, HH, and JJ are open, releasing 76 pressure.
|
||||||
|
You move to valve GG.
|
||||||
|
|
||||||
|
== Minute 19 ==
|
||||||
|
Valves BB, DD, HH, and JJ are open, releasing 76 pressure.
|
||||||
|
You move to valve FF.
|
||||||
|
|
||||||
|
== Minute 20 ==
|
||||||
|
Valves BB, DD, HH, and JJ are open, releasing 76 pressure.
|
||||||
|
You move to valve EE.
|
||||||
|
|
||||||
|
== Minute 21 ==
|
||||||
|
Valves BB, DD, HH, and JJ are open, releasing 76 pressure.
|
||||||
|
You open valve EE.
|
||||||
|
|
||||||
|
== Minute 22 ==
|
||||||
|
Valves BB, DD, EE, HH, and JJ are open, releasing 79 pressure.
|
||||||
|
You move to valve DD.
|
||||||
|
|
||||||
|
== Minute 23 ==
|
||||||
|
Valves BB, DD, EE, HH, and JJ are open, releasing 79 pressure.
|
||||||
|
You move to valve CC.
|
||||||
|
|
||||||
|
== Minute 24 ==
|
||||||
|
Valves BB, DD, EE, HH, and JJ are open, releasing 79 pressure.
|
||||||
|
You open valve CC.
|
||||||
|
|
||||||
|
== Minute 25 ==
|
||||||
|
Valves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.
|
||||||
|
|
||||||
|
== Minute 26 ==
|
||||||
|
Valves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.
|
||||||
|
|
||||||
|
== Minute 27 ==
|
||||||
|
Valves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.
|
||||||
|
|
||||||
|
== Minute 28 ==
|
||||||
|
Valves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.
|
||||||
|
|
||||||
|
== Minute 29 ==
|
||||||
|
Valves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.
|
||||||
|
|
||||||
|
== Minute 30 ==
|
||||||
|
Valves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
This approach lets you release the most pressure possible in 30 minutes
|
||||||
|
with this valve layout, =1651=.
|
||||||
|
|
||||||
|
Work out the steps to release the most pressure in 30 minutes. /What is
|
||||||
|
the most pressure you can release?/
|
||||||
|
|
||||||
|
Your puzzle answer was =1737=.
|
||||||
|
|
||||||
|
** --- Part Two ---
|
||||||
|
You're worried that even with an optimal approach, the pressure released
|
||||||
|
won't be enough. What if you got one of the elephants to help you?
|
||||||
|
|
||||||
|
It would take you 4 minutes to teach an elephant how to open the right
|
||||||
|
valves in the right order, leaving you with only /26 minutes/ to
|
||||||
|
actually execute your plan. Would having two of you working together be
|
||||||
|
better, even if it means having less time? (Assume that you teach the
|
||||||
|
elephant before opening any valves yourself, giving you both the same
|
||||||
|
full 26 minutes.)
|
||||||
|
|
||||||
|
In the example above, you could teach the elephant to help you as
|
||||||
|
follows:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
== Minute 1 ==
|
||||||
|
No valves are open.
|
||||||
|
You move to valve II.
|
||||||
|
The elephant moves to valve DD.
|
||||||
|
|
||||||
|
== Minute 2 ==
|
||||||
|
No valves are open.
|
||||||
|
You move to valve JJ.
|
||||||
|
The elephant opens valve DD.
|
||||||
|
|
||||||
|
== Minute 3 ==
|
||||||
|
Valve DD is open, releasing 20 pressure.
|
||||||
|
You open valve JJ.
|
||||||
|
The elephant moves to valve EE.
|
||||||
|
|
||||||
|
== Minute 4 ==
|
||||||
|
Valves DD and JJ are open, releasing 41 pressure.
|
||||||
|
You move to valve II.
|
||||||
|
The elephant moves to valve FF.
|
||||||
|
|
||||||
|
== Minute 5 ==
|
||||||
|
Valves DD and JJ are open, releasing 41 pressure.
|
||||||
|
You move to valve AA.
|
||||||
|
The elephant moves to valve GG.
|
||||||
|
|
||||||
|
== Minute 6 ==
|
||||||
|
Valves DD and JJ are open, releasing 41 pressure.
|
||||||
|
You move to valve BB.
|
||||||
|
The elephant moves to valve HH.
|
||||||
|
|
||||||
|
== Minute 7 ==
|
||||||
|
Valves DD and JJ are open, releasing 41 pressure.
|
||||||
|
You open valve BB.
|
||||||
|
The elephant opens valve HH.
|
||||||
|
|
||||||
|
== Minute 8 ==
|
||||||
|
Valves BB, DD, HH, and JJ are open, releasing 76 pressure.
|
||||||
|
You move to valve CC.
|
||||||
|
The elephant moves to valve GG.
|
||||||
|
|
||||||
|
== Minute 9 ==
|
||||||
|
Valves BB, DD, HH, and JJ are open, releasing 76 pressure.
|
||||||
|
You open valve CC.
|
||||||
|
The elephant moves to valve FF.
|
||||||
|
|
||||||
|
== Minute 10 ==
|
||||||
|
Valves BB, CC, DD, HH, and JJ are open, releasing 78 pressure.
|
||||||
|
The elephant moves to valve EE.
|
||||||
|
|
||||||
|
== Minute 11 ==
|
||||||
|
Valves BB, CC, DD, HH, and JJ are open, releasing 78 pressure.
|
||||||
|
The elephant opens valve EE.
|
||||||
|
|
||||||
|
(At this point, all valves are open.)
|
||||||
|
|
||||||
|
== Minute 12 ==
|
||||||
|
Valves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
== Minute 20 ==
|
||||||
|
Valves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
== Minute 26 ==
|
||||||
|
Valves BB, CC, DD, EE, HH, and JJ are open, releasing 81 pressure.
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
With the elephant helping, after 26 minutes, the best you could do would
|
||||||
|
release a total of =1707= pressure.
|
||||||
|
|
||||||
|
/With you and an elephant working together for 26 minutes, what is the
|
||||||
|
most pressure you could release?/
|
||||||
|
|
||||||
|
Your puzzle answer was =2216=.
|
||||||
|
|
||||||
|
Both parts of this puzzle are complete! They provide two gold stars: **
|
446
2022/day16/aoc-c.c
Normal file
446
2022/day16/aoc-c.c
Normal file
@@ -0,0 +1,446 @@
|
|||||||
|
/* aoc-c.c: Advent of Code 2022, day 16
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023 Bruno Raoult ("br")
|
||||||
|
* Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
* Some rights reserved. See COPYING.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this
|
||||||
|
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "br.h"
|
||||||
|
#include "list.h"
|
||||||
|
#include "pool.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "bits.h"
|
||||||
|
|
||||||
|
#include "aoc.h"
|
||||||
|
|
||||||
|
pool_t *pool_valve;
|
||||||
|
|
||||||
|
union val {
|
||||||
|
u32 val;
|
||||||
|
char str[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
enum state {
|
||||||
|
CLOSED,
|
||||||
|
OPENED
|
||||||
|
};
|
||||||
|
|
||||||
|
struct worker {
|
||||||
|
struct valve *pos;
|
||||||
|
int depth;
|
||||||
|
int time;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct valve {
|
||||||
|
int index; /* -1 for zero flow rate */
|
||||||
|
union val val;
|
||||||
|
enum state state;
|
||||||
|
int rate;
|
||||||
|
int evalflow, evaltime;
|
||||||
|
int playedflow, playedtime;
|
||||||
|
struct hlist_node hlist;
|
||||||
|
struct list_head index_sorted;
|
||||||
|
struct list_head flow_sorted;
|
||||||
|
struct list_head eval;
|
||||||
|
int worker;
|
||||||
|
struct list_head played;
|
||||||
|
int ntunnels, tottunnels;
|
||||||
|
struct valve **tunnels; /* array */
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct graph {
|
||||||
|
struct valve *aa; /* head ("AA") */
|
||||||
|
int npositive; /* only "AA" & working valves */
|
||||||
|
int nvalves;
|
||||||
|
u64 opened; /* bitmask of opened valves */
|
||||||
|
u64 openable; /* bitmask of openable valves */
|
||||||
|
struct list_head index_sorted; /* TO REMOVE ? */
|
||||||
|
struct list_head flow_sorted;
|
||||||
|
struct list_head eval;
|
||||||
|
struct list_head played[2];
|
||||||
|
struct valve **indexed_all;
|
||||||
|
int *dist; /* 2-D array */
|
||||||
|
} graph = {
|
||||||
|
.aa = NULL,
|
||||||
|
.npositive = 0,
|
||||||
|
.nvalves = 0,
|
||||||
|
.index_sorted = LIST_HEAD_INIT(graph.index_sorted),
|
||||||
|
.flow_sorted = LIST_HEAD_INIT(graph.flow_sorted),
|
||||||
|
.eval = LIST_HEAD_INIT(graph.eval),
|
||||||
|
.played[0] = LIST_HEAD_INIT(graph.played[0]),
|
||||||
|
.played[1] = LIST_HEAD_INIT(graph.played[1]),
|
||||||
|
.indexed_all = NULL,
|
||||||
|
.dist = NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
#define POS(a, b) ((a)*graph.nvalves + (b))
|
||||||
|
#define DIST(a, b) (graph.dist[POS((a), (b))])
|
||||||
|
|
||||||
|
static void print_valves()
|
||||||
|
{
|
||||||
|
struct valve *cur;
|
||||||
|
printf("**** graph: .head=%p npositive=%d\n", graph.aa, graph.npositive);
|
||||||
|
printf("index1: ");
|
||||||
|
list_for_each_entry(cur, &graph.index_sorted, index_sorted) {
|
||||||
|
printf("%d:%s ", cur->index, cur->val.str);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
printf("index2: ");
|
||||||
|
for (int i = 0; i < graph.nvalves; ++i) {
|
||||||
|
printf("%d:%s ", graph.indexed_all[i]->index, graph.indexed_all[i]->val.str);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
if (testmode()) {
|
||||||
|
printf("distances:\n ");
|
||||||
|
for (int i = 0; i < graph.nvalves; ++i) {
|
||||||
|
printf(" %s", graph.indexed_all[i]->val.str);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
for (int i = 0; i < graph.nvalves; ++i) {
|
||||||
|
printf("%s ", graph.indexed_all[i]->val.str);
|
||||||
|
for (int j = 0; j < graph.nvalves; ++j) {
|
||||||
|
printf("%5d ", DIST(i, j));
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("flow_sorted: ");
|
||||||
|
list_for_each_entry(cur, &graph.flow_sorted, flow_sorted) {
|
||||||
|
printf("%s:%d ", cur->val.str, cur->rate);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
printf("openable: %#lx ", graph.openable);
|
||||||
|
int pos, tmp;
|
||||||
|
bit_for_each64_2(pos, tmp, graph.openable) {
|
||||||
|
printf("%d ", pos);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PAD3 log(3, "%*s", _depth * 2, "")
|
||||||
|
#define PAD4 log(4, "%*s", _depth * 2, "")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eval() - eval possible moves from @flow_sorted list.
|
||||||
|
* @_depth: recursivity depth (for debug only, TODO: remove).
|
||||||
|
* @nworkers: number of workers.
|
||||||
|
* @workers: array of workers.
|
||||||
|
* @pick: max position (in @flow_sorted) to pick moves from (-1 for all).
|
||||||
|
* @pressure: total pressure per time unit so far.
|
||||||
|
*
|
||||||
|
* Find the "best" next move by evaluating only the first @pick elements
|
||||||
|
* in @flow_sorted list.
|
||||||
|
*
|
||||||
|
* @Return: the current position eval.
|
||||||
|
*/
|
||||||
|
static struct valve *eval(int _depth, int nworkers, struct worker *worker, int pick, int pressure)
|
||||||
|
{
|
||||||
|
struct valve *cur, *best = NULL, *sub;
|
||||||
|
struct list_head *list_flow, *tmp;
|
||||||
|
int _pick = pick, val = 0, val1, max = 0, bestworker = -1;
|
||||||
|
int _nworkers = nworkers;
|
||||||
|
if (nworkers == 2 && worker[0].pos->index == worker[1].pos->index)
|
||||||
|
_nworkers = 1;
|
||||||
|
|
||||||
|
PAD3; log_f(3, "EVAL _depth=%d w0={ pos=%d[%s] depth=%d time=%d } w1={ pos=%d[%s] depth=%d time=%d } pick=%d pressure=%d \n",
|
||||||
|
_depth,
|
||||||
|
worker[0].pos->index, worker[0].pos->val.str,
|
||||||
|
worker[0].depth, worker[0].time,
|
||||||
|
worker[1].pos->index, worker[1].pos->val.str,
|
||||||
|
worker[1].depth, worker[1].time,
|
||||||
|
pick, pressure);
|
||||||
|
list_for_each_safe(list_flow, tmp, &graph.flow_sorted) {
|
||||||
|
cur = list_entry(list_flow, struct valve, flow_sorted);
|
||||||
|
//int nworkers = worker[0].pos->index == worker[1].pos->index? 1: 2;
|
||||||
|
if (!--_pick) {
|
||||||
|
PAD4; log(4, "pick exhausted\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (int _w = 0; _w < _nworkers; ++_w) {
|
||||||
|
struct worker *w = worker + _w;
|
||||||
|
int d = DIST(w->pos->index, cur->index);
|
||||||
|
int remain = w->time - (d + 1);
|
||||||
|
PAD3; log(3, "worker %d/%d ", _w + 1, nworkers );
|
||||||
|
PAD3; log(3, "dist(%s,%s) = %d ", w->pos->val.str, cur->val.str, d);
|
||||||
|
if (remain < 1) {
|
||||||
|
PAD3; log(4, "time exhausted\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
val = remain * cur->rate;
|
||||||
|
PAD3; log(3, "--> val=%d\n", val);
|
||||||
|
|
||||||
|
if (w->depth > 0) {
|
||||||
|
struct worker _tmp = *w;
|
||||||
|
w->pos = cur;
|
||||||
|
w->depth--;
|
||||||
|
w->time = remain;
|
||||||
|
/* do not use list_del() here, to preserve prev/next pointers */
|
||||||
|
__list_del_entry(list_flow);
|
||||||
|
sub = eval(_depth + 1, nworkers, worker, pick, pressure + w->pos->rate);
|
||||||
|
list_flow->prev->next = list_flow;
|
||||||
|
list_flow->next->prev = list_flow;
|
||||||
|
*w = _tmp;
|
||||||
|
} else {
|
||||||
|
sub = NULL;
|
||||||
|
}
|
||||||
|
val1 = sub? sub->evalflow: 0;
|
||||||
|
PAD3; log(3, "eval3(%s->%s)= %5d = %d + %d", w->pos->val.str, cur->val.str,
|
||||||
|
val+val1, val, val1);
|
||||||
|
if (val + val1 > max) {
|
||||||
|
max = val + val1;
|
||||||
|
best = cur;
|
||||||
|
bestworker = _w;
|
||||||
|
log(3, " NEW MAX !");
|
||||||
|
}
|
||||||
|
log(3, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (best) {
|
||||||
|
best->evalflow = max;
|
||||||
|
best->worker = bestworker; /* FIXME */
|
||||||
|
PAD3; log(3, "EVAL returning best [%s] worker=%d eval=%d\n", best->val.str,
|
||||||
|
best->worker, max);
|
||||||
|
}
|
||||||
|
return best;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct valve *find_valve(union val val, int ntunnels, int rate)
|
||||||
|
{
|
||||||
|
struct valve *cur;
|
||||||
|
|
||||||
|
log_f(3, "val=%s ntunnels=%d rate=%d\n", val.str, ntunnels, rate);
|
||||||
|
list_for_each_entry(cur, &graph.index_sorted, index_sorted) {
|
||||||
|
//log(3, "\tcomparing with found, addr=%p\n", cur);
|
||||||
|
if (cur->val.val == val.val) {
|
||||||
|
log(3, "\tfound, addr=%p\n", cur);
|
||||||
|
if (ntunnels)
|
||||||
|
goto init;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cur = pool_get(pool_valve);
|
||||||
|
cur->val.val = val.val;
|
||||||
|
cur->ntunnels = 0;
|
||||||
|
cur->state = CLOSED;
|
||||||
|
cur->worker = -1;
|
||||||
|
cur->evalflow = cur->playedflow = 0;
|
||||||
|
cur->evaltime = cur->playedtime = 30;
|
||||||
|
INIT_LIST_HEAD(&cur->index_sorted);
|
||||||
|
INIT_LIST_HEAD(&cur->flow_sorted);
|
||||||
|
INIT_LIST_HEAD(&cur->eval);
|
||||||
|
INIT_LIST_HEAD(&cur->played);
|
||||||
|
log(3, "\talloc new, addr=%p\n", cur);
|
||||||
|
init:
|
||||||
|
if (ntunnels) {
|
||||||
|
cur->rate = rate;
|
||||||
|
cur->tottunnels = ntunnels;
|
||||||
|
cur->tunnels = calloc(ntunnels, sizeof(struct valve *));
|
||||||
|
}
|
||||||
|
end:
|
||||||
|
return cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nthtok - get nth token fron string.
|
||||||
|
* @buf: buffer to parse.
|
||||||
|
* @sep: separators string.
|
||||||
|
* @n: token number (0: first token).
|
||||||
|
*
|
||||||
|
* @Return: pointer to token.
|
||||||
|
*/
|
||||||
|
static char *nthtok(char *buf, const char *sep, int n)
|
||||||
|
{
|
||||||
|
char *ret;
|
||||||
|
for (; n >= 0; n--) {
|
||||||
|
ret = strtok(buf, sep);
|
||||||
|
buf = NULL;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SEP " ,;="
|
||||||
|
static struct graph *parse()
|
||||||
|
{
|
||||||
|
int index = 0, ntunnels;
|
||||||
|
size_t alloc = 0;
|
||||||
|
ssize_t buflen;
|
||||||
|
char *buf = NULL, *tok;
|
||||||
|
int rate;
|
||||||
|
struct valve *v1, *v2;
|
||||||
|
union val cur, link;
|
||||||
|
|
||||||
|
while ((buflen = getline(&buf, &alloc, stdin)) > 0) {
|
||||||
|
buf[--buflen] = 0;
|
||||||
|
/* valve name */
|
||||||
|
strncpy(cur.str, nthtok(buf, SEP, 1), sizeof(cur.str));
|
||||||
|
|
||||||
|
//printf("valve=%s ", tok);
|
||||||
|
rate = atoi(nthtok(NULL, SEP, 3));
|
||||||
|
//printf("rate=%s ", tok);
|
||||||
|
tok = nthtok(NULL, SEP, 4);
|
||||||
|
ntunnels = (buf + buflen - tok) / 4 + 1;
|
||||||
|
v1 = find_valve(cur, ntunnels, rate);
|
||||||
|
v1->index = index++;
|
||||||
|
// TODO: remove this list ?
|
||||||
|
list_add_tail(&v1->index_sorted, &graph.index_sorted);
|
||||||
|
graph.nvalves++;
|
||||||
|
//if (rate || v1->val.val == ('A' << 8 | 'A')) {
|
||||||
|
if (rate) {
|
||||||
|
struct valve *cur;
|
||||||
|
graph.npositive++;
|
||||||
|
/* keep this list sorted by flow decrasing */
|
||||||
|
list_for_each_entry(cur, &graph.flow_sorted, flow_sorted) {
|
||||||
|
if (rate > cur->rate) {
|
||||||
|
list_add_tail(&v1->flow_sorted, &cur->flow_sorted);
|
||||||
|
goto inserted;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list_add_tail(&v1->flow_sorted, &graph.flow_sorted);
|
||||||
|
inserted: ;
|
||||||
|
if (rate) {
|
||||||
|
//printf("adjust openable(%d): %#lx", v1->index, graph.openable);
|
||||||
|
graph.openable |= (1 << v1->index);
|
||||||
|
//printf("->%#lx", graph.openable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//printf("lead=%s ntunnels=%d ", tok, ntunnels);
|
||||||
|
do {
|
||||||
|
link.val = *(u16 *)tok;
|
||||||
|
v2 = find_valve(link, 0, 0);
|
||||||
|
*(v1->tunnels + v1->ntunnels++) = v2;
|
||||||
|
//printf(",%s", tok);
|
||||||
|
} while ((tok = nthtok(NULL, SEP, 0)));
|
||||||
|
//printf("\n");
|
||||||
|
}
|
||||||
|
graph.aa = find_valve((union val) { .str="AA" }, 0, 0);
|
||||||
|
/* build array of indexed valves */
|
||||||
|
graph.indexed_all = calloc(graph.nvalves, sizeof(struct valve *));
|
||||||
|
list_for_each_entry(v1, &graph.index_sorted, index_sorted) {
|
||||||
|
graph.indexed_all[v1->index] = v1;
|
||||||
|
}
|
||||||
|
return &graph;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int is_neighbour(int i, int j)
|
||||||
|
{
|
||||||
|
struct valve *v1 = graph.indexed_all[i], *v2 = graph.indexed_all[j];
|
||||||
|
for (int i = 0; i < v1->ntunnels; ++i)
|
||||||
|
if (v1->tunnels[i]->val.val == v2->val.val)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void build_distances()
|
||||||
|
{
|
||||||
|
int i, j, k;
|
||||||
|
graph.dist = calloc(graph.nvalves * graph.nvalves, sizeof(int));
|
||||||
|
/* initialize values */
|
||||||
|
for (i = 0; i < graph.nvalves; ++i) {
|
||||||
|
for (j = 1; j < graph.nvalves; ++j) {
|
||||||
|
if (i != j) {
|
||||||
|
if (is_neighbour(i, j))
|
||||||
|
DIST(i, j) = DIST(j, i) = 1;
|
||||||
|
else
|
||||||
|
DIST(i, j) = DIST(j, i) = 10000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get all distances using Floyd-Warshall
|
||||||
|
* see https://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm
|
||||||
|
*
|
||||||
|
* Add all vertices one by one to the set of intermediate vertices.
|
||||||
|
* ---> Before start of an iteration, we have shortest distances between all
|
||||||
|
* pairs of vertices such that the shortest distances consider only the
|
||||||
|
* vertices in set {0, 1, 2, .. k-1} as intermediate vertices.
|
||||||
|
* ----> After the end of an iteration, vertex no. k is added to the set of
|
||||||
|
* intermediate vertices and the set becomes {0, 1, 2, .. k}
|
||||||
|
*/
|
||||||
|
for (k = 0; k < graph.nvalves; k++) {
|
||||||
|
/* Pick all vertices as source one by one */
|
||||||
|
for (i = 0; i < graph.nvalves; i++) {
|
||||||
|
/* Pick all vertices as destination for the above picked source */
|
||||||
|
for (j = i + 1; j < graph.nvalves; j++)
|
||||||
|
DIST(i, j) = DIST(j, i) = min(DIST(i, j), DIST(i, k) + DIST(k, j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_played(int nworkers)
|
||||||
|
{
|
||||||
|
struct valve *p;
|
||||||
|
int total = 0;
|
||||||
|
for (int w = 0; w < nworkers; ++w) {
|
||||||
|
int remain = 26, i = 1;
|
||||||
|
struct valve *prev = graph.aa;
|
||||||
|
i = 1;
|
||||||
|
printf("played by %d/%d:\n", w + 1, nworkers);
|
||||||
|
list_for_each_entry(p, &graph.played[w], played) {
|
||||||
|
printf("%2d: %s, ", i, p->val.str);
|
||||||
|
remain -= DIST(p->index, prev->index) + 1;
|
||||||
|
total += p->rate * remain;
|
||||||
|
printf("dist=%d remain=%d total=%d", DIST(p->index, prev->index), remain,
|
||||||
|
total);
|
||||||
|
printf("\n");
|
||||||
|
i++;
|
||||||
|
prev = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int doit(int part)
|
||||||
|
{
|
||||||
|
struct worker w[2];
|
||||||
|
struct valve *best;
|
||||||
|
int res = 0;
|
||||||
|
//int topick = part == 1? 7: 12;
|
||||||
|
int topick = part == 1? 12: 12;
|
||||||
|
|
||||||
|
w[0].pos = w[1].pos = graph.aa;
|
||||||
|
//w[0].depth = w[1].depth = part == 1? 7: 4;
|
||||||
|
w[0].depth = w[1].depth = part == 1? 4: 4;
|
||||||
|
w[0].time = w[1].time = part == 1? 30: 26;
|
||||||
|
|
||||||
|
while ((best = eval(0, part, w, topick, 0))) {
|
||||||
|
list_del(&best->flow_sorted);
|
||||||
|
list_add_tail(&best->played, &graph.played[best->worker]);
|
||||||
|
w[best->worker].time -= DIST(w[best->worker].pos->index, best->index) + 1;
|
||||||
|
w[best->worker].pos = best;
|
||||||
|
res += best->rate * w[best->worker].time;
|
||||||
|
print_played(part);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ulong part1()
|
||||||
|
{
|
||||||
|
return doit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ulong part2()
|
||||||
|
{
|
||||||
|
return doit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int ac, char **av)
|
||||||
|
{
|
||||||
|
int part = parseargs(ac, av);
|
||||||
|
pool_valve = pool_create("valve", 512, sizeof(struct valve));
|
||||||
|
parse();
|
||||||
|
build_distances();
|
||||||
|
print_valves();
|
||||||
|
printf("%s: res=%lu\n", *av, part == 1? part1(): part2());
|
||||||
|
exit(0);
|
||||||
|
}
|
17
2022/day16/aoc.h
Normal file
17
2022/day16/aoc.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/* aoc.c: Advent of Code 2022
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022-2023 Bruno Raoult ("br")
|
||||||
|
* Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
* Some rights reserved. See COPYING.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this
|
||||||
|
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
*/
|
||||||
|
#ifndef _AOC_H_
|
||||||
|
#define _AOC_H_
|
||||||
|
|
||||||
|
extern int parseargs(int ac, char**av);
|
||||||
|
extern int testmode(void);
|
||||||
|
#endif /* _AOC_H_ */
|
68
2022/day16/common.bash
Normal file
68
2022/day16/common.bash
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# common.bash: Advent of Code 2022, common bash functions
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022-2023 Bruno Raoult ("br")
|
||||||
|
# Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
# Some rights reserved. See COPYING.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along with this
|
||||||
|
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
|
||||||
|
# shellcheck disable=2034
|
||||||
|
export cmdname=${0##*/}
|
||||||
|
export debug=0
|
||||||
|
export res
|
||||||
|
export LANG=C
|
||||||
|
|
||||||
|
shopt -s extglob
|
||||||
|
set -o noglob
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
printf "usage: %s [-d DEBUG] [-p PART]\n" "$cmdname"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
checkargs() {
|
||||||
|
local part=1
|
||||||
|
while getopts p:d: todo; do
|
||||||
|
case "$todo" in
|
||||||
|
d)
|
||||||
|
if [[ "$OPTARG" =~ ^[[:digit:]+]$ ]]; then
|
||||||
|
debug="$OPTARG"
|
||||||
|
else
|
||||||
|
printf "%s: illegal [%s] debug level.\n" "$CMD" "$OPTARG"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
p)
|
||||||
|
if [[ "$OPTARG" =~ ^[12]$ ]]; then
|
||||||
|
part="$OPTARG"
|
||||||
|
else
|
||||||
|
printf "%s: illegal [%s] part.\n" "$CMD" "$OPTARG"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
# Now check remaining argument (backup directory)
|
||||||
|
shift $((OPTIND - 1))
|
||||||
|
|
||||||
|
(( $# > 1 )) && usage
|
||||||
|
return "$part"
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
local -i part
|
||||||
|
|
||||||
|
checkargs "$@"
|
||||||
|
part=$?
|
||||||
|
parse "$part"
|
||||||
|
solve "$part"
|
||||||
|
printf "%s: res=%s\n" "$cmdname" "$res"
|
||||||
|
}
|
59
2022/day16/common.c
Normal file
59
2022/day16/common.c
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/* common.c: Advent of Code 2022, common functions
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022-2023 Bruno Raoult ("br")
|
||||||
|
* Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
* Some rights reserved. See COPYING.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this
|
||||||
|
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "aoc.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
static int _testmode = 0;
|
||||||
|
|
||||||
|
static int usage(char *prg)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: %s [-t][-d debug_level] [-p part] [-i input]\n", prg);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int testmode(void)
|
||||||
|
{
|
||||||
|
return _testmode;
|
||||||
|
}
|
||||||
|
|
||||||
|
int parseargs(int ac, char **av)
|
||||||
|
{
|
||||||
|
int opt, part = 1;
|
||||||
|
|
||||||
|
while ((opt = getopt(ac, av, "td:p:")) != -1) {
|
||||||
|
switch (opt) {
|
||||||
|
case 't':
|
||||||
|
_testmode = 1;
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
debug_level_set(atoi(optarg));
|
||||||
|
break;
|
||||||
|
case 'p': /* 1 or 2 */
|
||||||
|
part = atoi(optarg);
|
||||||
|
if (part < 1 || part > 2)
|
||||||
|
return usage(*av);
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
|
||||||
|
default:
|
||||||
|
return usage(*av);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (optind < ac)
|
||||||
|
return usage(*av);
|
||||||
|
return part;
|
||||||
|
}
|
10
2022/day16/input/example.txt
Normal file
10
2022/day16/input/example.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Valve AA has flow rate=0; tunnels lead to valves DD, II, BB
|
||||||
|
Valve BB has flow rate=13; tunnels lead to valves CC, AA
|
||||||
|
Valve CC has flow rate=2; tunnels lead to valves DD, BB
|
||||||
|
Valve DD has flow rate=20; tunnels lead to valves CC, AA, EE
|
||||||
|
Valve EE has flow rate=3; tunnels lead to valves FF, DD
|
||||||
|
Valve FF has flow rate=0; tunnels lead to valves EE, GG
|
||||||
|
Valve GG has flow rate=0; tunnels lead to valves FF, HH
|
||||||
|
Valve HH has flow rate=22; tunnel leads to valve GG
|
||||||
|
Valve II has flow rate=0; tunnels lead to valves AA, JJ
|
||||||
|
Valve JJ has flow rate=21; tunnel leads to valve II
|
54
2022/day16/input/input.txt
Normal file
54
2022/day16/input/input.txt
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
Valve EJ has flow rate=25; tunnel leads to valve MC
|
||||||
|
Valve WC has flow rate=0; tunnels lead to valves OW, RU
|
||||||
|
Valve NP has flow rate=0; tunnels lead to valves VR, KL
|
||||||
|
Valve AA has flow rate=0; tunnels lead to valves QT, AP, EZ, AK, XV
|
||||||
|
Valve VO has flow rate=6; tunnels lead to valves KM, RF, HS, LJ, IA
|
||||||
|
Valve CB has flow rate=0; tunnels lead to valves UI, UP
|
||||||
|
Valve TE has flow rate=18; tunnel leads to valve JT
|
||||||
|
Valve CZ has flow rate=0; tunnels lead to valves UP, OW
|
||||||
|
Valve LJ has flow rate=0; tunnels lead to valves DV, VO
|
||||||
|
Valve UP has flow rate=7; tunnels lead to valves SK, CB, CZ
|
||||||
|
Valve FP has flow rate=0; tunnels lead to valves OW, RE
|
||||||
|
Valve KM has flow rate=0; tunnels lead to valves SE, VO
|
||||||
|
Valve DV has flow rate=0; tunnels lead to valves LJ, UM
|
||||||
|
Valve FL has flow rate=0; tunnels lead to valves AH, TS
|
||||||
|
Valve VR has flow rate=24; tunnels lead to valves DM, TF, NP
|
||||||
|
Valve IA has flow rate=0; tunnels lead to valves VS, VO
|
||||||
|
Valve RF has flow rate=0; tunnels lead to valves VO, JF
|
||||||
|
Valve RT has flow rate=0; tunnels lead to valves UM, SE
|
||||||
|
Valve RU has flow rate=0; tunnels lead to valves AR, WC
|
||||||
|
Valve SE has flow rate=4; tunnels lead to valves GU, KM, CX, RT
|
||||||
|
Valve MC has flow rate=0; tunnels lead to valves EJ, AR
|
||||||
|
Valve TF has flow rate=0; tunnels lead to valves AH, VR
|
||||||
|
Valve CX has flow rate=0; tunnels lead to valves SE, TO
|
||||||
|
Valve GL has flow rate=11; tunnels lead to valves UY, KL, CY
|
||||||
|
Valve GU has flow rate=0; tunnels lead to valves SE, EZ
|
||||||
|
Valve VS has flow rate=0; tunnels lead to valves XN, IA
|
||||||
|
Valve EZ has flow rate=0; tunnels lead to valves AA, GU
|
||||||
|
Valve GK has flow rate=0; tunnels lead to valves FI, HZ
|
||||||
|
Valve JT has flow rate=0; tunnels lead to valves TE, XN
|
||||||
|
Valve DM has flow rate=0; tunnels lead to valves VR, HZ
|
||||||
|
Valve AR has flow rate=16; tunnels lead to valves UI, RU, MC
|
||||||
|
Valve XN has flow rate=9; tunnels lead to valves XP, JT, VS, GT, CY
|
||||||
|
Valve CY has flow rate=0; tunnels lead to valves XN, GL
|
||||||
|
Valve QT has flow rate=0; tunnels lead to valves UM, AA
|
||||||
|
Valve KL has flow rate=0; tunnels lead to valves GL, NP
|
||||||
|
Valve SK has flow rate=0; tunnels lead to valves XV, UP
|
||||||
|
Valve OW has flow rate=12; tunnels lead to valves CZ, WC, FP
|
||||||
|
Valve AK has flow rate=0; tunnels lead to valves AA, HS
|
||||||
|
Valve XV has flow rate=0; tunnels lead to valves AA, SK
|
||||||
|
Valve GT has flow rate=0; tunnels lead to valves XN, UM
|
||||||
|
Valve FI has flow rate=0; tunnels lead to valves JF, GK
|
||||||
|
Valve UY has flow rate=0; tunnels lead to valves JF, GL
|
||||||
|
Valve UM has flow rate=5; tunnels lead to valves DV, GT, RT, QT
|
||||||
|
Valve IQ has flow rate=0; tunnels lead to valves HZ, AH
|
||||||
|
Valve JF has flow rate=10; tunnels lead to valves RF, FI, UY, RE, TS
|
||||||
|
Valve TS has flow rate=0; tunnels lead to valves JF, FL
|
||||||
|
Valve AH has flow rate=23; tunnels lead to valves IQ, FL, TF
|
||||||
|
Valve HS has flow rate=0; tunnels lead to valves AK, VO
|
||||||
|
Valve HZ has flow rate=20; tunnels lead to valves IQ, DM, GK
|
||||||
|
Valve TO has flow rate=15; tunnel leads to valve CX
|
||||||
|
Valve XP has flow rate=0; tunnels lead to valves AP, XN
|
||||||
|
Valve AP has flow rate=0; tunnels lead to valves XP, AA
|
||||||
|
Valve RE has flow rate=0; tunnels lead to valves JF, FP
|
||||||
|
Valve UI has flow rate=0; tunnels lead to valves AR, CB
|
111
2022/day17/Makefile
Normal file
111
2022/day17/Makefile
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
# AOC daily Makefile - GNU make only.
|
||||||
|
#
|
||||||
|
# Copyright (C) 2021-2023 Bruno Raoult ("br")
|
||||||
|
# Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
# Some rights reserved. See COPYING.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along with this
|
||||||
|
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
#
|
||||||
|
|
||||||
|
INPUT := input/input.txt
|
||||||
|
SHELL := /bin/bash
|
||||||
|
|
||||||
|
CC := gcc
|
||||||
|
BEAR := bear
|
||||||
|
CCLSFILE:= compile_commands.json
|
||||||
|
|
||||||
|
LIB := aoc_$(shell uname -m)
|
||||||
|
INCDIR := ../include
|
||||||
|
LIBDIR := ../lib
|
||||||
|
LDFLAGS := -L$(LIBDIR)
|
||||||
|
#LDLIB := -l$(LIB) -lm
|
||||||
|
LDLIB := -l$(LIB)
|
||||||
|
|
||||||
|
export LD_LIBRARY_PATH = $(LIBDIR)
|
||||||
|
|
||||||
|
CFLAGS += -std=gnu11
|
||||||
|
CFLAGS += -O2
|
||||||
|
CFLAGS += -g
|
||||||
|
# for gprof
|
||||||
|
# CFLAGS += -pg
|
||||||
|
CFLAGS += -Wall
|
||||||
|
CFLAGS += -Wextra
|
||||||
|
CFLAGS += -march=native
|
||||||
|
# Next one may be useful for valgrind (some invalid instructions)
|
||||||
|
# CFLAGS += -mno-tbm
|
||||||
|
CFLAGS += -Wmissing-declarations
|
||||||
|
CFLAGS += -Wno-unused-result
|
||||||
|
|
||||||
|
CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
|
||||||
|
CFLAGS += -DDEBUG_POOL # memory pools management
|
||||||
|
|
||||||
|
VALGRIND := valgrind
|
||||||
|
VALGRINDFLAGS := --leak-check=full --show-leak-kinds=all --track-origins=yes \
|
||||||
|
--sigill-diagnostics=yes --quiet --show-error-list=yes
|
||||||
|
|
||||||
|
|
||||||
|
TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n"
|
||||||
|
export PATH := .:$(PATH)
|
||||||
|
|
||||||
|
.PHONY: clean all compile assembly memcheck memcheck1 memcheck2 part1 part2 ccls bear org
|
||||||
|
|
||||||
|
all: README.org ccls part1 part2
|
||||||
|
|
||||||
|
memcheck: memcheck1 memcheck2
|
||||||
|
|
||||||
|
memcheck1: aoc-c
|
||||||
|
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 1 < $(INPUT)
|
||||||
|
|
||||||
|
memcheck2: aoc-c
|
||||||
|
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 2 < $(INPUT)
|
||||||
|
@#@valgrind -s --track-origins=yes aoc-c -p 2 < $(INPUT)
|
||||||
|
|
||||||
|
compile: aoc-c
|
||||||
|
|
||||||
|
cpp: aoc-c.i
|
||||||
|
|
||||||
|
assembly: aoc-c.s
|
||||||
|
|
||||||
|
part1: aoc-c
|
||||||
|
@#$(TIME) aoc.bash -p 1 < $(INPUT) 2>&1
|
||||||
|
@$(TIME) aoc-c -p 1 < $(INPUT)
|
||||||
|
|
||||||
|
part2: aoc-c
|
||||||
|
@#$(TIME) aoc.bash -p 2 < $(INPUT) 2>&1
|
||||||
|
@$(TIME) aoc-c -p 2 < $(INPUT)
|
||||||
|
|
||||||
|
ccls: $(CCLSFILE)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -f aoc-c core* vgcore* gmon.out aoc-c.s aoc-c.i README.html compile_commands.json
|
||||||
|
|
||||||
|
aoc-c: aoc-c.c common.c
|
||||||
|
@echo compiling $<
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $^ $(LDLIB) -o $@
|
||||||
|
|
||||||
|
# generate pre-processed file (.i) and assembler (.s)
|
||||||
|
%.i: %.c
|
||||||
|
@echo generating $@
|
||||||
|
@$(CC) -E $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||||
|
|
||||||
|
%.s: %.c
|
||||||
|
@echo generating $@
|
||||||
|
@$(CC) -S -fverbose-asm $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||||
|
|
||||||
|
# generate README.org from README.html (must cleanup !)
|
||||||
|
org: README.org
|
||||||
|
|
||||||
|
%.org: %.html
|
||||||
|
@echo generating $@. Cleanup before commit !
|
||||||
|
@pandoc $< -o $@
|
||||||
|
|
||||||
|
# generate compile_commands.json
|
||||||
|
$(CCLSFILE): aoc-c.c Makefile
|
||||||
|
$(BEAR) -- make clean compile
|
||||||
|
|
||||||
|
bear: clean
|
||||||
|
@touch .ccls-root
|
||||||
|
@$(BEAR) -- make compile
|
374
2022/day17/README.org
Normal file
374
2022/day17/README.org
Normal file
@@ -0,0 +1,374 @@
|
|||||||
|
** --- Day 17: Pyroclastic Flow ---
|
||||||
|
Your handheld device has located an alternative exit from the cave for
|
||||||
|
you and the elephants. The ground is rumbling almost continuously now,
|
||||||
|
but the strange valves bought you some time. It's definitely getting
|
||||||
|
warmer in here, though.
|
||||||
|
|
||||||
|
The tunnels eventually open into a very tall, narrow chamber. Large,
|
||||||
|
oddly-shaped rocks are falling into the chamber from above, presumably
|
||||||
|
due to all the rumbling. If you can't work out where the rocks will fall
|
||||||
|
next, you might be crushed!
|
||||||
|
|
||||||
|
The five types of rocks have the following peculiar shapes, where =#= is
|
||||||
|
rock and =.= is empty space:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
####
|
||||||
|
|
||||||
|
.#.
|
||||||
|
###
|
||||||
|
.#.
|
||||||
|
|
||||||
|
..#
|
||||||
|
..#
|
||||||
|
###
|
||||||
|
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
##
|
||||||
|
##
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
The rocks fall in the order shown above: first the =-= shape, then the
|
||||||
|
=+= shape, and so on. Once the end of the list is reached, the same
|
||||||
|
order repeats: the =-= shape falls first, sixth, 11th, 16th, etc.
|
||||||
|
|
||||||
|
The rocks don't spin, but they do get pushed around by jets of hot gas
|
||||||
|
coming out of the walls themselves. A quick scan reveals the effect the
|
||||||
|
jets of hot gas will have on the rocks as they fall (your puzzle input).
|
||||||
|
|
||||||
|
For example, suppose this was the jet pattern in your cave:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
In jet patterns, =<= means a push to the left, while =>= means a push to
|
||||||
|
the right. The pattern above means that the jets will push a falling
|
||||||
|
rock right, then right, then right, then left, then left, then right,
|
||||||
|
and so on. If the end of the list is reached, it repeats.
|
||||||
|
|
||||||
|
The tall, vertical chamber is exactly /seven units wide/. Each rock
|
||||||
|
appears so that its left edge is two units away from the left wall and
|
||||||
|
its bottom edge is three units above the highest rock in the room (or
|
||||||
|
the floor, if there isn't one).
|
||||||
|
|
||||||
|
After a rock appears, it alternates between /being pushed by a jet of
|
||||||
|
hot gas/ one unit (in the direction indicated by the next symbol in the
|
||||||
|
jet pattern) and then /falling one unit down/. If any movement would
|
||||||
|
cause any part of the rock to move into the walls, floor, or a stopped
|
||||||
|
rock, the movement instead does not occur. If a /downward/ movement
|
||||||
|
would have caused a falling rock to move into the floor or an
|
||||||
|
already-fallen rock, the falling rock stops where it is (having landed
|
||||||
|
on something) and a new rock immediately begins falling.
|
||||||
|
|
||||||
|
Drawing falling rocks with =@= and stopped rocks with =#=, the jet
|
||||||
|
pattern in the example above manifests as follows:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
The first rock begins falling:
|
||||||
|
|..@@@@.|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
+-------+
|
||||||
|
|
||||||
|
Jet of gas pushes rock right:
|
||||||
|
|...@@@@|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
+-------+
|
||||||
|
|
||||||
|
Rock falls 1 unit:
|
||||||
|
|...@@@@|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
+-------+
|
||||||
|
|
||||||
|
Jet of gas pushes rock right, but nothing happens:
|
||||||
|
|...@@@@|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
+-------+
|
||||||
|
|
||||||
|
Rock falls 1 unit:
|
||||||
|
|...@@@@|
|
||||||
|
|.......|
|
||||||
|
+-------+
|
||||||
|
|
||||||
|
Jet of gas pushes rock right, but nothing happens:
|
||||||
|
|...@@@@|
|
||||||
|
|.......|
|
||||||
|
+-------+
|
||||||
|
|
||||||
|
Rock falls 1 unit:
|
||||||
|
|...@@@@|
|
||||||
|
+-------+
|
||||||
|
|
||||||
|
Jet of gas pushes rock left:
|
||||||
|
|..@@@@.|
|
||||||
|
+-------+
|
||||||
|
|
||||||
|
Rock falls 1 unit, causing it to come to rest:
|
||||||
|
|..####.|
|
||||||
|
+-------+
|
||||||
|
|
||||||
|
A new rock begins falling:
|
||||||
|
|...@...|
|
||||||
|
|..@@@..|
|
||||||
|
|...@...|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
|..####.|
|
||||||
|
+-------+
|
||||||
|
|
||||||
|
Jet of gas pushes rock left:
|
||||||
|
|..@....|
|
||||||
|
|.@@@...|
|
||||||
|
|..@....|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
|..####.|
|
||||||
|
+-------+
|
||||||
|
|
||||||
|
Rock falls 1 unit:
|
||||||
|
|..@....|
|
||||||
|
|.@@@...|
|
||||||
|
|..@....|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
|..####.|
|
||||||
|
+-------+
|
||||||
|
|
||||||
|
Jet of gas pushes rock right:
|
||||||
|
|...@...|
|
||||||
|
|..@@@..|
|
||||||
|
|...@...|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
|..####.|
|
||||||
|
+-------+
|
||||||
|
|
||||||
|
Rock falls 1 unit:
|
||||||
|
|...@...|
|
||||||
|
|..@@@..|
|
||||||
|
|...@...|
|
||||||
|
|.......|
|
||||||
|
|..####.|
|
||||||
|
+-------+
|
||||||
|
|
||||||
|
Jet of gas pushes rock left:
|
||||||
|
|..@....|
|
||||||
|
|.@@@...|
|
||||||
|
|..@....|
|
||||||
|
|.......|
|
||||||
|
|..####.|
|
||||||
|
+-------+
|
||||||
|
|
||||||
|
Rock falls 1 unit:
|
||||||
|
|..@....|
|
||||||
|
|.@@@...|
|
||||||
|
|..@....|
|
||||||
|
|..####.|
|
||||||
|
+-------+
|
||||||
|
|
||||||
|
Jet of gas pushes rock right:
|
||||||
|
|...@...|
|
||||||
|
|..@@@..|
|
||||||
|
|...@...|
|
||||||
|
|..####.|
|
||||||
|
+-------+
|
||||||
|
|
||||||
|
Rock falls 1 unit, causing it to come to rest:
|
||||||
|
|...#...|
|
||||||
|
|..###..|
|
||||||
|
|...#...|
|
||||||
|
|..####.|
|
||||||
|
+-------+
|
||||||
|
|
||||||
|
A new rock begins falling:
|
||||||
|
|....@..|
|
||||||
|
|....@..|
|
||||||
|
|..@@@..|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
|...#...|
|
||||||
|
|..###..|
|
||||||
|
|...#...|
|
||||||
|
|..####.|
|
||||||
|
+-------+
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
The moment each of the next few rocks begins falling, you would see
|
||||||
|
this:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
|..@....|
|
||||||
|
|..@....|
|
||||||
|
|..@....|
|
||||||
|
|..@....|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
|..#....|
|
||||||
|
|..#....|
|
||||||
|
|####...|
|
||||||
|
|..###..|
|
||||||
|
|...#...|
|
||||||
|
|..####.|
|
||||||
|
+-------+
|
||||||
|
|
||||||
|
|..@@...|
|
||||||
|
|..@@...|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
|....#..|
|
||||||
|
|..#.#..|
|
||||||
|
|..#.#..|
|
||||||
|
|#####..|
|
||||||
|
|..###..|
|
||||||
|
|...#...|
|
||||||
|
|..####.|
|
||||||
|
+-------+
|
||||||
|
|
||||||
|
|..@@@@.|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
|....##.|
|
||||||
|
|....##.|
|
||||||
|
|....#..|
|
||||||
|
|..#.#..|
|
||||||
|
|..#.#..|
|
||||||
|
|#####..|
|
||||||
|
|..###..|
|
||||||
|
|...#...|
|
||||||
|
|..####.|
|
||||||
|
+-------+
|
||||||
|
|
||||||
|
|...@...|
|
||||||
|
|..@@@..|
|
||||||
|
|...@...|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
|.####..|
|
||||||
|
|....##.|
|
||||||
|
|....##.|
|
||||||
|
|....#..|
|
||||||
|
|..#.#..|
|
||||||
|
|..#.#..|
|
||||||
|
|#####..|
|
||||||
|
|..###..|
|
||||||
|
|...#...|
|
||||||
|
|..####.|
|
||||||
|
+-------+
|
||||||
|
|
||||||
|
|....@..|
|
||||||
|
|....@..|
|
||||||
|
|..@@@..|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
|..#....|
|
||||||
|
|.###...|
|
||||||
|
|..#....|
|
||||||
|
|.####..|
|
||||||
|
|....##.|
|
||||||
|
|....##.|
|
||||||
|
|....#..|
|
||||||
|
|..#.#..|
|
||||||
|
|..#.#..|
|
||||||
|
|#####..|
|
||||||
|
|..###..|
|
||||||
|
|...#...|
|
||||||
|
|..####.|
|
||||||
|
+-------+
|
||||||
|
|
||||||
|
|..@....|
|
||||||
|
|..@....|
|
||||||
|
|..@....|
|
||||||
|
|..@....|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
|.....#.|
|
||||||
|
|.....#.|
|
||||||
|
|..####.|
|
||||||
|
|.###...|
|
||||||
|
|..#....|
|
||||||
|
|.####..|
|
||||||
|
|....##.|
|
||||||
|
|....##.|
|
||||||
|
|....#..|
|
||||||
|
|..#.#..|
|
||||||
|
|..#.#..|
|
||||||
|
|#####..|
|
||||||
|
|..###..|
|
||||||
|
|...#...|
|
||||||
|
|..####.|
|
||||||
|
+-------+
|
||||||
|
|
||||||
|
|..@@...|
|
||||||
|
|..@@...|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
|....#..|
|
||||||
|
|....#..|
|
||||||
|
|....##.|
|
||||||
|
|....##.|
|
||||||
|
|..####.|
|
||||||
|
|.###...|
|
||||||
|
|..#....|
|
||||||
|
|.####..|
|
||||||
|
|....##.|
|
||||||
|
|....##.|
|
||||||
|
|....#..|
|
||||||
|
|..#.#..|
|
||||||
|
|..#.#..|
|
||||||
|
|#####..|
|
||||||
|
|..###..|
|
||||||
|
|...#...|
|
||||||
|
|..####.|
|
||||||
|
+-------+
|
||||||
|
|
||||||
|
|..@@@@.|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
|.......|
|
||||||
|
|....#..|
|
||||||
|
|....#..|
|
||||||
|
|....##.|
|
||||||
|
|##..##.|
|
||||||
|
|######.|
|
||||||
|
|.###...|
|
||||||
|
|..#....|
|
||||||
|
|.####..|
|
||||||
|
|....##.|
|
||||||
|
|....##.|
|
||||||
|
|....#..|
|
||||||
|
|..#.#..|
|
||||||
|
|..#.#..|
|
||||||
|
|#####..|
|
||||||
|
|..###..|
|
||||||
|
|...#...|
|
||||||
|
|..####.|
|
||||||
|
+-------+
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
To prove to the elephants your simulation is accurate, they want to know
|
||||||
|
how tall the tower will get after 2022 rocks have stopped (but before
|
||||||
|
the 2023rd rock begins falling). In this example, the tower of rocks
|
||||||
|
will be =3068= units tall.
|
||||||
|
|
||||||
|
/How many units tall will the tower of rocks be after 2022 rocks have
|
||||||
|
stopped falling?/
|
17
2022/day17/aoc.h
Normal file
17
2022/day17/aoc.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/* aoc.c: Advent of Code 2022
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022-2023 Bruno Raoult ("br")
|
||||||
|
* Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
* Some rights reserved. See COPYING.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this
|
||||||
|
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
*/
|
||||||
|
#ifndef _AOC_H_
|
||||||
|
#define _AOC_H_
|
||||||
|
|
||||||
|
extern int parseargs(int ac, char**av);
|
||||||
|
extern int testmode(void);
|
||||||
|
#endif /* _AOC_H_ */
|
68
2022/day17/common.bash
Normal file
68
2022/day17/common.bash
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# common.bash: Advent of Code 2022, common bash functions
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022-2023 Bruno Raoult ("br")
|
||||||
|
# Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
# Some rights reserved. See COPYING.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along with this
|
||||||
|
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
|
||||||
|
# shellcheck disable=2034
|
||||||
|
export cmdname=${0##*/}
|
||||||
|
export debug=0
|
||||||
|
export res
|
||||||
|
export LANG=C
|
||||||
|
|
||||||
|
shopt -s extglob
|
||||||
|
set -o noglob
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
printf "usage: %s [-d DEBUG] [-p PART]\n" "$cmdname"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
checkargs() {
|
||||||
|
local part=1
|
||||||
|
while getopts p:d: todo; do
|
||||||
|
case "$todo" in
|
||||||
|
d)
|
||||||
|
if [[ "$OPTARG" =~ ^[[:digit:]+]$ ]]; then
|
||||||
|
debug="$OPTARG"
|
||||||
|
else
|
||||||
|
printf "%s: illegal [%s] debug level.\n" "$CMD" "$OPTARG"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
p)
|
||||||
|
if [[ "$OPTARG" =~ ^[12]$ ]]; then
|
||||||
|
part="$OPTARG"
|
||||||
|
else
|
||||||
|
printf "%s: illegal [%s] part.\n" "$CMD" "$OPTARG"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
# Now check remaining argument (backup directory)
|
||||||
|
shift $((OPTIND - 1))
|
||||||
|
|
||||||
|
(( $# > 1 )) && usage
|
||||||
|
return "$part"
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
local -i part
|
||||||
|
|
||||||
|
checkargs "$@"
|
||||||
|
part=$?
|
||||||
|
parse "$part"
|
||||||
|
solve "$part"
|
||||||
|
printf "%s: res=%s\n" "$cmdname" "$res"
|
||||||
|
}
|
59
2022/day17/common.c
Normal file
59
2022/day17/common.c
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/* common.c: Advent of Code 2022, common functions
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022-2023 Bruno Raoult ("br")
|
||||||
|
* Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
* Some rights reserved. See COPYING.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this
|
||||||
|
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "aoc.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
static int _testmode = 0;
|
||||||
|
|
||||||
|
static int usage(char *prg)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: %s [-t][-d debug_level] [-p part] [-i input]\n", prg);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int testmode(void)
|
||||||
|
{
|
||||||
|
return _testmode;
|
||||||
|
}
|
||||||
|
|
||||||
|
int parseargs(int ac, char **av)
|
||||||
|
{
|
||||||
|
int opt, part = 1;
|
||||||
|
|
||||||
|
while ((opt = getopt(ac, av, "td:p:")) != -1) {
|
||||||
|
switch (opt) {
|
||||||
|
case 't':
|
||||||
|
_testmode = 1;
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
debug_level_set(atoi(optarg));
|
||||||
|
break;
|
||||||
|
case 'p': /* 1 or 2 */
|
||||||
|
part = atoi(optarg);
|
||||||
|
if (part < 1 || part > 2)
|
||||||
|
return usage(*av);
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
|
||||||
|
default:
|
||||||
|
return usage(*av);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (optind < ac)
|
||||||
|
return usage(*av);
|
||||||
|
return part;
|
||||||
|
}
|
1
2022/day17/input/example.txt
Normal file
1
2022/day17/input/example.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>
|
1
2022/day17/input/input.txt
Normal file
1
2022/day17/input/input.txt
Normal file
File diff suppressed because one or more lines are too long
@@ -25,6 +25,7 @@
|
|||||||
#ifdef DEBUG_DEBUG
|
#ifdef DEBUG_DEBUG
|
||||||
void debug_init(u32 level);
|
void debug_init(u32 level);
|
||||||
void debug_level_set(u32 level);
|
void debug_level_set(u32 level);
|
||||||
|
u32 debug_level_get(void);
|
||||||
void _printf debug(u32 level, bool timestamp,
|
void _printf debug(u32 level, bool timestamp,
|
||||||
u32 indent, const char *src,
|
u32 indent, const char *src,
|
||||||
u32 line, const char *, ...);
|
u32 line, const char *, ...);
|
||||||
|
88
2022/libsrc/Makefile
Normal file
88
2022/libsrc/Makefile
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
# AOC Makefile - GNU make only.
|
||||||
|
#
|
||||||
|
# Copyright (C) 2021-2022 Bruno Raoult ("br")
|
||||||
|
# Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
# Some rights reserved. See COPYING.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along with this
|
||||||
|
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
#
|
||||||
|
|
||||||
|
SHELL := /bin/bash
|
||||||
|
CC := gcc
|
||||||
|
BEAR := bear
|
||||||
|
CCLSFILE:= compile_commands.json
|
||||||
|
|
||||||
|
#LIBS = -lreadline -lncurses
|
||||||
|
CFLAGS += -std=gnu11
|
||||||
|
|
||||||
|
CFLAGS += -O2
|
||||||
|
CFLAGS += -g
|
||||||
|
# for gprof
|
||||||
|
#CFLAGS += -pg
|
||||||
|
CFLAGS += -Wall
|
||||||
|
CFLAGS += -Wextra
|
||||||
|
CFLAGS += -march=native
|
||||||
|
|
||||||
|
CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
|
||||||
|
CFLAGS += -DDEBUG_POOL # memory pools management
|
||||||
|
# Next one may be useful for valgrind (some invalid instructions)
|
||||||
|
# CFLAGS += -mno-tbm
|
||||||
|
CFLAGS += -Wmissing-declarations
|
||||||
|
CFLAGS += -Wno-unused-result
|
||||||
|
|
||||||
|
INCDIR := ../include
|
||||||
|
LIBSRCDIR := .
|
||||||
|
LIBDIR := ../lib
|
||||||
|
LIB := libaoc_$(shell uname -m)
|
||||||
|
SLIB := $(LIBDIR)/$(LIB).a
|
||||||
|
DLIB := $(LIBDIR)/$(LIB).so
|
||||||
|
LIBSRC := $(wildcard $(LIBSRCDIR)/*.c)
|
||||||
|
LIBOBJ := $(patsubst %.c,%.o,$(LIBSRC))
|
||||||
|
LDFLAGS := -L$(LIBDIR)
|
||||||
|
LDLIB := -l$(LIB)
|
||||||
|
|
||||||
|
.PHONY: clean cleanlib cleanall all redo output lib $(SUBDIRS)
|
||||||
|
|
||||||
|
all: lib $(SUBDIRS)
|
||||||
|
|
||||||
|
compile: $(LIBOBJ)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@$(RM) -f *.o *.s *.i $(LIBOBJ)
|
||||||
|
|
||||||
|
cleanall: clean
|
||||||
|
@$(RM) -f $(SLIB) $(DLIB) $(LIBOBJ)
|
||||||
|
|
||||||
|
lib: $(DLIB) $(SLIB)
|
||||||
|
|
||||||
|
$(SLIB): $(LIBOBJ)
|
||||||
|
@echo building $@ static library.
|
||||||
|
@mkdir -p $(LIBDIR)
|
||||||
|
@$(AR) $(ARFLAGS) -o $@ $^
|
||||||
|
|
||||||
|
$(DLIB): CFLAGS += -fPIC
|
||||||
|
$(DLIB): LDFLAGS += -shared
|
||||||
|
$(DLIB): $(LIBOBJ)
|
||||||
|
@echo building $@ shared library.
|
||||||
|
@mkdir -p $(LIBDIR)
|
||||||
|
@$(CC) $(LDFLAGS) $^ -o $@
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
@echo compiling $<.
|
||||||
|
@$(CC) -c $(CFLAGS) $(LDFLAGS) -I $(INCDIR) -o $@ $<
|
||||||
|
|
||||||
|
# generate pre-processed file (.i) and assembler (.s)
|
||||||
|
%.i: %.c
|
||||||
|
@echo generating $@
|
||||||
|
@$(CC) -E $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||||
|
|
||||||
|
%.s: %.c
|
||||||
|
@echo generating $@
|
||||||
|
@$(CC) -S -fverbose-asm $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||||
|
|
||||||
|
bear: clean
|
||||||
|
@touch .ccls-root
|
||||||
|
@$(BEAR) -- make compile
|
@@ -35,6 +35,11 @@ void debug_level_set(u32 level)
|
|||||||
log(1, "debug level set to %u\n", level);
|
log(1, "debug level set to %u\n", level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 debug_level_get()
|
||||||
|
{
|
||||||
|
return debug_level;
|
||||||
|
}
|
||||||
|
|
||||||
void debug_init(u32 level)
|
void debug_init(u32 level)
|
||||||
{
|
{
|
||||||
struct timespec timer;
|
struct timespec timer;
|
||||||
|
@@ -14,3 +14,7 @@
|
|||||||
|
|
||||||
#### Advent of Code 2021
|
#### Advent of Code 2021
|
||||||
- `C`: All (days 1-25)
|
- `C`: All (days 1-25)
|
||||||
|
|
||||||
|
#### Advent of Code 2022
|
||||||
|
- `Bash`: All (days 1-12)
|
||||||
|
- `C`: All (days 1-14)
|
||||||
|
Reference in New Issue
Block a user