-
Notifications
You must be signed in to change notification settings - Fork 0
/
day_03.cpp
138 lines (125 loc) · 2.9 KB
/
day_03.cpp
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
// day3.cpp : Defines the entry point for the console application.
// Advent of Code 2017
// http://adventofcode.com/
#include <iostream>
#include <string>
#include <limits>
#include <vector>
#include <map>
// track spiral totals in part 2
std::map<std::string,int> sum;
// x,y -> "x,y"
std::string idx(int x,int y)
{
std::string idx = std::to_string((long long)x);
idx.push_back(',');
idx.append(std::to_string((long long)y));
return idx;
}
// lookup a sum at cell x,y
int lookup(int x, int y)
{
std::string id = idx(x,y);
if (sum.find(id)!=sum.end())
return sum[id];
return 0;
}
// sum the 8 neighbors of x,y and save it
int save_sum(int x,int y)
{
int tot = 0;
tot += lookup(x-1,y-1);
tot += lookup(x,y-1);
tot += lookup(x+1,y-1);
tot += lookup(x-1,y+1);
tot += lookup(x,y+1);
tot += lookup(x+1,y+1);
tot += lookup(x-1,y);
tot += lookup(x+1,y);
sum[idx(x,y)] = tot;
std::cout << tot << std::endl;
return tot;
}
// given a value, do spiral enwwsseeennn... etc. summing the 8 neighbors as we go
// find the first value higher than the problem input
int main2(int argc, char* argv[])
{
sum[idx(0,0)] = 1;
std::cout << "Enter a value for part 2" << std::endl;
int val;
std::cin >> val;
int x=0, y=0;
int count = 0;
while(1) {
// move east
count++;
for (int i=0;i<count;i++) {
x++;
if (val<save_sum(x,y))
goto done;
}
// move north
for (int i=0;i<count;i++) {
y++;
if (val<save_sum(x,y))
goto done;
}
// move west
count++;
for (int i=0;i<count;i++) {
x--;
if (val<save_sum(x,y))
goto done;
}
// move south
for (int i=0;i<count;i++) {
y--;
if (val<save_sum(x,y))
goto done;
}
}
done:
std::cin >> val;
return 0;
}
// part 1 given a spiral starting at 1, calculate the manhattan distance back
// to the center from the problem input.
// I used the following for some clues http://mathforum.org/library/drmath/view/62201.html
// then hack hack hack...
int main1(int argc, char* argv[])
{
int val;
std::cout << "Enter a value (or -1 to quit part 1)" << std::endl;
while (1) {
std::cin >> val;
if (val==-1)
break;
int side = 1;
int count = 1;
int inner = 0;
int pos = 0;
int of = 0;
int dist = 0;
int rings = 1;
do { // iterate til we get a big enough ring
side += 2;
count = side*side;
rings++;
} while (count<val);
inner = side>1 ? (side-2)*(side-2) : 0; // count of cells inside the ring
pos = ((val-inner)+side/2)%(side-1); // distance away from the 12pm 3pm 6pm 9pm positions
of = (side-1)*(side-1); // unused - cells in this ring
dist = pos + rings-1; // total manhattan distance
std::cout << "Rings " << rings << std::endl;
std::cout << "Side " << side << std::endl;
std::cout << "Pos " << pos << std::endl;
std::cout << "Of " << of << std::endl;
std::cout << "Dist " << dist << std::endl;
};
return 0;
}
int main(int argc, char* argv[])
{
main1(argc,argv);
main2(argc,argv);
}