Skip to content

Commit 57b7f96

Browse files
author
Aseem Brahma
committed
ColorfulChocolates
1 parent 6e8a8aa commit 57b7f96

File tree

1 file changed

+171
-0
lines changed

1 file changed

+171
-0
lines changed

ColorfulChocolates.cpp

+171
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
#include <iostream>
2+
#include <iterator>
3+
#include <algorithm>
4+
#include <map>
5+
#include <vector>
6+
#include <iomanip>
7+
#include <sstream>
8+
#include <queue>
9+
#include <string>
10+
#include <cmath>
11+
#include <set>
12+
#include <limits>
13+
#include <numeric>
14+
#include <bitset>
15+
#include <stack>
16+
#include <utility>
17+
#include <unordered_set>
18+
#include <unordered_map>
19+
20+
#define DEBUG 0
21+
#define ARR_SIZE(x) ((sizeof(x)) / (sizeof(x[0])))
22+
#define INF_INT numeric_limits<int>::max()
23+
#define MIN_INT numeric_limits<int>::min()
24+
25+
using namespace std;
26+
27+
typedef unsigned long long ULL;
28+
typedef long long LL;
29+
typedef pair<int, int> pii;
30+
31+
vector<string> &split(const string &s, char delim, vector<string> &elems) {
32+
stringstream ss(s);
33+
string item;
34+
while (getline(ss, item, delim)) {
35+
elems.push_back(item);
36+
}
37+
return elems;
38+
}
39+
40+
vector<string> split(const string &s, char delim) {
41+
vector<string> elems;
42+
split(s, delim, elems);
43+
return elems;
44+
}
45+
46+
template <typename K, typename V>
47+
V GetWithDef(const std::map <K,V> & m, const K & key, const V & defval ) {
48+
typename std::map<K,V>::const_iterator it = m.find( key );
49+
if ( it == m.end() ) {
50+
return defval;
51+
}
52+
else {
53+
return it->second;
54+
}
55+
}
56+
57+
template<typename T>
58+
void print_vector(const vector<T> &v) {
59+
cerr << " { ";
60+
for (typename vector<T>::const_iterator it = v.begin(); it != v.end(); ++it) {
61+
cerr << *it << ", ";
62+
}
63+
cerr << " } " << endl;
64+
}
65+
66+
class ColorfulChocolates {
67+
/*
68+
* For each letter, record the positions that it occurs in, into a set
69+
* For each such set, for each entry, see how many letters you can bring
70+
* in adjacent to that entry, without exceeding the number of swaps
71+
* For example, if 'B' occurs at positions {1, 2, 4, 6, 7}, and if in the
72+
* current iteration we are considering the entry for position 4, then
73+
* maintain a list of iterators encompassing how many positions we are spread
74+
* over, and a list of position indices representing the actual spread.
75+
* In this case, we start with iterators to [4, 4], and indices [4, 4]. When
76+
* we combine the letter at position 2, we update to [2, 4], indices [3, 4]
77+
* because we have now dealt with the letter at position 2, and brought it
78+
* over to position 3
79+
*/
80+
81+
public:
82+
int maximumSpread(string chocolates, int maxSwaps) {
83+
int result = 0;
84+
unordered_map<char, set<int> > m;
85+
for (int i = 0; i < chocolates.size(); ++i) {
86+
m[chocolates[i]].insert(i);
87+
}
88+
for (unordered_map<char, set<int> >::iterator it = m.begin();
89+
it != m.end();
90+
++it) {
91+
//cout << it->first << endl;
92+
set<int>::iterator set_last = prev(it->second.end());
93+
for (set<int>::iterator it2 = it->second.begin();
94+
it2 != it->second.end();
95+
++it2) {
96+
int swapsLeft = maxSwaps;
97+
int spread = 1;
98+
pair<set<int>::iterator, set<int>::iterator> endpts = make_pair(it2,
99+
it2);
100+
pair<int, int> endidx = make_pair(*it2, *it2);
101+
102+
while (swapsLeft > 0 &&
103+
!(endpts.first == it->second.begin() && endpts.second == set_last)) {
104+
int lb_diff = numeric_limits<int>::max();
105+
if (endpts.first != it->second.begin())
106+
lb_diff = endidx.first - (*(prev(endpts.first)));
107+
108+
int ub_diff = numeric_limits<int>::max();
109+
if (endpts.second != set_last)
110+
ub_diff = *(next(endpts.second)) - endidx.second;
111+
112+
int diff;
113+
if (lb_diff <= ub_diff) {
114+
--endpts.first;
115+
--endidx.first;
116+
diff = lb_diff;
117+
}
118+
else {
119+
++endpts.second;
120+
++endidx.second;
121+
diff = ub_diff;
122+
}
123+
//cout << *endpts.first << ", " << *endpts.second << endl;
124+
//cout << endidx.first << ", " << endidx.second << endl;
125+
swapsLeft -= (diff - 1);
126+
if (swapsLeft >= 0)
127+
++spread;
128+
}
129+
130+
//cout << "spread " << spread << endl;
131+
result = max(result, spread);
132+
}
133+
}
134+
return result;
135+
}
136+
137+
bool runTest(string chocolates, int maxSwaps, int solution) {
138+
int output = maximumSpread(chocolates, maxSwaps);
139+
140+
if (output != solution)
141+
{
142+
cerr << "Failed for " << chocolates << ", " << maxSwaps << endl;
143+
cerr << "Expected: " << solution << endl;
144+
cerr << "Found instead:" << output << endl;
145+
return false;
146+
}
147+
else {
148+
return true;
149+
}
150+
}
151+
};
152+
153+
int main(int argc, char* argv[]) {
154+
ColorfulChocolates test;
155+
{
156+
test.runTest("ABCDCBC", 1, 2);
157+
}
158+
{
159+
test.runTest("ABCDCBC", 2, 3);
160+
}
161+
{
162+
test.runTest("ABBABABBA", 3, 4);
163+
}
164+
{
165+
test.runTest("ABBABABBA", 4, 5);
166+
}
167+
{
168+
test.runTest("QASOKZNHWNFODOQNHGQKGLIHTPJUVGKLHFZTGPDCEKSJYIWFOO", 77, 5);
169+
}
170+
}
171+

0 commit comments

Comments
 (0)