1 /* Copyright (C) 2013-2014 Michal Brzozowski (rusolis@poczta.fm)
2 
3    This file is part of KeeperRL.
4 
5    KeeperRL is free software; you can redistribute it and/or modify it under the terms of the
6    GNU General Public License as published by the Free Software Foundation; either version 2
7    of the License, or (at your option) any later version.
8 
9    KeeperRL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
10    even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11    GNU General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License along with this program.
14    If not, see http://www.gnu.org/licenses/ . */
15 
16 #include "stdafx.h"
17 
18 #include "util.h"
19 #include "position.h"
20 
init(int seed)21 void RandomGen::init(int seed) {
22   generator.seed(seed);
23 }
24 
get(int max)25 int RandomGen::get(int max) {
26   return get(0, max);
27 }
28 
getLL()29 long long RandomGen::getLL() {
30   return uniform_int_distribution<long long>(-(1LL << 62), 1LL << 62)(generator);
31 }
32 
get(Range r)33 int RandomGen::get(Range r) {
34   return get(r.getStart(), r.getEnd());
35 }
36 
get(int min,int max)37 int RandomGen::get(int min, int max) {
38   CHECK(max > min);
39   return uniform_int_distribution<int>(min, max - 1)(generator);
40 }
41 
operator ""_s(const char * str,size_t)42 std::string operator "" _s(const char* str, size_t) {
43   return std::string(str);
44 }
45 
getCardinalName(Dir d)46 string getCardinalName(Dir d) {
47   switch (d) {
48     case Dir::N: return "north";
49     case Dir::S: return "south";
50     case Dir::E: return "east";
51     case Dir::W: return "west";
52     case Dir::NE: return "north-east";
53     case Dir::NW: return "north-west";
54     case Dir::SE: return "south-east";
55     case Dir::SW: return "south-west";
56   }
57 }
58 
get(const vector<double> & weights)59 int RandomGen::get(const vector<double>& weights) {
60   double sum = 0;
61   for (double elem : weights)
62     sum += elem;
63   CHECK(sum > 0);
64   double r = getDouble(0, sum);
65   sum = 0;
66   for (int i : All(weights)) {
67     sum += weights[i];
68     if (sum >= r)
69       return i;
70   }
71   return weights.size() - 1;
72 }
73 
roll(int chance)74 bool RandomGen::roll(int chance) {
75   return get(chance) == 0;
76 }
77 
chance(double v)78 bool RandomGen::chance(double v) {
79   return getDouble(0, 1) <= v;
80 }
81 
getDouble()82 double RandomGen::getDouble() {
83   return defaultDist(generator);
84 }
85 
getDouble(double a,double b)86 double RandomGen::getDouble(double a, double b) {
87   return uniform_real_distribution<double>(a, b)(generator);
88 }
89 
90 RandomGen Random;
91 
92 template string toString<int>(const int&);
93 template string toString<unsigned int>(const unsigned int&);
94 //template string toString<size_t>(const size_t&);
95 template string toString<char>(const char&);
96 template string toString<double>(const double&);
97 //template string toString<Vec2>(const Vec2&);
98 
99 template int fromString<int>(const string&);
100 template double fromString<double>(const string&);
101 
102 template optional<int> fromStringSafe<int>(const string&);
103 template optional<double> fromStringSafe<double>(const string&);
104 
105 
106 template <class T>
fromStringSafe(const string & s)107 optional<T> fromStringSafe(const string& s){
108   std::stringstream ss(s);
109   T t;
110   ss >> t;
111   if (!ss)
112     return none;
113   return t;
114 }
115 
trim(string & s)116 void trim(string& s) {
117   while (!s.empty() && isspace(s[0]))
118     s.erase(s.begin());
119   while (!s.empty() && isspace(*s.rbegin()))
120     s.erase(s.size() - 1);
121 }
122 
toUpper(const string & s)123 string toUpper(const string& s) {
124   string ret(s);
125   transform(ret.begin(), ret.end(), ret.begin(), ::toupper);
126   return ret;
127 }
128 
toLower(const string & s)129 string toLower(const string& s) {
130   string ret(s);
131   transform(ret.begin(), ret.end(), ret.begin(), ::tolower);
132   return ret;
133 }
134 
endsWith(const string & s,const string & suffix)135 bool endsWith(const string& s, const string& suffix) {
136   return s.size() >= suffix.size() && s.substr(s.size() - suffix.size()) == suffix;
137 }
138 
split(const string & s,const set<char> & delim)139 vector<string> split(const string& s, const set<char>& delim) {
140   if (s.empty())
141     return {};
142   int begin = 0;
143   vector<string> ret;
144   for (int i : Range(s.size() + 1))
145     if (i == s.size() || delim.count(s[i])) {
146       string tmp = s.substr(begin, i - begin);
147       ret.push_back(tmp);
148       begin = i + 1;
149     }
150   return ret;
151 }
152 
contains(const string & s,const string & p)153 bool contains(const string& s, const string& p) {
154   return s.find(p) != string::npos;
155 }
156 
toString(const Vec2 & v)157 string toString(const Vec2& v) {
158   stringstream ss;
159   ss << "(" << v.x << ", " << v.y << ")";
160   return ss.str();
161 }
162 
Vec2(int _x,int _y)163 Vec2::Vec2(int _x, int _y) : x(_x), y(_y) {
164 }
165 
Vec2(Dir dir)166 Vec2::Vec2(Dir dir) {
167   switch (dir) {
168     case Dir::N: x = 0; y = -1; break;
169     case Dir::S: x = 0; y = 1; break;
170     case Dir::E: x = 1; y = 0; break;
171     case Dir::W: x = -1; y = 0; break;
172     case Dir::NE: x = 1; y = -1; break;
173     case Dir::SE: x = 1; y = 1; break;
174     case Dir::NW: x = -1; y = -1; break;
175     case Dir::SW: x = -1; y = 1; break;
176   }
177 }
178 
mult(const Vec2 & v) const179 Vec2 Vec2::mult(const Vec2& v) const {
180   return Vec2(x * v.x, y * v.y);
181 }
182 
div(const Vec2 & v) const183 Vec2 Vec2::div(const Vec2& v) const {
184   return Vec2(x / v.x, y / v.y);
185 }
186 
dotProduct(Vec2 a,Vec2 b)187 int Vec2::dotProduct(Vec2 a, Vec2 b) {
188   return a.x * b.x + a.y * b.y;
189 }
190 
191 static const vector<Vec2> dir8 {
192   Vec2(0, -1), Vec2(0, 1), Vec2(1, 0), Vec2(-1, 0), Vec2(1, -1), Vec2(-1, -1), Vec2(1, 1), Vec2(-1, 1)
193 };
194 
directions8()195 const vector<Vec2>& Vec2::directions8() {
196   return dir8;
197 }
198 
neighbors8() const199 vector<Vec2> Vec2::neighbors8() const {
200   return {Vec2(x, y + 1), Vec2(x + 1, y), Vec2(x, y - 1), Vec2(x - 1, y), Vec2(x + 1, y + 1), Vec2(x + 1, y - 1),
201       Vec2(x - 1, y - 1), Vec2(x - 1, y + 1)};
202 }
203 
204 static const vector<Vec2> dir4 {
205   Vec2(0, -1), Vec2(0, 1), Vec2(1, 0), Vec2(-1, 0)
206 };
207 
directions4()208 const vector<Vec2>& Vec2::directions4() {
209   return dir4;
210 }
211 
neighbors4() const212 vector<Vec2> Vec2::neighbors4() const {
213   return { Vec2(x, y + 1), Vec2(x + 1, y), Vec2(x, y - 1), Vec2(x - 1, y)};
214 }
215 
directions8(RandomGen & random)216 vector<Vec2> Vec2::directions8(RandomGen& random) {
217   return random.permutation(directions8());
218 }
219 
neighbors8(RandomGen & random) const220 vector<Vec2> Vec2::neighbors8(RandomGen& random) const {
221   return random.permutation(neighbors8());
222 }
223 
directions4(RandomGen & random)224 vector<Vec2> Vec2::directions4(RandomGen& random) {
225   return random.permutation(directions4());
226 }
227 
neighbors4(RandomGen & random) const228 vector<Vec2> Vec2::neighbors4(RandomGen& random) const {
229   return random.permutation(neighbors4());
230 }
231 
isCardinal4() const232 bool Vec2::isCardinal4() const {
233   return abs(x) + abs(y) == 1;
234 }
235 
isCardinal8() const236 bool Vec2::isCardinal8() const {
237   return max(abs(x), abs(y)) == 1;
238 }
239 
getCardinalDir() const240 Dir Vec2::getCardinalDir() const {
241   switch (x) {
242     case 0:
243       switch (y) {
244         case -1: return Dir::N;
245         case 1: return Dir::S;
246       }
247       break;
248     case 1:
249       switch (y) {
250         case 0: return Dir::E;
251         case -1: return Dir::NE;
252         case 1: return Dir::SE;
253       }
254       break;
255     case -1:
256       switch (y) {
257         case 0: return Dir::W;
258         case -1: return Dir::NW;
259         case 1: return Dir::SW;
260       }
261       break;
262   }
263   FATAL << "Not cardinal dir " << *this;
264   return {};
265 }
266 
corners()267 vector<Vec2> Vec2::corners() {
268   return { Vec2(1, 1), Vec2(1, -1), Vec2(-1, -1), Vec2(-1, 1)};
269 }
270 
calculateLayers(set<Vec2> elems)271 vector<set<Vec2>> Vec2::calculateLayers(set<Vec2> elems) {
272   vector<set<Vec2>> ret;
273   while (1) {
274     ret.emplace_back();
275     set<Vec2> curElems(elems);
276     for (Vec2 v : curElems)
277       for (Vec2 v2 : v.neighbors4())
278         if (!curElems.count(v2)) {
279           ret.back().insert(v);
280           elems.erase(v);
281           break;
282         }
283     if (elems.empty())
284       break;
285   }
286   return ret;
287 }
288 
289 SERIALIZE_DEF(Rectangle, px, py, kx, ky, w, h)
290 
291 SERIALIZATION_CONSTRUCTOR_IMPL(Rectangle);
292 
boundingBox(const vector<Vec2> & verts)293 Rectangle Rectangle::boundingBox(const vector<Vec2>& verts) {
294   CHECK(!verts.empty());
295   int infinity = 1000000;
296   int minX = infinity, maxX = -infinity, minY = infinity, maxY = -infinity;
297   for (Vec2 v : verts) {
298     minX = min(minX, v.x);
299     maxX = max(maxX, v.x);
300     minY = min(minY, v.y);
301     maxY = max(maxY, v.y);
302   }
303   return Rectangle(minX, minY, maxX + 1, maxY + 1);
304 }
305 
centered(Vec2 center,int radius)306 Rectangle Rectangle::centered(Vec2 center, int radius) {
307   return Rectangle(center - Vec2(radius, radius), center + Vec2(radius + 1, radius + 1));
308 }
309 
centered(int radius)310 Rectangle Rectangle::centered(int radius) {
311   return Rectangle(-Vec2(radius, radius), Vec2(radius + 1, radius + 1));
312 }
313 
getAllSquares() const314 vector<Vec2> Rectangle::getAllSquares() const {
315   vector<Vec2> ret;
316   for (Vec2 v : (*this))
317     ret.push_back(v);
318   return ret;
319 }
320 
apply(Vec2::LinearMap map) const321 Rectangle Rectangle::apply(Vec2::LinearMap map) const {
322   Vec2 v1 = map(Vec2(px, py));
323   Vec2 v2 = map(Vec2(kx - 1, ky - 1));
324   return Rectangle(min(v1.x, v2.x), min(v1.y, v2.y), max(v1.x, v2.x) + 1, max(v1.y, v2.y) + 1);
325 }
326 
operator ==(const Rectangle & r) const327 bool Rectangle::operator == (const Rectangle& r) const {
328   return px == r.px && py == r.py && kx == r.kx && ky == r.ky;
329 }
330 
operator !=(const Rectangle & r) const331 bool Rectangle::operator != (const Rectangle& r) const {
332   return !(*this == r);
333 }
334 
335 template <class Archive>
serialize(Archive & ar,const unsigned int)336 void Vec2::serialize(Archive& ar, const unsigned int) {
337   ar(x, y);
338 }
339 
340 SERIALIZABLE(Vec2);
341 
inRectangle(int px,int py,int kx,int ky) const342 bool Vec2::inRectangle(int px, int py, int kx, int ky) const {
343   return x >= px && x < kx && y >= py && y < ky;
344 }
345 
inRectangle(const Rectangle & r) const346 bool Vec2::inRectangle(const Rectangle& r) const {
347   return x >= r.px && x < r.kx && y >= r.py && y < r.ky;
348 }
349 
operator ==(const Vec2 & v) const350 bool Vec2::operator== (const Vec2& v) const {
351   return v.x == x && v.y == y;
352 }
353 
operator !=(const Vec2 & v) const354 bool Vec2::operator!= (const Vec2& v) const {
355   return v.x != x || v.y != y;
356 }
357 
operator +=(const Vec2 & v)358 Vec2& Vec2::operator +=(const Vec2& v) {
359   x += v.x;
360   y += v.y;
361   return *this;
362 }
363 
operator +(const Vec2 & v) const364 Vec2 Vec2::operator + (const Vec2& v) const {
365   return Vec2(x + v.x, y + v.y);
366 }
367 
operator *(int a) const368 Vec2 Vec2::operator * (int a) const {
369   return Vec2(x * a, y * a);
370 }
371 
operator *(double a) const372 Vec2 Vec2::operator * (double a) const {
373   return Vec2(x * a, y * a);
374 }
375 
operator /(int a) const376 Vec2 Vec2::operator / (int a) const {
377   return Vec2(x / a, y / a);
378 }
379 
operator -=(const Vec2 & v)380 Vec2& Vec2::operator -=(const Vec2& v) {
381   x -= v.x;
382   y -= v.y;
383   return *this;
384 }
385 
operator -(const Vec2 & v) const386 Vec2 Vec2::operator - (const Vec2& v) const {
387   return Vec2(x - v.x, y - v.y);
388 }
389 
operator -() const390 Vec2 Vec2::operator - () const {
391   return Vec2(-x, -y);
392 }
393 
operator <(Vec2 v) const394 bool Vec2::operator < (Vec2 v) const {
395   return x < v.x || (x == v.x && y < v.y);
396 }
397 
length8() const398 int Vec2::length8() const {
399   return max(abs(x), abs(y));
400 }
401 
dist8(Vec2 v) const402 int Vec2::dist8(Vec2 v) const {
403   return (v - *this).length8();
404 }
405 
distD(Vec2 v) const406 double Vec2::distD(Vec2 v) const {
407   return (v - *this).lengthD();
408 }
409 
length4() const410 int Vec2::length4() const {
411   return abs(x) + abs(y);
412 }
413 
lengthD() const414 double Vec2::lengthD() const {
415   return sqrt(x * x + y * y);
416 }
417 
shorten() const418 Vec2 Vec2::shorten() const {
419   CHECK(x == 0 || y == 0 || abs(x) == abs(y));
420   int d = length8();
421   return Vec2(x / d, y / d);
422 }
423 
sgn(int a)424 static int sgn(int a) {
425   if (a == 0)
426     return 0;
427   if (a < 0)
428     return -1;
429   else
430     return 1;
431 }
432 
sgn(int a,int b)433 static int sgn(int a, int b) {
434   if (abs(a) >= abs(b))
435     return sgn(a);
436   else
437     return 0;
438 }
439 
approxL1() const440 pair<Vec2, Vec2> Vec2::approxL1() const {
441   return make_pair(Vec2(sgn(x, x), sgn(y,y)), Vec2(sgn(x, y), sgn(y, x)));
442 }
443 
getBearing() const444 Vec2 Vec2::getBearing() const {
445   double ang = atan2(y, x) / 3.14159265359 * 180 / 45;
446   if (ang < 0)
447     ang += 8;
448   if (ang < 0.5 || ang >= 7.5)
449     return Vec2(1, 0);
450   if (ang >= 0.5 && ang < 1.5)
451     return Vec2(1, 1);
452   if (ang >= 1.5 && ang < 2.5)
453     return Vec2(0, 1);
454   if (ang >= 2.5 && ang < 3.5)
455     return Vec2(-1, 1);
456   if (ang >= 3.5 && ang < 4.5)
457     return Vec2(-1, 0);
458   if (ang >= 4.5 && ang < 5.5)
459     return Vec2(-1, -1);
460   if (ang >= 5.5 && ang < 6.5)
461     return Vec2(0, -1);
462   if (ang >= 6.5 && ang < 7.5)
463     return Vec2(1, -1);
464   FATAL << ang;
465   return Vec2(0, 0);
466 }
467 
getCenterOfWeight(vector<Vec2> vs)468 Vec2 Vec2::getCenterOfWeight(vector<Vec2> vs) {
469   Vec2 ret;
470   for (Vec2 v : vs)
471     ret += v;
472   return ret / vs.size();
473 }
474 
Rectangle(int _w,int _h)475 Rectangle::Rectangle(int _w, int _h) : px(0), py(0), kx(_w), ky(_h), w(_w), h(_h) {
476   if (w <= 0 || h <= 0) {
477     kx = ky = 0;
478     w = h = 0;
479   }
480 }
481 
Rectangle(Vec2 d)482 Rectangle::Rectangle(Vec2 d) : Rectangle(d.x, d.y) {
483 }
484 
Rectangle(int px1,int py1,int kx1,int ky1)485 Rectangle::Rectangle(int px1, int py1, int kx1, int ky1) : px(px1), py(py1), kx(kx1), ky(ky1), w(kx1 - px1),
486     h(ky1 - py1) {
487   if (kx <= px || ky <= py) {
488     kx = px;
489     ky = py;
490     w = h = 0;
491   }
492 }
493 
Rectangle(Vec2 p,Vec2 k)494 Rectangle::Rectangle(Vec2 p, Vec2 k) : Rectangle(p.x, p.y, k.x, k.y) {
495 }
496 
Rectangle(Range xRange,Range yRange)497 Rectangle::Rectangle(Range xRange, Range yRange)
498     : Rectangle(xRange.getStart(), yRange.getStart(), xRange.getEnd(), yRange.getEnd()) {
499 }
500 
Iter(int x1,int y1,int px1,int py1,int kx1,int ky1)501 Rectangle::Iter::Iter(int x1, int y1, int px1, int py1, int kx1, int ky1) : pos(x1, y1), px(px1), py(py1), kx(kx1), ky(ky1) {}
502 
randomVec2() const503 Vec2 Rectangle::randomVec2() const {
504   return Vec2(Random.get(px, kx), Random.get(py, ky));
505 }
506 
middle() const507 Vec2 Rectangle::middle() const {
508   return Vec2((px + kx) / 2, (py + ky) / 2);
509 }
510 
left() const511 int Rectangle::left() const {
512   return px;
513 }
514 
top() const515 int Rectangle::top() const {
516   return py;
517 }
518 
getXRange() const519 Range Rectangle::getXRange() const {
520   return Range(px, kx);
521 }
522 
getYRange() const523 Range Rectangle::getYRange() const {
524   return Range(py, ky);
525 }
526 
right() const527 int Rectangle::right() const {
528   return kx;
529 }
530 
bottom() const531 int Rectangle::bottom() const {
532   return ky;
533 }
534 
width() const535 int Rectangle::width() const {
536   return w;
537 }
538 
height() const539 int Rectangle::height() const {
540   return h;
541 }
542 
area() const543 int Rectangle::area() const {
544   return w * h;
545 }
546 
getSize() const547 Vec2 Rectangle::getSize() const {
548   return Vec2(w, h);
549 }
550 
topLeft() const551 Vec2 Rectangle::topLeft() const {
552   return Vec2(px, py);
553 }
554 
bottomRight() const555 Vec2 Rectangle::bottomRight() const {
556   return Vec2(kx, ky);
557 }
558 
topRight() const559 Vec2 Rectangle::topRight() const {
560   return Vec2(kx, py);
561 }
562 
bottomLeft() const563 Vec2 Rectangle::bottomLeft() const {
564   return Vec2(px, ky);
565 }
566 
intersects(const Rectangle & other) const567 bool Rectangle::intersects(const Rectangle& other) const {
568   return max(px, other.px) < min(kx, other.kx) && max(py, other.py) < min(ky, other.ky);
569 }
570 
contains(const Rectangle & other) const571 bool Rectangle::contains(const Rectangle& other) const {
572   return px <= other.px && py <= other.py && kx >= other.kx && ky >= other.ky;
573 }
574 
intersection(const Rectangle & other) const575 Rectangle Rectangle::intersection(const Rectangle& other) const {
576   return Rectangle(max(px, other.px), max(py, other.py), min(kx, other.kx), min(ky, other.ky));
577 }
578 
translate(Vec2 v) const579 Rectangle Rectangle::translate(Vec2 v) const {
580   return Rectangle(topLeft() + v, bottomRight() + v);
581 }
582 
minusMargin(int margin) const583 Rectangle Rectangle::minusMargin(int margin) const {
584   return Rectangle(px + margin, py + margin, kx - margin, ky - margin);
585 }
586 
operator *() const587 Vec2 Rectangle::Iter::operator* () const {
588   return pos;
589 }
operator !=(const Iter & other) const590 bool Rectangle::Iter::operator != (const Iter& other) const {
591   return pos != other.pos;
592 }
593 
operator ++()594 const Rectangle::Iter& Rectangle::Iter::operator++ () {
595   ++pos.y;
596   if (pos.y >= ky) {
597     pos.y = py;
598     ++pos.x;
599   }
600   return *this;
601 }
602 
begin() const603 Rectangle::Iter Rectangle::begin() const {
604   return Iter(px, py, px, py, kx, ky);
605 }
606 
end() const607 Rectangle::Iter Rectangle::end() const {
608   return Iter(kx, py, px, py, kx, ky);
609 }
610 
Range(int a,int b)611 Range::Range(int a, int b) : start(a), finish(b) {
612 }
Range(int a)613 Range::Range(int a) : Range(0, a) {}
614 
singleElem(int a)615 Range Range::singleElem(int a) {
616   return Range(a, a + 1);
617 }
618 
reverse()619 Range Range::reverse() {
620   Range r(finish - 1, start - 1);
621   r.increment = -1;
622   return r;
623 }
624 
isEmpty() const625 bool Range::isEmpty() const {
626   return (increment == 1 && start >= finish) || (increment == -1 && start <= finish);
627 }
628 
shorten(int r)629 Range Range::shorten(int r) {
630   if (start < finish) {
631     if (finish - start >= 2 * r)
632       return Range(start + r, finish - r);
633     else
634       return Range(0, 0);
635   } else {
636     if (start - finish >= 2 * r)
637       return Range(start - r, finish + r);
638     else
639       return Range(0, 0);
640   }
641 }
642 
getStart() const643 int Range::getStart() const {
644   return start;
645 }
646 
getEnd() const647 int Range::getEnd() const {
648   return finish;
649 }
650 
getLength() const651 int Range::getLength() const {
652   return finish - start;
653 }
654 
contains(int p) const655 bool Range::contains(int p) const {
656   return (increment > 0 && p >= start && p < finish) || (increment < 0 && p <= start && p > finish);
657 }
658 
begin()659 Range::Iter Range::begin() {
660   if ((increment > 0 && start < finish) || (increment < 0 && start > finish))
661     return Iter(start, start, finish, increment);
662   else
663     return end();
664 }
665 
end()666 Range::Iter Range::end() {
667   return Iter(finish, start, finish, increment);
668 }
669 
Iter(int i,int a,int b,int inc)670 Range::Iter::Iter(int i, int a, int b, int inc) : ind(i), min(a), max(b), increment(inc) {}
671 
operator *() const672 int Range::Iter::operator* () const {
673   return ind;
674 }
675 
operator !=(const Iter & other) const676 bool Range::Iter::operator != (const Iter& other) const {
677   return other.ind != ind;
678 }
679 
operator ++()680 const Range::Iter& Range::Iter::operator++ () {
681   ind += increment;
682   //CHECK(ind <= max && ind >= min) << ind << " " << min << " " << max;
683   return *this;
684 }
685 
686 SERIALIZE_DEF(Range, start, finish, increment)
687 SERIALIZATION_CONSTRUCTOR_IMPL(Range);
688 
combine(const vector<string> & adj,bool commasOnly)689 string combine(const vector<string>& adj, bool commasOnly) {
690   string res;
691   for (int i : All(adj)) {
692     if (i == adj.size() - 1 && i > 0 && !commasOnly)
693       res.append(" and ");
694     else if (i > 0)
695       res.append(", ");
696     res.append(adj[i]);
697   }
698   return res;
699 }
700 
hasSentenceEnding(const string & s)701 bool hasSentenceEnding(const string& s) {
702   return s.back() == '.' || s.back() == '?' || s.back() == '!' || s.back() == '\"';
703 }
704 
combineSentences(const vector<string> & v)705 string combineSentences(const vector<string>& v) {
706   if (v.empty())
707     return "";
708   string ret;
709   for (string s : v) {
710     if (s.empty())
711       continue;
712     if (!ret.empty()) {
713       if (!hasSentenceEnding(ret))
714         ret += ".";
715       ret += " ";
716     }
717     ret += s;
718   }
719   return ret;
720 }
721 
addAParticle(const string & s)722 string addAParticle(const string& s) {
723   if (isupper(s[0]))
724     return s;
725   if (contains({'a', 'e', 'u', 'i', 'o'}, s[0]))
726     return string("an ") + s;
727   else
728     return string("a ") + s;
729 }
730 
capitalFirst(string s)731 string capitalFirst(string s) {
732   if (!s.empty() && islower(s[0]))
733     s[0] = toupper(s[0]);
734   return s;
735 }
736 
noCapitalFirst(string s)737 string noCapitalFirst(string s) {
738   if (!s.empty() && isupper(s[0]))
739     s[0] = tolower(s[0]);
740   return s;
741 }
742 
makeSentence(string s)743 string makeSentence(string s) {
744   if (s.empty())
745     return s;
746   s = capitalFirst(s);
747   if (s.size() > 1 && s[0] == '\"' && islower(s[1]))
748     s[1] = toupper(s[1]);
749   if (!hasSentenceEnding(s))
750     s.append(".");
751   return s;
752 }
753 
makeSentences(string s)754 vector<string> makeSentences(string s) {
755   vector<string> ret = split(s, {'.'});
756   for (auto& elem : ret) {
757     trim(elem);
758     elem = makeSentence(elem);
759   }
760   return ret;
761 }
762 
lowercase(string s)763 string lowercase(string s) {
764   for (int i : All(s))
765     if (isupper(s[i]))
766       s[i] = tolower(s[i]);
767   return s;
768 }
769 
getPlural(const string & a,const string & b,int num)770 string getPlural(const string& a, const string&b, int num) {
771   if (num == 1)
772     return "1 " + a;
773   else
774     return toString(num) + " " + b;
775 }
776 
getPlural(const string & a,int num)777 string getPlural(const string& a, int num) {
778   if (num == 1)
779     return "1 " + a;
780   else
781     return toString(num) + " " + a + "s";
782 }
783 
toText(int num)784 static string toText(int num) {
785   switch (num) {
786     case 0: return "zero";
787     case 1: return "one";
788     case 2: return "two";
789     case 3: return "three";
790     case 4: return "four";
791     case 5: return "five";
792     case 6: return "six";
793     case 7: return "seven";
794     case 8: return "eight";
795     case 9: return "nine";
796     default: FATAL << "Unsupported number " << num;
797              return "";
798   }
799 }
800 
getPluralText(const string & a,int num)801 string getPluralText(const string& a, int num) {
802   if (num == 1)
803     return "a " + a;
804   else
805     return toText(num) + " " + a + "s";
806 }
807 
Semaphore(int v)808 Semaphore::Semaphore(int v) : value(v) {}
809 
p()810 void Semaphore::p() {
811   std::unique_lock<std::mutex> lock(mut);
812   while (!value) {
813     cond.wait(lock);
814   }
815   --value;
816 }
817 
get()818 int Semaphore::get() {
819   std::unique_lock<std::mutex> lock(mut);
820   return value;
821 }
822 
v()823 void Semaphore::v() {
824   std::unique_lock<std::mutex> lock(mut);
825   ++value;
826   lock.unlock();
827   cond.notify_one();
828 }
829 
__anonbfec713f0102null830 AsyncLoop::AsyncLoop(function<void()> f) : AsyncLoop([]{}, f) {
831 }
832 
AsyncLoop(function<void ()> init,function<void ()> loop)833 AsyncLoop::AsyncLoop(function<void()> init, function<void()> loop)
834     : done(false), t([=] { init(); while (!done) { loop(); }}) {
835 }
836 
setDone()837 void AsyncLoop::setDone() {
838   done = true;
839 }
840 
finishAndWait()841 void AsyncLoop::finishAndWait() {
842   setDone();
843   if (t.joinable())
844     t.join();
845 }
846 
~AsyncLoop()847 AsyncLoop::~AsyncLoop() {
848   finishAndWait();
849 }
850 
ConstructorFunction(function<void ()> fun)851 ConstructorFunction::ConstructorFunction(function<void()> fun) {
852   fun();
853 }
854 
DestructorFunction(function<void ()> dest)855 DestructorFunction::DestructorFunction(function<void()> dest) : destFun(dest) {
856 }
857 
~DestructorFunction()858 DestructorFunction::~DestructorFunction() {
859   destFun();
860 }
861 
contains(DirSet dirSet) const862 bool DirSet::contains(DirSet dirSet) const {
863   return intersection(dirSet) == dirSet;
864 }
865 
DirSet(const initializer_list<Dir> & dirs)866 DirSet::DirSet(const initializer_list<Dir>& dirs) {
867   for (Dir dir : dirs)
868     content |= (1 << int(dir));
869 }
870 
DirSet(const vector<Dir> & dirs)871 DirSet::DirSet(const vector<Dir>& dirs) {
872   for (Dir dir : dirs)
873     content |= (1 << int(dir));
874 }
875 
DirSet(unsigned char c)876 DirSet::DirSet(unsigned char c) : content(c) {
877 }
878 
DirSet()879 DirSet::DirSet() {
880 }
881 
DirSet(bool n,bool s,bool e,bool w,bool ne,bool nw,bool se,bool sw)882 DirSet::DirSet(bool n, bool s, bool e, bool w, bool ne, bool nw, bool se, bool sw) {
883   content = n | (s << 1) | (e << 2) | (w << 3) | (ne << 4) | (nw << 5) | (se << 6) | (sw << 7);
884 }
885 
insert(Dir dir)886 void DirSet::insert(Dir dir) {
887   content |= (1 << int(dir));
888 }
889 
has(Dir dir) const890 bool DirSet::has(Dir dir) const {
891   return content & (1 << int(dir));
892 }
893 
oneElement(Dir dir)894 DirSet DirSet::oneElement(Dir dir) {
895   return DirSet(1 << int(dir));
896 }
897 
fullSet()898 DirSet DirSet::fullSet() {
899   return 255;
900 }
901 
intersection(DirSet s) const902 DirSet DirSet::intersection(DirSet s) const {
903   s.content &= content;
904   return s;
905 }
906 
complement() const907 DirSet DirSet::complement() const {
908   return ~content;
909 }
910 
Iter(const DirSet & s,Dir num)911 DirSet::Iter::Iter(const DirSet& s, Dir num) : set(s), ind(num) {
912   goForward();
913 }
914 
goForward()915 void DirSet::Iter::goForward() {
916   while (ind < Dir(8) && !set.has(ind))
917     ind = Dir(int(ind) + 1);
918 }
919 
operator *() const920 Dir DirSet::Iter::operator* () const {
921   return ind;
922 }
923 
operator !=(const Iter & other) const924 bool DirSet::Iter::operator != (const Iter& other) const {
925   return ind != other.ind;
926 }
927 
operator ++()928 const DirSet::Iter& DirSet::Iter::operator++ () {
929   ind = Dir(int(ind) + 1);
930   goForward();
931   return *this;
932 }
933 
DisjointSets(int s)934 DisjointSets::DisjointSets(int s) : father(s), size(s, 1) {
935   for (int i : Range(s))
936     father[i] = i;
937 }
938 
join(int i,int j)939 void DisjointSets::join(int i, int j) {
940   i = getSet(i);
941   j = getSet(j);
942   if (size[i] < size[j])
943     swap(i, j);
944   father[j] = i;
945   size[i] += size[j];
946 }
947 
same(int i,int j)948 bool DisjointSets::same(int i, int j) {
949   return getSet(i) == getSet(j);
950 }
951 
same(const vector<int> & v)952 bool DisjointSets::same(const vector<int>& v) {
953   for (int i : All(v))
954     if (!same(v[i], v[0]))
955       return false;
956   return true;
957 }
958 
getSet(int i)959 int DisjointSets::getSet(int i) {
960   int ret = i;
961   while (father[ret] != ret)
962     ret = father[ret];
963   while (i != ret) {
964     int j = father[i];
965     father[i] = ret;
966     i = j;
967   }
968   return ret;
969 }
970 
getSize(const std::string & s)971 int getSize(const std::string& s) {
972   return s.size();
973 }
974 
getString(const std::string & s)975 const char* getString(const std::string& s) {
976   return s.c_str();
977 }
978 
combineWithOr(const vector<string> & elems)979 string combineWithOr(const vector<string>& elems) {
980   string ret;
981   for (auto& elem : elems) {
982     if (!ret.empty())
983       ret += " or ";
984     ret += elem;
985   }
986   return ret;
987 }
988