-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday20-mix.chpl
97 lines (88 loc) · 2.86 KB
/
day20-mix.chpl
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
// day 20, mix
use IO;
iter readInput() {
var num : int;
var count : int;
while readf("%i", num) {
yield(count,num);
count += 1;
}
}
var input = readInput();
//writeln(input);
var curr = 0;
while curr<input.size {
//writeln();
//writeln("curr = ", curr);
var idx, pos, val : int;
// search through to find what we should be currently moving
for (i,(p,v)) in zip(input.domain,input) {
if p==curr {
idx = i; // FIXME: that these don't go out of loop is confusing
pos = p;
val = v;
break;
}
}
//writeln("idx = ", idx, ", pos = ", pos, ", val = ", val);
// find target location
var targetIdx = calcTargetIndex(val, idx);
//if val < 0 && idx<=abs(val) { // wrap around to left
// targetIdx = (idx + val + input.size-1) % input.size;
//} else if val>0 && (idx+val)>=input.size { // wrap around to right
// targetIdx = (idx + val + 1) % input.size;
//} else {
// targetIdx = (idx + val) % input.size;
//}
//writeln("after call: targetIdx = ", targetIdx);
// put the (pos,val) pair in target by swapping with everyone before then
if idx<targetIdx {
for i in idx..<targetIdx {
input[i] <=> input[i+1];
}
} else {
for i in targetIdx..<idx by -1 {
input[i] <=> input[i+1];
}
}
curr += 1;
//writeln(input);
}
//writeln(input);
// find the zero value
var zeroIdx : int;
while input[zeroIdx][1]!=0 {
zeroIdx +=1;
}
//writeln("zeroIdx = ", zeroIdx);
// These are only relevant for the testin20a.txt input
//writeln("calcTargetIndex(4,10)-1 should equal 0, ", calcTargetIndex(4,10)-1);
//writeln("calcTargetIndex(4,18)-1 should equal 1, ", calcTargetIndex(4,18)-1);
//writeln("calcTargetIndex(5,4) should equal 3, ", calcTargetIndex(5,4));
var first = input[calcTargetIndex(1000,zeroIdx)-1][1],
second = input[calcTargetIndex(2000,zeroIdx)-1][1],
third = input[calcTargetIndex(3000,zeroIdx)-1][1];
writeln("1000 past zero = ", first);
writeln("2000 past zero = ", second);
writeln("3000 past zero = ", third);
writeln("answer = ", first+second+third);
proc calcTargetIndex(val, idx : int) {
var targetIdx : int;
if val < 0 && idx<=abs(val) { // wrap around to left
//targetIdx = (idx + val + input.size -1*(1+val/input.size)) % input.size;
var toBegin = idx;
var mod = (abs(val)-toBegin) % input.size;
targetIdx = if mod>1 then input.size-mod-1 else 0;
//targetIdx = input.size-1 - ((abs(val) - toBegin)%input.size);
//writeln("wrap left: targetIdx = ", targetIdx);
} else if val>0 && (idx+val)>=input.size { // wrap around to right
//targetIdx = (idx + val + 1*(1+val/input.size)) % input.size;
var toEnd = input.size - idx;
var mod = (val-toEnd) % input.size;
targetIdx = if mod<input.size-1 then mod+1 else input.size-1;
//writeln("wrap right: targetIdx = ", targetIdx);
} else {
targetIdx = (idx + val) % input.size;
}
return targetIdx;
}