diff --git a/2020/RESULTS.txt b/2020/RESULTS.txt index 18ac875..7783ef8 100644 --- a/2020/RESULTS.txt +++ b/2020/RESULTS.txt @@ -495,11 +495,19 @@ ex1.bash: res=75893264 time: 0:00.01 real, 0.01 user, 0.00 sys context-switch: 0+1, page-faults: 0+166 +aoc-c : res=75893264 + time: 0:00.00 real, 0.00 user, 0.00 sys + context-switch: 0+1, page-faults: 0+83 + +++++++++++++++++ ex2 ex2.bash: res=38162588308 time: 6:52.50 real, 412.30 user, 0.14 sys context-switch: 2219+1, page-faults: 0+30233 +aoc-c : res=38162588308 + time: 0:01.33 real, 1.32 user, 0.01 sys + context-switch: 3+1, page-faults: 0+3992 + ========================================= ================= day24 ================= ========================================= diff --git a/2020/day23/aoc-c.c b/2020/day23/aoc-c.c new file mode 100644 index 0000000..42b141e --- /dev/null +++ b/2020/day23/aoc-c.c @@ -0,0 +1,116 @@ +/* aoc-c.c: Advent2020, day 23, part 1 + */ + +#include +#include +#include +#include +#include + +#include "list.h" +#include "debug.h" + +/* Here we will simply use an array for the numbers (as key is the number + * itself). All elements make a next/prev ring. + * Note: we will ignore array[0] to avoid millions of useless "position -1" + * calculations + */ + +struct list_head *curcup; /* curcup cup */ +struct list_head *cups; /* the cups cups */ +int lastnum; /* last cup number */ + +#define CUR_CUP (&*curcup) +#define NUM(pcup) ((pcup) - cups) + +static __always_inline void step() +{ + struct list_head *first, *last, *dest = CUR_CUP; + int num[3] = { 0 }; + + first = CUR_CUP->next; + last = first->next->next; + num[0] = NUM(first); + num[1] = NUM(first->next); + num[2] = NUM(last); + + do { + if (NUM(--dest) <= 0) + dest = &cups[lastnum]; + } while (NUM(dest) == num[0] || NUM(dest) == num[1] || NUM(dest) == num[2]); + + //list_bulk_move_tail(dest->next, first, last); + list_bulk_move(dest, first, last); + curcup = CUR_CUP->next; +} + +/** + * parse - initialize cups list. + */ +static void parse(int last) +{ + int count = 0, c; + cups = malloc(sizeof(struct list_head) * (last + 1)); + + if (cups) { + for (c = getchar(); isdigit(c); c = getchar(), ++count) { + struct list_head *next = &cups[c - '0']; + if (!count) /* first cup */ + INIT_LIST_HEAD(curcup = next); + else + list_add_tail(&cups[c - '0'], CUR_CUP); + } + for (++count; count <= last; ++count) /* add remaining cups */ + list_add_tail(&cups[count], CUR_CUP); + } +} + +static long part1() +{ + struct list_head *cur; + int res = 0; + list_for_each(cur, &cups[1]) { + res = res * 10 + NUM(cur); + } + return res; +} + +static long part2() +{ + return NUM((&cups[1])->next) * NUM((&cups[1])->next->next); +} + +static int usage(char *prg) +{ + fprintf(stderr, "Usage: %s [-d debug_level] [-p part]\n", prg); + return 1; +} + +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); + } + } + + lastnum = part == 1? 9: 1000000; + int loops = part == 1? 100: 10000000; + parse(lastnum); + for (int i = 0; i < loops; ++i) + step(); + printf("%s : res=%ld\n", *av, part == 1? part1(): part2()); + free(cups); + exit (0); +}