zip.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <malloc_np.h>
  4. #include <string.h>
  5. typedef struct {
  6. size_t len;
  7. char *items[10];
  8. } truc_array;
  9. enum dirs {
  10. R, /* right */
  11. L, /* left */
  12. U, /* up */
  13. D /* down */
  14. };
  15. static __attribute((malloc)) __attribute__((nonnull)) char *get_it(truc_array const *src)
  16. {
  17. char *r = mallocx(src->len, MALLOCX_ZERO);
  18. size_t n = 0;
  19. enum dirs dir = R;
  20. int x = 0, y = 0;
  21. while (src->len && (n < src->len)) {
  22. char c;
  23. while((c = src->items[y][x]) != ' ') {
  24. /* store */
  25. if (c != '*')
  26. r[n++] = c;
  27. if (n == src->len)
  28. break;
  29. /* test next one */
  30. int tx = x;
  31. int ty = y;
  32. switch (dir) {
  33. case R:
  34. tx++;
  35. break;
  36. case L:
  37. tx--;
  38. break;
  39. case U:
  40. ty--;
  41. break;
  42. case D:
  43. ty++;
  44. break;
  45. default:
  46. fprintf(stderr, "Bug!\n");
  47. break;
  48. }
  49. /* ouch */
  50. if (tx > 14 || tx < 0 || ty <0 || ty > 9)
  51. break;
  52. if ((c = src->items[ty][tx]) == ' ')
  53. break;
  54. /* valid next */
  55. x = tx;
  56. y = ty;
  57. }
  58. switch (dir) {
  59. char c_up, c_down, c_left, c_right;
  60. case R:
  61. case L:
  62. /* cover up and down */
  63. c_up = ' ';
  64. c_down = ' ';
  65. if (y > 1)
  66. c_up = src->items[y - 1][x];
  67. if (y < 9)
  68. c_down = src->items[y + 1][x];
  69. if (c_up != ' ') {
  70. y = y - 1;
  71. dir = U;
  72. }
  73. else if (c_down != ' ') {
  74. y = y + 1;
  75. dir = D;
  76. }
  77. else
  78. return r;
  79. break;
  80. case U:
  81. case D:
  82. /* cover left and right */
  83. c_left = ' ';
  84. c_right = ' ';
  85. if (x > 1)
  86. c_left = src->items[y][x - 1];
  87. if (y < 14)
  88. c_right = src->items[y][x + 1];
  89. if (c_left != ' ') {
  90. x = x - 1;
  91. dir = L;
  92. }
  93. else if (c_right != ' ') {
  94. x = x + 1;
  95. dir = R;
  96. } else
  97. return r;
  98. break;
  99. }
  100. }
  101. return r;
  102. }
  103. static void print_it(truc_array src)
  104. {
  105. printf("+---------------+\n");
  106. for (size_t j= 0; j < 10;) {
  107. printf("|%s|\n", src.items[j++]);
  108. }
  109. printf("+---------------+\n");
  110. }
  111. int main(int argc, char *argv[])
  112. {
  113. truc_array a= {128, };
  114. char *r = NULL;
  115. /* 012345789ABCDEF */
  116. a.items[0] = "*01** ";
  117. a.items[1] = "edcBA ";
  118. a.items[2] = "* * X ";
  119. a.items[3] = "* ! * ";
  120. a.items[4] = "****F** ";
  121. a.items[5] = " * *H* ";
  122. a.items[6] = " *G** * ";
  123. a.items[7] = " X I ";
  124. a.items[8] = " X **J**** ";
  125. a.items[9] = "X Z ";
  126. print_it(a);
  127. puts("");
  128. r = get_it(&a);
  129. printf("[ %s ]\n", r);
  130. dallocx(r, 0);
  131. }