diff options
author | Adam Spragg <adam@spra.gg> | 2022-12-11 17:59:18 +0000 |
---|---|---|
committer | Adam Spragg <adam@spra.gg> | 2022-12-11 17:59:18 +0000 |
commit | 2517d9765da22386852d75bdfb4f70b5181c0c35 (patch) | |
tree | 777624d497130ea79b345a9c2744ddf4de3a099b | |
parent | 750bbe645053b3b7112f1dbfbb619ffc7ebc7668 (diff) |
First attempt at puzzle 11 part 2 (buggy)
Turned item worry levels to unsigned long in an attempt to not overflow.
Added checks for overflow, and they get hit - quickly - without the
calming factor. Will need to think about this. (or try bignums)
-rw-r--r-- | 11.c | 77 |
1 files changed, 64 insertions, 13 deletions
@@ -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); |