Advertisement
Guest User

Untitled

a guest
Feb 9th, 2016
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.20 KB | None | 0 0
  1. #include <stddef.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <limits.h>
  6.  
  7. #define MAX_CITIES 10
  8.  
  9. struct route;
  10.  
  11. struct city
  12. {
  13. char name[16];
  14. struct route* routes;
  15. };
  16.  
  17. struct city* add_city(struct city** cities, const char* name, size_t maxcount)
  18. {
  19. struct city* c;
  20.  
  21. while (*cities && maxcount--)
  22. cities++;
  23. if (!maxcount) return NULL;
  24.  
  25. c = *cities = calloc(1, sizeof **cities);
  26. if (c) strcpy(c->name, name);
  27.  
  28. return c;
  29. }
  30.  
  31. struct city* find_city(struct city** cities, const char* name)
  32. {
  33. while (*cities)
  34. {
  35. if (strcmp((*cities)->name, name) == 0)
  36. return *cities;
  37.  
  38. ++cities;
  39. }
  40.  
  41. return NULL;
  42. }
  43.  
  44. struct city* find_or_add_city(struct city** cities, const char* name, size_t maxcount)
  45. {
  46. struct city* c;
  47. if ((c = find_city(cities, name)) == NULL)
  48. c = add_city(cities, name, maxcount);
  49.  
  50. return c;
  51. }
  52.  
  53. struct route
  54. {
  55. struct city* to;
  56. unsigned distance;
  57.  
  58. struct route* next;
  59. };
  60.  
  61. void do_add_route(struct city* from, struct city* to, unsigned distance)
  62. {
  63. struct route* rte = from->routes,
  64. * newrte = calloc(1, sizeof *newrte);
  65.  
  66. if (!newrte)
  67. {
  68. perror("can't create route");
  69. exit(EXIT_FAILURE);
  70. }
  71.  
  72. newrte->to = to;
  73. newrte->distance = distance;
  74.  
  75. if (!rte)
  76. from->routes = newrte;
  77. else
  78. {
  79. while (rte->next)
  80. rte = rte->next;
  81.  
  82. rte->next = newrte;
  83. }
  84. }
  85.  
  86. void add_route(struct city* from, struct city* to, unsigned distance)
  87. {
  88. do_add_route(from, to, distance);
  89. do_add_route(to, from, distance);
  90. }
  91.  
  92. int parse_input(FILE* stream, struct city** cities, size_t maxcount)
  93. {
  94. size_t i = 0;
  95. while (i < maxcount && !feof(stream))
  96. {
  97. char from[16], to[16];
  98. unsigned distance;
  99. struct city* fromcity,
  100. * tocity;
  101. int parse_status = scanf("%15s to %15s = %u\n", from, to, &distance);
  102.  
  103. if (parse_status != 3)
  104. {
  105. char garbage[21];
  106.  
  107. if (ferror(stream))
  108. perror("can't read input");
  109. else
  110. {
  111. fgets(garbage, 20, stream);
  112. fprintf(stderr, "parse error near '%s'\n", garbage);
  113. }
  114.  
  115. return 0;
  116. }
  117.  
  118. fromcity = find_or_add_city(cities, from, maxcount);
  119. if (!fromcity)
  120. {
  121. fprintf(stderr, "could not add city '%s'\n", from);
  122. return 0;
  123. }
  124.  
  125. tocity = find_or_add_city(cities, to, maxcount);
  126. if (!tocity)
  127. {
  128. fprintf(stderr, "could not add city '%s'\n", to);
  129. return 0;
  130. }
  131.  
  132. add_route(fromcity, tocity, distance);
  133. }
  134.  
  135. return 1;
  136. }
  137.  
  138. unsigned distance_to(struct city* c, const char* name)
  139. {
  140. struct route* rte = c->routes;
  141.  
  142. while (rte)
  143. {
  144. if (strcmp(rte->to->name, name) == 0)
  145. return rte->distance;
  146.  
  147. rte = rte->next;
  148. }
  149.  
  150. return 0;
  151. }
  152.  
  153. unsigned measure_route(struct city** cities)
  154. {
  155. unsigned distance = 0;
  156. while (cities[1])
  157. {
  158. unsigned leg = distance_to(cities[0], cities[1]->name);
  159. if (!leg)
  160. /* hit a dead end */
  161. return 0;
  162.  
  163. distance += leg;
  164. ++cities;
  165. }
  166.  
  167. return distance;
  168. }
  169.  
  170. void print_route(struct city** cities)
  171. {
  172. while (*cities)
  173. {
  174. struct city* c = *cities;
  175. printf("%s ", c->name);
  176.  
  177. if (*++cities)
  178. fputs("-> ", stdout);
  179. }
  180. }
  181.  
  182. void swap_cities(struct city** left, struct city** right)
  183. {
  184. struct city* mid = *left;
  185. *left = *right;
  186. *right = mid;
  187. }
  188.  
  189. void try_route(struct city** cities, unsigned* shortest, unsigned* longest)
  190. {
  191. unsigned distance = measure_route(cities);
  192.  
  193. if (!distance)
  194. /* can't get here from there */
  195. return;
  196.  
  197. /*print_route(cities);
  198. printf("= %u", distance);*/
  199.  
  200. if (distance < *shortest)
  201. {
  202. *shortest = distance;
  203.  
  204. fputs("New shortest: ", stdout);
  205. print_route(cities);
  206. printf("= %u\n", distance);
  207. /*putchar('*');*/
  208. }
  209.  
  210. if (distance > *longest)
  211. {
  212. *longest = distance;
  213.  
  214. fputs("New longest: ", stdout);
  215. print_route(cities);
  216. printf("= %u\n", distance);
  217. }
  218.  
  219. /*putchar('\n');*/
  220. }
  221.  
  222. void try_routes(struct city** cities, size_t count, unsigned* shortest, unsigned* longest)
  223. {
  224. size_t i;
  225.  
  226. if (count == 1)
  227. try_route(cities, shortest, longest);
  228. else
  229. {
  230. for (i = 0; i < count - 1; ++i)
  231. {
  232. try_routes(cities, count - 1, shortest, longest);
  233.  
  234. if ((count & 1) == 0)
  235. swap_cities(cities + i, cities + (count - 1));
  236. else
  237. swap_cities(cities, cities + (count - 1));
  238. }
  239.  
  240. try_routes(cities, count - 1, shortest, longest);
  241. }
  242. }
  243.  
  244. int main(void)
  245. {
  246. struct city* cities[MAX_CITIES + 1] = {0};
  247. unsigned shortest = UINT_MAX, longest = 0;
  248. size_t count = 0;
  249.  
  250. if (!parse_input(stdin, cities, MAX_CITIES))
  251. return EXIT_FAILURE;
  252.  
  253. while (cities[count])
  254. ++count;
  255.  
  256. try_routes(cities, count, &shortest, &longest);
  257.  
  258. printf("The shortest distance is %u\n"
  259. "The longest distance is %u\n",
  260. shortest, longest);
  261.  
  262. return EXIT_SUCCESS;
  263. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement