You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

135 lines
4.1KB

  1. //
  2. // Created by red on 03/12/19.
  3. //
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <zconf.h>
  7. #include <string.h>
  8. #include <stdbool.h>
  9. struct Point {
  10. int x;
  11. int y;
  12. };
  13. #ifndef ORIGIN
  14. #define ORIGIN (struct Point){.x=0,.y=0,}
  15. #endif
  16. //given a point, a direction and a distance, return the point that's that distance in the given direction
  17. struct Point get_pt(char dir, int delta, struct Point loc) {
  18. struct Point dloc;
  19. switch(dir) {
  20. case 'R': dloc = (struct Point){
  21. .x = loc.x + delta,
  22. .y = loc.y,
  23. }; break;
  24. case 'L': dloc = (struct Point){
  25. .x = loc.x - delta,
  26. .y = loc.y,
  27. }; break;
  28. case 'U': dloc = (struct Point){
  29. .x = loc.x,
  30. .y = loc.y + delta,
  31. }; break;
  32. case 'D': dloc = (struct Point){
  33. .x = loc.x,
  34. .y = loc.y - delta,
  35. }; break;
  36. default: dloc = loc;
  37. }
  38. return dloc;
  39. }
  40. //takes four points, checks if the line a1 - a2 intersects b1 - b2, returns intersection point if yes, origin otherwise
  41. struct Point intersects(struct Point a1, struct Point a2, struct Point b1, struct Point b2) {
  42. bool a_isvert = (a1.x == a2.x);
  43. bool b_isvert = (b1.x == b2.x);
  44. if (a_isvert == b_isvert) { //no collision if lines are both vertical or both horizontal
  45. return ORIGIN;
  46. }
  47. // if b is vertical, call the function again with the operands reversed. we want to assume a is vertical
  48. if (b_isvert) {
  49. return intersects(b1, b2, a1, a2);
  50. }
  51. // determine the smaller and bigger x-coord of b1 & b2. same for y-coord of a1 & a2
  52. int b_lx = (b1.x < b2.x) ? b1.x : b2.x;
  53. int b_gx = (b1.x < b2.x) ? b2.x : b1.x;
  54. int a_ly = (a1.y < a2.y) ? a1.y : a2.y;
  55. int a_gy = (a1.y < a2.y) ? a2.y : a1.y;
  56. // if the x-coord of a1 is somewhere between b1 and b2, and the y-coord of b1 is somewhere between a1 and a2
  57. // then the lines must intersect.
  58. if (a1.x > b_lx && a1.x < b_gx && b1.y > a_ly && b1.y < a_gy) {
  59. //return the manhattan distance of the intersection
  60. return (struct Point){
  61. .x = a1.x,
  62. .y = b1.y,
  63. };
  64. }
  65. //if the end of the function is reached, the lines don't intersect.
  66. return ORIGIN;
  67. }
  68. //returns the manhattan distance between two points
  69. int manhattan(struct Point a, struct Point b) {
  70. return (abs(a.x - b.x) + abs(a.y - b.y));
  71. }
  72. //scan an input string, saving all the points to out. return the no. of points read
  73. size_t scan_points(char* in, struct Point* out){
  74. //sequence is assumed to start at the origin.
  75. out[0] = ORIGIN;
  76. size_t i = 1;
  77. while (*in != 0) { //read until null
  78. char dir;
  79. int delta;
  80. int num_read;
  81. sscanf(in, "%c%d%n", &dir, &delta, &num_read);
  82. out[i] = get_pt(dir, delta, out[i]);
  83. i++;
  84. in += num_read + 1; // skip the number we just read, and the separator
  85. }
  86. return i;
  87. }
  88. int main() {
  89. //allocate an input string, and two arrays for input points
  90. //we don't know the exact length of the arrays but we know it's smaller than 400
  91. char* input_raw = calloc(1500,sizeof(char));
  92. scanf("%s", input_raw);
  93. struct Point a[400];
  94. struct Point b[400];
  95. char* ptr = input_raw;
  96. size_t a_size = scan_points(ptr, a);
  97. //clear the input buffer
  98. memset((void*) input_raw, 0, sizeof(char)*1500);
  99. //scan the second input sequence, reset var ptr to the beginning of the string, reset location to the origin
  100. scanf("%s", input_raw);
  101. ptr = input_raw;
  102. size_t b_size = scan_points(ptr, b);
  103. free((void*) input_raw);
  104. /*
  105. * we want to find collisions between a and
  106. */
  107. int min = INT_MAX;
  108. int min_delay = INT_MAX;
  109. int a_delay = 0;
  110. for (size_t i = 1; i < a_size; i++) {
  111. int b_delay = 0;
  112. for (size_t j = 1; j < b_size; j++) {
  113. struct Point pt = intersects(a[i-1], a[i], b[j-1], b[j]);
  114. int dist = manhattan(ORIGIN, pt);
  115. if (dist > 0) {
  116. if (dist < min) min = dist;
  117. int delay = a_delay + b_delay + manhattan(pt, a[i-1]) + manhattan(pt, b[j-1]);
  118. if (delay < min_delay) min_delay = delay;
  119. }
  120. b_delay += manhattan(b[j-1], b[j]);
  121. }
  122. a_delay += manhattan(a[i-1], a[i]);
  123. }
  124. printf("Min. intersection distance from origin: %d\n"
  125. "Min. intersection distance on lines: %d\n", min, min_delay);
  126. return EXIT_SUCCESS;
  127. }