-
Notifications
You must be signed in to change notification settings - Fork 0
/
05.c
139 lines (110 loc) · 3.56 KB
/
05.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include <stdio.h>
#include <string.h>
#define CHARS_PER_STACK 3
#define MAX_STACKS 15
#define MAX_LINE_SIZE MAX_STACKS * (CHARS_PER_STACK + 1)
#define MAX_STACK_HEIGHT 500
struct stack
{
size_t count;
char boxes[MAX_STACK_HEIGHT];
};
typedef struct stack stack;
void print_all_stacks(stack *stacks) {
size_t max_height = 0;
for (size_t i = 0; i < MAX_STACKS; i++)
if (stacks[i].count > max_height)
max_height = stacks[i].count;
for (size_t i = max_height - 1; ; i--) {
for (size_t j = 0; j < MAX_STACKS; j++)
printf("%c ", stacks[j].boxes[i] ? stacks[j].boxes[i] : ' ');
printf("\n");
if (i == 0)
break;
}
}
void print_top_boxes(stack *stacks) {
for (size_t i = 0; i < MAX_STACKS; i++)
if (stacks[i].boxes[stacks[i].count - 1])
printf("%c", stacks[i].boxes[stacks[i].count - 1]);
printf("\n");
}
int main(int argc, char **argv) {
char line[MAX_LINE_SIZE];
unsigned count;
size_t from, to;
int box_direction;
stack stacks[MAX_STACKS];
if (argc != 2) {
fprintf(
stderr,
"%s: expected exactly one argument (crate mover model, cm9000 or cm9001)\n",
argv[0]
);
return 1;
} else if (strcmp(argv[1], "cm9000") == 0)
box_direction = -1;
else if (strcmp(argv[1], "cm9001") == 0)
box_direction = 1;
else {
fprintf(stderr, "%s: expected cm9000 or cm9001\n", argv[0]);
return 1;
}
memset(stacks, 0, sizeof stacks);
// Read the initial stack configuration
while (fgets(line, sizeof line, stdin) != NULL) {
if (strcmp(line, "\n") == 0)
break;
size_t string_length = strcspn(line, "\n");
for (size_t i = 0; i < MAX_STACKS; i++) {
size_t stack_index = i * (CHARS_PER_STACK + 1);
if (stack_index > string_length)
break;
char stack_symbol = line[stack_index + 1];
if (stack_symbol < 'A' || stack_symbol > 'Z')
continue;
stacks[i].boxes[stacks[i].count] = stack_symbol;
stacks[i].count++;
}
}
// Reverse boxes in the stack
for (size_t i = 0; i < MAX_STACKS; i++) {
for (size_t j = 0; j < stacks[i].count / 2; j++) {
char temp = stacks[i].boxes[j];
stacks[i].boxes[j] = stacks[i].boxes[stacks[i].count - j - 1];
stacks[i].boxes[stacks[i].count - j - 1] = temp;
}
}
printf("Before moving boxes:\n");
print_all_stacks(&stacks[0]);
printf("\n");
// Process crate moving instructions
while (fgets(line, sizeof line, stdin) != NULL) {
sscanf(line, "move %u from %zu to %zu", &count, &from, &to);
// They are 1-based in the input file
from--;
to--;
size_t i, stop;
if (box_direction < 0) {
i = stacks[from].count - 1;
stop = stacks[from].count - count;
} else {
i = stacks[from].count - count;
stop = stacks[from].count;
}
while (box_direction < 0 && i >= stop || box_direction > 0 && i < stop) {
stacks[to].boxes[stacks[to].count] = stacks[from].boxes[i];
stacks[to].count++;
stacks[from].boxes[i] = 0;
stacks[from].count--;
if (i == stop)
break;
i += box_direction;
}
}
printf("After moving boxes:\n");
print_all_stacks(&stacks[0]);
printf("\nTop boxes say ");
print_top_boxes(&stacks[0]);
return 0;
}