Advertisement
Guest User

12-new.c

a guest
Feb 24th, 2022
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.74 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdbool.h>
  4.  
  5. #include "strmanip.h"
  6. #include "memmanage.h"
  7.  
  8. /* Types */
  9. typedef struct cave {
  10.     char *name;
  11.     bool is_small;
  12.     int visits;
  13.  
  14.     struct cave **conn_list;
  15.     int conn_cnt;
  16.     int cap;
  17. } cave;
  18.  
  19. typedef struct {
  20.     cave **cave_list;
  21.     int cave_cnt;
  22.     int cap;
  23. } cntxt;
  24.  
  25. /* Function declarations */
  26. void input_caves(cntxt *c);
  27. cave* get_cave(cntxt *c, char *name);
  28. cave* alloc_cave(cntxt *c, char *name);
  29. void connect_caves(cave *a, cave *b);
  30. int pathfind(cave *curr, int max_vst, _Bool vstd_twice);
  31.  
  32. int
  33. main(void)
  34. {
  35.     cntxt c = {
  36.         .cave_list = NULL,
  37.         .cave_cnt = 0,
  38.         .cap = 0
  39.     };
  40.  
  41.     input_caves(&c);
  42.  
  43.     cave *start = get_cave(&c, "start");
  44.  
  45.     printf("Part 1: %u\n", pathfind(start, 1, false));
  46.     printf("Part 2: %u\n", pathfind(start, 2, false));
  47.  
  48.     mem_clean();
  49.  
  50.     return 0;
  51. }
  52.  
  53. void
  54. input_caves(cntxt *c)
  55. {
  56.     char *s = NULL;
  57.  
  58.     while ((s = str_input()))
  59.     {
  60.         char *name_a = str_word(0, s);
  61.         char *name_b = str_word(1, s);
  62.  
  63.         cave *a = get_cave(c, name_a);
  64.         if (a == NULL) a = alloc_cave(c, name_a);
  65.  
  66.         cave *b = get_cave(c, name_b);
  67.         if (b == NULL) b = alloc_cave(c, name_b);
  68.  
  69.         connect_caves(a, b);
  70.     }
  71. }
  72.  
  73. cave*
  74. get_cave(cntxt *c, char *name)
  75. {
  76.     for (int i = 0; i < c->cave_cnt; ++i) {
  77.         if (strcmp(name, c->cave_list[i]->name) == 0)
  78.             return c->cave_list[i];
  79.     }
  80.  
  81.     return NULL;
  82. }
  83.  
  84. cave*
  85. alloc_cave(cntxt *c, char *name)
  86. {
  87.     cave *p = mem_alloc(sizeof(cave));
  88.     p->name = name;
  89.     p->is_small = 'a' <= *name && *name <= 'z';
  90.     p->conn_list = NULL;
  91.     p->conn_cnt = 0;
  92.     p->cap = 0;
  93.  
  94.     if (c->cave_cnt == c->cap)
  95.         c->cave_list = mem_realloc(c->cave_list, (c->cap += 128) * sizeof(cave*));
  96.  
  97.     c->cave_list[c->cave_cnt++] = p;
  98.  
  99.     return p;
  100. }
  101.  
  102. void
  103. connect_caves(cave *a, cave *b)
  104. {
  105.     if (a->conn_cnt == a->cap)
  106.         a->conn_list = mem_realloc(a->conn_list, (a->cap += 128) * sizeof(cave*));
  107.     if (b->conn_cnt == b->cap)
  108.         b->conn_list = mem_realloc(b->conn_list, (b->cap += 128) * sizeof(cave*));
  109.  
  110.     a->conn_list[a->conn_cnt++] = b;
  111.     b->conn_list[b->conn_cnt++] = a;
  112. }
  113.  
  114. int
  115. pathfind(cave *curr, int max_vst, _Bool vstd_twice)
  116. {
  117.     if (strcmp(curr->name, "end") == 0)
  118.         return 1;
  119.  
  120.     if (
  121.         curr->is_small && curr->visits >= 1 &&
  122.         (strcmp(curr->name, "start") == 0 || max_vst == 1 || vstd_twice)
  123.        )
  124.         return 0;
  125.  
  126.     ++curr->visits;
  127.     vstd_twice = vstd_twice || (curr->is_small && max_vst == 2 && curr->visits >= 2);
  128.  
  129.     int found_paths = 0;
  130.  
  131.     for (int i = 0; i < curr->conn_cnt; ++i)
  132.         found_paths += pathfind(curr->conn_list[i], max_vst, vstd_twice);
  133.  
  134.     --curr->visits; /* When the algorithm backtracks a cave, it's as if it hadn't been visited before, so it has *
  135.                      * to sub 1 from the visit counter.                                                          */
  136.  
  137.     return found_paths;
  138. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement