summaryrefslogtreecommitdiff
path: root/11.c
diff options
context:
space:
mode:
Diffstat (limited to '11.c')
-rw-r--r--11.c77
1 files changed, 64 insertions, 13 deletions
diff --git a/11.c b/11.c
index ec06772..5f14466 100644
--- a/11.c
+++ b/11.c
@@ -1,8 +1,10 @@
#include <ctype.h>
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
enum worry_op {
@@ -14,7 +16,7 @@ enum worry_op {
struct monkey {
- int * items;
+ unsigned long * items;
int nitems;
enum worry_op wo;
int wparam;
@@ -62,7 +64,7 @@ monkey_additem(struct monkey * m, int worry)
void * p;
++m->nitems;
- p = realloc(m->items, m->nitems * sizeof(int));
+ p = realloc(m->items, m->nitems * sizeof(unsigned long));
if (!p)
return 0;
m->items = p;
@@ -74,24 +76,54 @@ monkey_additem(struct monkey * m, int worry)
void
monkey_dump(struct monkey const * m, int n)
{
- int * i;
+ unsigned long * item;
fprintf(stderr, "Monkey %d: %d/%d/%d/%d/%d/%d: ",
n, m->wo, m->wparam, m->test_div, m->test_true, m->test_false, m->inspections);
- for (i = m->items; i < m->items + m->nitems; ++i) {
- fprintf(stderr, "%s%d", i == m->items ? "" : ", ", *i);
+ for (item = m->items; item < m->items + m->nitems; ++item) {
+ fprintf(stderr, "%s%lu", item == m->items ? "" : ", ", *item);
}
fprintf(stderr, "\n");
}
int
-main()
+main(int argc, char ** argv)
{
char buf[BUFSIZ];
struct monkey * monkeys = NULL, * m = NULL;
int nmonkeys = 0;
int i, j;
+ int calming = 3, rounds = 20;
+
+ while ((i = getopt(argc, argv, "p:c:r:")) != -1) {
+ switch (i) {
+ case 'p':
+ switch (atol(optarg)) {
+ case 1: calming = 3; rounds = 20; break;
+ case 2: calming = 1; rounds = 10000; break;
+ default:
+ fprintf(stderr, "Unexpected part %d\n", atoi(optarg));
+ return -1;
+ }
+ break;
+
+ case 'c':
+ calming = atoi(optarg);
+ if (calming == 0) {
+ fprintf(stderr, "Unexpected calming factor %d\n", calming);
+ return -1;
+ }
+ break;
+
+ case 'r':
+ rounds = atoi(optarg);
+ break;
+
+ default:
+ return -1;
+ }
+ }
// Read monkey data
while (fgets(buf, sizeof(buf), stdin)) {
@@ -176,20 +208,39 @@ main()
}
// Perform monkey inspection rounds
- for (i = 0; i < 20; ++i) {
+ for (i = 0; i < rounds; ++i) {
for (m = monkeys; m < monkeys + nmonkeys; ++m) {
- int * item;
+ unsigned long * item;
for (item = m->items; item < m->items + m->nitems; ++item) {
int catcher;
switch (m->wo) {
- case WO_NONE: break; /* shouldn't happen */
- case WO_ADD: *item += m->wparam; break;
- case WO_MUL: *item *= m->wparam; break;
- case WO_SQR: *item *= *item; break;
+ case WO_NONE:
+ break; /* shouldn't happen */
+ case WO_ADD:
+ if (*item > ULONG_MAX - m->wparam)
+ fprintf(stderr, "%d/%d/%d: Overflow: %lu > %lu - %d\n",
+ i, (int) (monkeys - m), (int) (item - m->items),
+ *item, ULONG_MAX, m->wparam);
+ *item += m->wparam;
+ break;
+ case WO_MUL:
+ if (*item >= ULONG_MAX / m->wparam)
+ fprintf(stderr, "%d/%d/%d: Overflow: %lu >= %lu / %d\n",
+ i, (int) (monkeys - m), (int) (item - m->items),
+ *item, ULONG_MAX, m->wparam);
+ *item *= m->wparam;
+ break;
+ case WO_SQR:
+ if (*item >= ULONG_MAX / *item)
+ fprintf(stderr, "%d/%d/%d: Overflow: %lu >= %lu / %lu\n",
+ i, (int) (monkeys - m), (int) (item - m->items),
+ *item, ULONG_MAX, *item);
+ *item *= *item;
+ break;
}
- *item /= 3;
+ *item /= calming;
catcher = *item % m->test_div ? m->test_false : m->test_true;
monkey_additem(monkeys + catcher, *item);