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
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct num {
int val;
int ord;
};
// Proper mathematical modulo, which returns a value in the range 0 <= n < m
// Even if n is negative.
// Warning, evaluates `m` multiple times (but `n` only once)
#define modulo(n, m) ((((n) % (m)) + (m)) % (m))
int
main()
{
char buf[BUFSIZ];
struct num * nums = NULL;
int nnums = 0, numsize = 0, i, pos;
// Read file.
while (fgets(buf, sizeof(buf), stdin)) {
char * end;
if (nnums == numsize) {
void * p;
numsize += BUFSIZ;
if ((p = realloc(nums, numsize * sizeof(struct num))) == NULL) {
fprintf(stderr, "Bad realloc(%zu)\n", numsize * sizeof(struct num));
free(nums);
return -1;
}
nums = p;
}
if ((nums[nnums].val = strtol(buf, &end, 10)) == 0
&& end == buf)
{
fprintf(stderr, "Invalid entry: %s\n", buf);
free(nums);
return -1;
}
nums[nnums].ord = nnums;
++nnums;
}
// Mix file.
for (i = 0, pos = 0; i < nnums; ++i) {
int newpos;
struct num tmp;
// Look for the num whose ordinal is i, starting from the
// position of the last num we looked at.
while (nums[pos].ord != i)
pos = modulo(pos + 1, nnums);
if (nums[pos].val == 0)
continue;
// Move this.
tmp = nums[pos];
newpos = modulo(pos + nums[pos].val, nnums - 1); // Buffer of nums does not include moving num
if (newpos > pos)
memmove(nums + pos, nums + pos + 1, (newpos - pos) * sizeof(struct num));
else
memmove(nums + newpos + 1, nums + newpos, (pos - newpos) * sizeof(struct num));
nums[newpos] = tmp;
}
// Find zero.
for (i = 0; i < nnums; ++i)
if (nums[i].val == 0)
break;
if (i == nnums) {
fprintf(stderr, "No zero found!\n");
free(nums);
return -1;
}
printf("Coords: %d,%d,%d; sum %d\n",
nums[modulo(i + 1000, nnums)].val,
nums[modulo(i + 2000, nnums)].val,
nums[modulo(i + 3000, nnums)].val,
nums[modulo(i + 1000, nnums)].val
+ nums[modulo(i + 2000, nnums)].val
+ nums[modulo(i + 3000, nnums)].val);
free(nums);
return 0;
}
|