Advertisement
Guest User

Untitled

a guest
Dec 5th, 2016
40
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.61 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <math.h>
  5. #define DAY(n) "input/day" #n ".txt"
  6.  
  7. /* Advent of Code 2016
  8.  * Solution for Day 1, Part 2
  9.  */
  10.  
  11. char *get_filebuffer(const char *path)
  12. {
  13.     FILE *fp = fopen(path, "rb");
  14.     fseek(fp, 0, SEEK_END);
  15.     long len = ftell(fp);
  16.     fseek(fp, 0, SEEK_SET);
  17.     char *buf = (char *) malloc(sizeof(char) * len + 1);
  18.     fread(buf, len, 1, fp);
  19.     buf[len] = '\0';
  20.     fclose(fp);
  21.     return buf;
  22. }
  23.  
  24. struct point {
  25.     int x;
  26.     int y;
  27.     enum { NORTH, EAST, SOUTH, WEST } dir;
  28.     struct point *next;
  29. };
  30.  
  31. struct list {
  32.     struct point *head;
  33.     unsigned depth;
  34. };
  35.  
  36. /* blocks, not shortest distance */
  37. #define distance(a, b) abs(abs((b).x - (a).x) + abs((b).y - (a).y))
  38. #define is_equal(a, b) (((b).x == (a).x) && ((b).y == (a).y))
  39.  
  40. void list_insert(struct list *ls, struct point *pt)
  41. {
  42.     struct point *node = malloc(sizeof(struct point));
  43.     *node = *pt; /* struct copy */
  44.     node->next = ls->head;
  45.     ls->head = node;
  46.     ls->depth++;
  47. }
  48.  
  49. void list_free(struct list *ls)
  50. {
  51.     while (ls->head != NULL)
  52.     {
  53.         struct point *node = ls->head;
  54.         ls->head = node->next;
  55.         free(node);
  56.         ls->depth--;
  57.     }
  58. }
  59.  
  60. int list_search(struct list *ls, struct point *pt)
  61. {
  62.     unsigned i, found = 0;
  63.     if (ls->head != NULL)
  64.     {
  65.         struct point **arr = malloc(sizeof(struct point *) * ls->depth);
  66.         struct point *node = ls->head;
  67.         for (i = 0; i < ls->depth; i++) /* unroll */
  68.             arr[i] = node, node = node->next;
  69.         for (i = ls->depth - 1; i > 0 && !found; --i)
  70.             if (is_equal(*arr[i], *pt))
  71.                 found = !found;
  72.         free(arr);
  73.     }
  74.     return found;
  75. }
  76.  
  77. int main(void)
  78. {
  79.     char *ins = get_filebuffer(DAY(01));
  80. /*  char *ins = get_filebuffer("input/poop.txt"); */
  81.     struct list prev = { 0 };
  82.     struct point orig = { 0 }, pt = { 0 }, act = { 0 };
  83.     unsigned passed = 0;
  84.     char *tok = strtok(ins, " ,");
  85.     while (tok != NULL)
  86.     {
  87.         char rot;
  88.         int dist;
  89.         sscanf(tok, "%c%d", &rot, &dist);
  90.         switch (rot)
  91.         {
  92.             case 'L': pt.dir = (pt.dir == NORTH) ? WEST : pt.dir - 1; break;
  93.             case 'R': pt.dir = (pt.dir == WEST) ? NORTH : pt.dir + 1; break;
  94.         }
  95.         switch (pt.dir)
  96.         {
  97.             case NORTH: pt.y += dist; break;
  98.             case EAST: pt.x += dist; break;
  99.             case SOUTH: pt.y -= dist; break;
  100.             case WEST: pt.x -= dist; break;
  101.         }
  102.         if (!passed && list_search(&prev, &pt))
  103.             act = pt, passed = !passed; /* passed first duplicate coord */
  104.         list_insert(&prev, &pt);
  105.         tok = strtok(NULL, " ,");
  106.     }
  107.     printf("Coords: X: %d Y: %d Blocks: %d\n", pt.x, pt.y, distance(orig, pt));
  108.     printf("Actual: X: %d Y: %d Blocks away: %d\n", act.x, act.y, distance(pt, act));
  109.     list_free(&prev);
  110.     free(ins);
  111.     return 0;
  112. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement