Advertisement
Guest User

Untitled

a guest
Mar 24th, 2017
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.17 KB | None | 0 0
  1. // q1a readints.c
  2. int *read_ints(int *len) {
  3. int *read = NULL, capacity = *len = 0, tmp;
  4.  
  5. while (scanf("%d", &tmp) == 1) {
  6. if (*len == capacity) {
  7. capacity += !capacity ? 1 : capacity;
  8. read = realloc(read, capacity * sizeof(int));
  9. }
  10.  
  11. read[(*len)++] = tmp;
  12. }
  13.  
  14. return !*len ? NULL : realloc(read, *len * sizeof(int)); // compress
  15. }
  16.  
  17. // q1b linesplit.c
  18. char **split_lines(const char *s, int *len) {
  19. assert(len);
  20. const int n = strlen(s); // O(n)
  21.  
  22. int breaks[n]; // at most there will be n lines, *len counts how many
  23. for (int i = *len = 0; i <= n; i++) // O(n) again,
  24. if (s[i] == '\n' || !s[i])
  25. breaks[(*len)++] = i;
  26.  
  27. if (!*len) // *len <= n
  28. return NULL;
  29.  
  30. char **lines = malloc(*len * sizeof(char *));
  31.  
  32. strncpy(lines[0] = malloc(sizeof(char) * (breaks[0] + 1)), s, breaks[0]);
  33. s += breaks[0] + 1;
  34.  
  35. for (int i = 1; i < *len; i++) { // O(n), *len is bounded by n
  36. lines[i] = malloc(sizeof(char) * (breaks[i] - breaks[i - 1]));
  37. strncpy(lines[i], s, breaks[i] - (breaks[i - 1] + 1));
  38. // printf("lines[%d]%s(%d)\n", i, lines[i], strlen(lines[i]));
  39. s += (breaks[i] - (breaks[i - 1]));
  40. }
  41.  
  42. return lines;
  43. }
  44.  
  45. // q2 sequence.c
  46. struct sequence {
  47. int *elements, n, capacity;
  48. };
  49.  
  50. struct sequence *sequence_create(void) {
  51. struct sequence *s = malloc(sizeof(struct sequence));
  52. s->elements = NULL, s->n = s->capacity = 0;
  53. return s;
  54. }
  55.  
  56. void sequence_destroy(struct sequence *seq) {
  57. assert(seq);
  58. free(seq->elements);
  59. seq->n = seq->capacity = 0;
  60. free(seq);
  61. }
  62.  
  63. int sequence_length(const struct sequence *seq) {
  64. assert(seq);
  65. return seq->n;
  66. }
  67.  
  68. int sequence_item_at(const struct sequence *seq, int pos) {
  69. assert(0 <= pos && pos < sequence_length(seq));
  70. return seq->elements[pos];
  71. }
  72.  
  73. void sequence_insert_at(struct sequence *seq, int pos, int val) {
  74. assert(0 <= pos && pos <= sequence_length(seq));
  75. printf("inserting at %d]=%d\n", pos, val);
  76. printf("n=%d, cap=%d\n", sequence_length(seq), seq->capacity);
  77.  
  78. if (sequence_length(seq) >= seq->capacity) {
  79. seq->capacity += !seq->capacity ? 1 : seq->capacity; // make room
  80. seq->elements = realloc(seq->elements, seq->capacity * sizeof(int));
  81. }
  82.  
  83. for (int j = seq->n++; j > 0 && j > pos; j--)
  84. seq->elements[j] = seq->elements[j - 1];
  85. seq->elements[pos] = val;
  86. }
  87.  
  88. int sequence_remove_at(struct sequence *seq, int pos) {
  89. assert(0 <= pos && pos < sequence_length(seq));
  90.  
  91. const int n = sequence_length(seq), extracted = seq->elements[pos];
  92.  
  93. for (int i = pos; i < n - 1; i++)
  94. seq->elements[i] = seq->elements[i + 1];
  95. seq->n--;
  96. return extracted;
  97. }
  98.  
  99. void sequence_print(const struct sequence *seq) {
  100. const int n = sequence_length(seq);
  101. if (printf("[") && !n && printf("empty]\n"))
  102. return;
  103.  
  104. for (int i = 0; i < n; i++)
  105. printf("%d%s", seq->elements[i], i < n - 1 ? "," : "]\n");
  106. }
  107.  
  108. // q3 set.c
  109. struct set {
  110. int *elements, n, capacity;
  111. };
  112.  
  113. struct set *set_create(void) {
  114. struct set *s = malloc(sizeof(struct set));
  115. s->elements = NULL, s->n = s->capacity = 0;
  116. return s;
  117. }
  118.  
  119. void set_destroy(struct set *s) {
  120. assert(s);
  121. free(s->elements);
  122. s->elements = NULL, s->n = s->capacity = 0;
  123. free(s);
  124. }
  125.  
  126. int set_size(const struct set *s) {
  127. assert(s);
  128. return s->n;
  129. }
  130.  
  131. // O(log n)
  132. static bool binsearch(const int arr[], const int n, const int key, int *at) {
  133. int start = 0, middle, end = n - 1;
  134.  
  135. while (start <= end)
  136. if (arr[middle = start + (end - start) / 2] == key)
  137. return (*at = middle, true);
  138. else if (key > arr[middle])
  139. start = middle + 1;
  140. else if (key < arr[middle])
  141. end = middle - 1;
  142.  
  143. return false;
  144. }
  145.  
  146. bool set_member(const struct set *s, int i) {
  147. assert(s);
  148. int location;
  149. return binsearch(s->elements, set_size(s), i, &location); // O(log n)
  150. }
  151.  
  152. void set_add(struct set *s, int i) {
  153. assert(s);
  154. int location;
  155. if (!binsearch(s->elements, set_size(s), i, &location)) {
  156. if (set_size(s) >= s->capacity) {
  157. s->capacity += !s->capacity ? 1 : s->capacity; // orig/double space
  158. s->elements = realloc(s->elements, s->capacity * sizeof(int));
  159. }
  160.  
  161. for (int j = s->n++; j > 0 && j > location; j--)
  162. s->elements[j] = s->elements[j - 1];
  163. s->elements[location] = i;
  164. }
  165. }
  166.  
  167. void set_remove(struct set *s, int i) {
  168. const int n = set_size(s);
  169. int location;
  170. if (binsearch(s->elements, n, i, &location)) {
  171. for (int j = location; j < n - 1; j++)
  172. s->elements[j] = s->elements[j + 1];
  173. s->n--;
  174. }
  175. }
  176.  
  177. struct set *set_union(const struct set *s1, const struct set *s2) {
  178. const int len1 = set_size(s1), len2 = set_size(s2), total = len1 + len2;
  179. int arr[total], i = 0, j = 0, k = 0, prev; // k is a counter <= total
  180.  
  181. while (i < len1 && j < len2) // merge, like in mergesort
  182. if (s1->elements[i] < s2->elements[j]) {
  183. if (s1->elements[i] != prev)
  184. arr[k++] = prev = s1->elements[i];
  185. i++;
  186. } else {
  187. if (s2->elements[j] != prev)
  188. arr[k++] = prev = s2->elements[j];
  189. j++;
  190. }
  191.  
  192. while (i < len1) {
  193. if (s1->elements[i] != prev)
  194. arr[k++] = s1->elements[i];
  195. i++;
  196. }
  197. while (j < len2) {
  198. if (s2->elements[j] != prev)
  199. arr[k++] = s2->elements[j];
  200. j++;
  201. }
  202.  
  203. struct set *u = set_create();
  204. u->elements = !k ? NULL : malloc(k * sizeof(int)), u->n = u->capacity = k;
  205. for (int i = 0; i < k; i++)
  206. u->elements[i] = arr[i]; // k <= total
  207. return u;
  208. }
  209.  
  210. struct set *set_intersect(const struct set *s1, const struct set *s2) {
  211. const int len1 = set_size(s1), len2 = set_size(s2), total = len1 + len2;
  212. int arr[total], i = 0, j = 0, k = 0;
  213.  
  214. while (i < len1 && j < len2) // merge, like in mergesort
  215. if (s1->elements[i] < s2->elements[j])
  216. i++;
  217. else if (s1->elements[i] > s2->elements[j])
  218. j++;
  219. else
  220. arr[k++] = s1->elements[i], i++, j++;
  221.  
  222. struct set *s = set_create();
  223. s->elements = !k ? NULL : malloc(k * sizeof(int)), s->n = s->capacity = k;
  224. for (int i = 0; i < k; i++)
  225. s->elements[i] = arr[i];
  226. return s;
  227. }
  228.  
  229. struct set *array_to_set(const int a[], int len) {
  230. assert(len);
  231.  
  232. int tmp[len], count = 0; // tmp holds sorted version of a[], O(n)
  233. for (int i = 0; i < len; i++)
  234. tmp[i] = a[i];
  235. merge_sort(tmp, len);
  236.  
  237. struct set *s = set_create();
  238. s->elements = !len ? NULL : malloc(sizeof(int) * len);
  239. if (!len)
  240. return s;
  241.  
  242. s->elements[count++] = tmp[0];
  243. for (int i = 1, prev = tmp[0]; i < len; i++)
  244. if (tmp[i] != prev) // count is len elements at most
  245. s->elements[count++] = prev = tmp[i];
  246.  
  247. s->elements = realloc(s->elements, sizeof(int) * count); // compress
  248. s->n = s->capacity = count;
  249. return s;
  250. }
  251.  
  252. int *set_to_array(const struct set *s) {
  253. const int n = set_size(s);
  254. int *arr = !n ? NULL : malloc(sizeof(int) * n);
  255.  
  256. for (int i = 0; i < n; i++)
  257. arr[i] = s->elements[i];
  258.  
  259. return arr;
  260. }
  261.  
  262. void set_print(const struct set *s) {
  263. const int n = set_size(s);
  264.  
  265. if (printf("[") && !n && printf("empty]\n"))
  266. return;
  267.  
  268. for (int i = 0; i < n; i++)
  269. printf("%d%s", s->elements[i], i < n - 1 ? "," : "]\n");
  270. }
  271.  
  272. // q4 inventory.c
  273. struct inventory {
  274. char **names;
  275. int *amount, n, capacity;
  276. };
  277.  
  278. struct inventory *inventory_create(void) {
  279. struct inventory *inv = malloc(sizeof(struct inventory));
  280. inv->names = NULL, inv->amount = NULL, inv->n = inv->capacity = 0;
  281. return inv;
  282. }
  283.  
  284. void inventory_destroy(struct inventory *inv) {
  285. assert(inv);
  286.  
  287. for (int i = 0; i < inv->n; i++) {
  288. assert(inv->names[i]);
  289. free(inv->names[i]);
  290. inv->names[i] = NULL;
  291. }
  292. free(inv->names);
  293.  
  294. free(inv->amount);
  295. inv->names = NULL, inv->amount = NULL, inv->n = inv->capacity = 0;
  296. free(inv);
  297. }
  298.  
  299. // O(log n)
  300. static bool binsearch(const char *arr[], const int n, const char *s, int *at) {
  301. int start = 0, middle, end = n - 1;
  302.  
  303. while (start <= end)
  304. if (!strcmp(arr[middle = start + (end - start) / 2], s))
  305. return (*at = middle, true);
  306. else if (strcmp(arr[middle], s) < 0)
  307. start = middle + 1;
  308. else // strcmp(arr[middle], s) > 0)
  309. end = middle - 1;
  310.  
  311. return (*at = start), false;
  312. }
  313.  
  314. int inventory_lookup(const struct inventory *inv, const char *item) {
  315. assert(inv && item);
  316.  
  317. int location;
  318. return binsearch(inv->names, inv->n, item, &location) ?
  319. inv->amount[location] :
  320. -1;
  321. }
  322.  
  323. void inventory_add(struct inventory *inv, const char *item, int qty) {
  324. assert(inv && item && qty >= 0);
  325.  
  326. int location;
  327. if (binsearch(inv->names, inv->n, item, &location))
  328. inv->amount[location] += qty;
  329. else {
  330. if (inv->n == inv->capacity) { // amortized: conditional capacity incr
  331. inv->capacity += !inv->capacity ? 1 : inv->capacity;
  332. inv->names = realloc(inv->names, inv->capacity * sizeof(char *));
  333. inv->amount = realloc(inv->amount, inv->capacity * sizeof(int));
  334. }
  335.  
  336. for (int i = inv->n++; i > 0 && i > location; i--) {
  337. inv->names[i] = inv->names[i - 1]; // copy char pointers
  338. inv->amount[i] = inv->amount[i - 1]; // and amounts
  339. }
  340. inv->names[location] = malloc((strlen(item) + 1) * sizeof(char));
  341. strcpy(inv->names[location], item), inv->amount[location] = qty;
  342. }
  343. }
  344.  
  345. void inventory_remove(struct inventory *inv, const char *item, int qty) {
  346. assert(inv && item && qty > 0);
  347.  
  348. int location, availability = -1;
  349. if (binsearch(inv->names, inv->n, item, &location))
  350. availability = inv->amount[location];
  351.  
  352. assert(qty <= availability);
  353. inv->amount[location] -= qty;
  354. }
  355.  
  356. // q5 llfun.c
  357. void print_llist(const struct llist *lst) {
  358. const int n = length(lst);
  359. if (printf("[") && !n && printf("empty]\n"))
  360. return;
  361.  
  362. struct llnode *curr = lst->front;
  363. while (curr)
  364. printf("%d%s", curr->item, curr->next ? "->" : "]\n"),
  365. curr = curr->next;
  366. }
  367.  
  368. struct llist *array_to_llist(const int a[], int len) {
  369. struct llist *l = list_create();
  370. for (int i = len - 1; i >= 0; i--)
  371. add_front(a[i], l);
  372. return l;
  373. }
  374.  
  375. int *llist_to_array(const struct llist *lst) {
  376. const int n = length(lst); // O(#nodes)
  377. int *arr = !n ? NULL : malloc(sizeof(int) * n), i;
  378. struct llnode *curr = lst->front;
  379.  
  380. while (curr) // O(#nodes) again
  381. arr[i++] = curr->item, curr = curr->next;
  382. return arr;
  383. }
  384.  
  385. void map(int (*f)(int), struct llist *lst) {
  386. assert(lst);
  387.  
  388. struct llnode *curr = lst->front;
  389. while (curr)
  390. curr->item = f(curr->item), curr = curr->next;
  391. }
  392.  
  393. // iterative version
  394. // void filter(bool (*f)(int), struct llist *lst) { // iterative version
  395. // assert(lst);
  396.  
  397. // struct llnode *curr = lst->front, *prev = NULL, *next;
  398. // while (curr) {
  399. // if (!f(curr->item)) {
  400. // if (!prev)
  401. // lst->front = curr->next;
  402. // else
  403. // prev->next = curr->next;
  404.  
  405. // next = curr->next;
  406. // free(curr);
  407. // } else {
  408. // prev = curr;
  409. // next = curr->next;
  410. // }
  411.  
  412. // curr = next;
  413. // }
  414. // }
  415.  
  416. void filter(bool (*f)(int), struct llist *lst) { // recursive version
  417. assert(lst);
  418.  
  419. static struct llnode *head, *prev = NULL, *next;
  420. static bool beginning = true;
  421.  
  422. // initialization
  423. if (beginning) // needed because static initializations need to be constant
  424. beginning = false, head = lst->front; // front mostly stays constant
  425.  
  426. struct llnode *curr = lst->front;
  427.  
  428. if (!curr) // base case, fall through return to end recursion
  429. lst->front = head, prev = NULL, beginning = true;
  430.  
  431. else {
  432. if (!f(curr->item)) {
  433. if (!prev)
  434. head = curr->next;
  435. else
  436. prev->next = curr->next;
  437.  
  438. next = curr->next;
  439. free(curr);
  440. } else {
  441. prev = curr;
  442. next = curr->next;
  443. }
  444.  
  445. lst->front = next;
  446. filter(f, lst);
  447. }
  448. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement