From 7e0a21704e7716468645b6af6823f5017e18f991 Mon Sep 17 00:00:00 2001 From: Bruno Raoult Date: Wed, 21 Dec 2022 13:34:28 +0100 Subject: [PATCH] 2022 day 11: C first version (parts 1 and 2) --- 2022/day11/aoc-c.c | 226 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 2022/day11/aoc-c.c diff --git a/2022/day11/aoc-c.c b/2022/day11/aoc-c.c new file mode 100644 index 0000000..0770b77 --- /dev/null +++ b/2022/day11/aoc-c.c @@ -0,0 +1,226 @@ +/* aoc-c.c: Advent of Code 2022, day 11 + * + * 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 . + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include +#include + +#include "br.h" +#include "debug.h" +#include "list.h" +#include "pool.h" + +#include "aoc.h" + +#define MAXMONKEYS 8 + +static int part1() +{ + return 1; +} + +static int part2() +{ + return 2; +} + +typedef struct monkey { + char op; /* '+' or '*' */ + long values[2]; /* formula operands */ + int div; /* divisor */ + struct list_head *dest[2]; /* destination monkey */ + uint visits; /* total visits */ + struct list_head items; /* monkey items */ +} monkey_t; + +typedef struct item { + int item; + struct list_head list; +} item_t; + +static monkey_t monkeys[MAXMONKEYS]; +static int nmonkeys; +static u64 lcm = 1, divide = 3; +static pool_t *pool_item; + + +static void print_monkeys() +{ + monkey_t *m = monkeys; + item_t *item; + + for (int i = 0; i < nmonkeys; ++i, m++) { + printf("Monkey %d visits:%u\n\titems: ", i, m->visits); + list_for_each_entry(item, &m->items, list) { + printf("%d ", item->item); + } + putchar('\n'); + printf("\ttrue=%ld false=%ld\n", + container_of(&m->dest[0], monkey_t, dest[0]) - monkeys, + container_of(&m->dest[0], monkey_t, dest[1]) - monkeys); + + //printf("\top: %ld %c %ld\n", m->values[0], m->op, m->values[1]); + //printf("\tdiv = %d\n", m->div); + //printf("\ttrue:%ld false:%ld\n", m->dest[1]-monkeys, m->dest[0]-monkeys); + } + //putchar('\n'); +} + +static u64 result() +{ + u64 max1 = 0, max2 = 0; + monkey_t *m = monkeys; + for (int i = 0; i < nmonkeys; ++i, m++) { + if (m->visits > max1) { + max2 = max1; + max1 = m->visits; + } else if (m->visits > max2) { + max2 = m->visits; + } + } + printf("max1=%lu max2=%lu res=%lu", max1, max2, max1*max2); + return max1 * max2; +} + +static void inspect(monkey_t *m) +{ + item_t *item, *tmp; + long op1, op2, res; + + list_for_each_entry_safe(item, tmp, &m->items, list) { + list_del(&item->list); + //printf("Monkey %ld inspects %d\n", m - monkeys, item->item); + m->visits++; + printf("Monkey %ld inspect=%d visits=%d ", m - monkeys, + item->item, m->visits); + op1 = m->values[0] < 0 ? item->item: m->values[0]; + op2 = m->values[1] < 0 ? item->item: m->values[1]; + if (m->op == '+') { + res = op1 + op2; + } else { + res = op1 * op2; + } + printf("op1=%ld op2=%ld op=%c res=%ld ", op1, op2, m->op, res); + res = (res / divide) % lcm; + //printf("final=%ld div=%d dest=%ld\n", res, m->div, + // m->dest[!!(res % m->div)] - monkeys); + item->item = res; + //if (res % m->div) { + list_add_tail(&item->list, m->dest[!!(res % m->div)]); + //} + //print_monkeys(); + } +} + +static char *skip(char *buf, int n) +{ + char *ret; + for (; n >= 0; n--) { + ret = strtok(buf, " ,\n"); + //printf("skip %d=%s\n", n, ret); + buf = NULL; + } + return ret; +} + +static char *getnext() +{ + return strtok(NULL, " ,\n"); +} + +static int parse() +{ + size_t alloc = 0; + char *buf = NULL, *tok; + //ssize_t buflen; + monkey_t *m = monkeys; + + while (getline(&buf, &alloc, stdin) > 0) { + printf("monkey %d\n", nmonkeys); + INIT_LIST_HEAD(&m->items); + + getline(&buf, &alloc, stdin); /* starting items */ + tok = skip(buf, 2); + printf("skip=%s\n", tok); + while (tok) { + item_t *item = pool_get(pool_item); + item->item = atoi(tok); + list_add_tail(&item->list, &m->items); + printf("val = %d\n", item->item); + tok = getnext(); + } + + getline(&buf, &alloc, stdin); /* operation */ + tok = skip(buf, 3); + printf("skip=%s\n", tok); + //tok = getnext(); + //printf("tok=%p %c\n", tok, *tok); + m->values[0] = (*tok == 'o') ? -1: atoi(tok); /* first operand */ + printf("val1 = %ld\n", m->values[0]); + //tok = getnext(); + m->op = *getnext(); /* operator */ + tok = getnext(); + m->values[1] = *tok == 'o' ? -1: atoi(tok); /* second operand */ + printf("val2 = %ld\n", m->values[1]); + + getline(&buf, &alloc, stdin); /* divisible */ + tok=skip(buf, 3); + //printf("skip div=%s\n", tok); + m->div = atoi(tok); + lcm *= m->div; + + getline(&buf, &alloc, stdin); /* true */ + //puts(buf); + tok = skip(buf, 5); + //printf("skip true=%s\n", tok); + m->dest[0] = &(monkeys + atoi(tok))->items; + //printf("true = %ld\n", m->dest[0] - monkeys); + + getline(&buf, &alloc, stdin); /* false */ + tok = skip(buf, 5); + //printf("skip false=%s\n", tok); + m->dest[1] = &(monkeys + atoi(tok))->items; + //printf("false = %ld\n", m->dest[1] - monkeys); + + getline(&buf, &alloc, stdin); /* skip empty line */ + + nmonkeys++; + m++; + printf("\n"); + //print_monkeys(); + //exit(0); + } + printf("lcm = %ld\n", lcm); + print_monkeys(); + free(buf); + return 1; +} + +int main(int ac, char **av) +{ + int part = parseargs(ac, av); + int rounds = part == 1? 20: 10000; + if (part == 2) + divide = 1; + pool_item = pool_create("item", 64, sizeof(item_t)); + + parse(); + for (int r = 0; r < rounds; ++r) { + for (int i = 0; i < nmonkeys; ++i) { + inspect(monkeys + i); + } + printf("+++++++ after round %d\n", r + 1); + print_monkeys(); + } + printf("%s: res=%lu\n", *av, result()); + exit(0); +}