diff --git a/2020/RESULTS.txt b/2020/RESULTS.txt index 5a31033..35a6c7e 100644 --- a/2020/RESULTS.txt +++ b/2020/RESULTS.txt @@ -490,6 +490,10 @@ ex1.bash: res=31314 time: 0:00.07 real, 0.06 user, 0.00 sys context-switch: 2+1, page-faults: 0+168 +aoc-c : res=31314 + time: 0:00.00 real, 0.00 user, 0.00 sys + context-switch: 0+1, page-faults: 0+89 + +++++++++++++++++ ex2 ex2.bash: res=32760 time: 1:21.92 real, 81.89 user, 0.01 sys diff --git a/2020/day22/aoc-c.c b/2020/day22/aoc-c.c new file mode 100644 index 0000000..8b7bd5b --- /dev/null +++ b/2020/day22/aoc-c.c @@ -0,0 +1,134 @@ +/* aoc-c.c: Advent2020, day 22, part 1 + */ + +#include +#include +#include +#include +#include + +#include "list.h" +#include "pool.h" +#include "debug.h" + +struct card { + int card; + struct list_head list; +}; + +struct player { + int ncards; + struct list_head head; +} players[2]; + +pool_t *pool_cards; + +static void print_cards() +{ + struct card *card; + for (int player = 0; player < 2; ++player) { + log(2, "player %d (%d cards): ", player + 1, players[player].ncards); + list_for_each_entry(card, &players[player].head, list) { + log(2, "%d ", card->card); + } + log(2, "\n"); + } +} + +static void parse() +{ + size_t alloc; + ssize_t len; + char *buf = NULL; + int player = -1; + struct card *card; + + INIT_LIST_HEAD(&players[0].head); + INIT_LIST_HEAD(&players[1].head); + players[0].ncards = players[1].ncards = 0; + while ((len = getline(&buf, &alloc, stdin)) > 0) { + buf[--len] = 0; + if (len == 0) + continue; + if (*buf == 'P') { + player++; + continue; + } else if (isdigit(*buf)) { /* card */ + card = pool_get(pool_cards); + card->card = atoi(buf); + players[player].ncards++; + list_add_tail(&card->list, &players[player].head); + } + } + free(buf); +} + +static int usage(char *prg) +{ + fprintf(stderr, "Usage: %s [-d debug_level] [-p part]\n", prg); + return 1; +} + +static long part1() +{ + struct card *c1, *c2; + int round = 0, mult = 1; + long res = 0; + + while (players[0].ncards > 0 && players[1].ncards > 0) { + c1 = list_first_entry_or_null(&players[0].head, struct card, list); + c2 = list_first_entry_or_null(&players[1].head, struct card, list); + if (c1->card > c2->card) { + list_move_tail(&c1->list, &players[0].head); + list_move_tail(&c2->list, &players[0].head); + players[1].ncards--; + players[0].ncards++; + } else { + list_move_tail(&c2->list, &players[1].head); + list_move_tail(&c1->list, &players[1].head); + players[0].ncards--; + players[1].ncards++; + } + round++; + log(2, "\nafter round %d\n", round); + print_cards(); + } + list_for_each_entry_reverse(c1, + players[0].ncards? &players[0].head: &players[1].head, + list) { + res += c1->card * mult++; + }; + return res; +} + +static long part2() +{ + return 2; +} + +int main(ac, av) + 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) + default: + return usage(*av); + } + } + + pool_cards = pool_create("cards", 128, sizeof(struct card)); + + parse(); + print_cards(); + printf("%s : res=%ld\n", *av, part == 1? part1(): part2()); + exit (0); +}