-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtime.cc
109 lines (98 loc) · 2.78 KB
/
time.cc
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
#include "time.h"
#include <random>
void min_split(Time const & t1, Time const & t2, Time * s1, Time * s2)
{
t1.split(t2.minVal(), s1, s2);
s1->scale(t2.sum());
}
Time min(Time const & t1, Time const & t2)
{
if (t1.minVal() > t2.minVal())
return min(t2, t1);
Time res;
Time t11, t12, t21, t22;
t12 = t1;
t22 = t2;
while (!t12.isEmpty() && !t22.isEmpty()) {
if (t12.minVal() < t22.minVal()) {
min_split(t12, t22, &t11, &t12);
res += t11;
} else {
min_split(t22, t12, &t21, &t22);
res += t21;
}
}
return res;
}
int Time::choose() const
{
static std::uniform_real_distribution<dbl::Data /*double*/> unif(0,1);
static std::random_device rd;
static std::mt19937 re(rd());
double r = unif(re) * _sum;
for (auto it = values.begin(); it != values.end(); ++it) {
r -= it->second;
if (r <= 0) return it->first;
}
// If we got here our sum isn't quite exact. That's ok.
return values.rbegin()->first;
}
Time operator | (int val, const Time& t)
{
Time res;
double s = 0;
auto i1 = t.values.begin();
for (; i1 != t.values.end(); ++i1) {
if (i1->first <= val) {
//s += i1->second;
} else {
break;
}
}
res.values.reserve(t.values.end() - i1);
res.values.insert(res.values.begin(), i1, t.values.end());
for (; i1 != t.values.end(); ++i1) {
s += i1->second;
}
res._sum = s;
return res;
}
Time operator - (int val, Time const & t)
{
return Time(val) - t;
}
std::ostream& operator << (std::ostream & os, Time const & time)
{
if (!time.isEmpty()) {
os << time.minVal() << "-" << time.maxVal() << " (" << time.sum()
<< ")";
} else {
os << "---";
}
os << "[";
for (auto it = time.values.begin(); it != time.values.end(); ++it) {
os << it->first << ":" << it->second << ", ";
}
os << "]";
return os;
}
std::istream& operator >> (std::istream & is, Time & time)
{
std::map<int, double> vals;
int v;
double vd;
double p;
char c;
is >> vd >> c >> p;
v = static_cast<int>(vd);
assert(v == vd);
vals[v] = p;
assert(c == ':');
while (is.peek() == ',') {
is >> c;
is >> v >> c >> p;
vals[v] = p;
}
time = Time(vals);
return is;
}