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
140
141
142
143
144
145
146
147
148
149
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if 1
#define transfer transfer_part1
#else
#define transfer transfer_part2
#endif
#if 0
#define FILENAME "sample.txt"
#define COLUMNS 3
#else
#define FILENAME "input.txt"
#define COLUMNS 9
#endif
#define STRINT(d) atoi(strtok(NULL, d)); strtok(NULL, d);
typedef struct crate crate;
crate *create_crate(char data);
void push(crate *c, int i);
crate *add(crate *c, crate *last, int i); // pushes an element to bottom of a given stack
crate *pop(int i);
void transfer_part1(int from, int to, int n);
void transfer_part2(int from, int to, int n);
void free_crates(crate *c);
void print_crate(char *format, crate *c);
crate *top[COLUMNS+1] = {0}; // +1 for part 2
void parse()
{
FILE *fp = fopen(FILENAME, "r");
if(!fp) {
fprintf(stderr, "ERROR: Could not open file: %s\n", FILENAME);
exit(1);
}
char line[256] = {0};
crate *last[COLUMNS] = {0};
while(fgets(line, sizeof(line), fp) != NULL)
{
if(line[0] == '\n') break; // the table has ended
for(int i = 0; i < COLUMNS; i++) {
char ch = line[(i*4)+1];
if(ch >= 'A' && ch <= 'Z') {
last[i] = add(create_crate(ch), last[i], i);
}
}
}
while(fgets(line, sizeof(line), fp) != NULL)
{
// we need to call strtok multiple times
// to get the right token (integer)
strtok(line, " ");
int n = STRINT(" ");
int from = STRINT(" ");
int to = STRINT(" ");
transfer(from-1, to-1, n);
}
fclose(fp);
}
int main(void)
{
parse();
for(int i = 0; i < COLUMNS; i++) {
print_crate("%c", top[i]);
free_crates(top[i]);
}
puts("");
return 0;
}
struct crate {
char data;
struct crate *prev;
};
crate *create_crate(char data)
{
crate *c = malloc(sizeof(crate));
c->data = data;
c->prev = NULL;
return c;
}
void push(crate *c, int i)
{
c->prev = top[i];
top[i] = c;
}
crate *add(crate *c, crate *last, int i)
{
if(last == NULL) {
push(c, i);
return c;
}
last->prev = c;
return c;
}
crate *pop(int i)
{
if(top[i] == NULL) {
fprintf(stderr, "ERROR: Column %d is empty, can't pop\n", i);
exit(1);
}
crate *c = top[i];
top[i] = c->prev;
return c;
}
void transfer_part1(int from, int to, int n)
{
for(int i = 0; i < n; i++)
push(pop(from), to);
}
void transfer_part2(int from, int to, int n)
{
transfer_part1(from, COLUMNS, n);
transfer_part1(COLUMNS, to, n);
}
void free_crates(crate *c)
{
if(c == NULL) return;
crate *prev = c->prev;
free(c);
free_crates(prev);
}
void print_crate(char *format, crate *c)
{
if(c == NULL) return;
printf(format, c->data);
}
|