I created two solutions for leetcode problem 17 in which it asks you to generate all possible text strings from a phone number combination, e.g. "3" results in ["d","e","f"].
My first solution uses a recursive algorithm to generate the strings and is given below:
class Solution {
public:
void fill_LUT(vector<string>& lut) {
lut.clear();
lut.push_back(" ");
lut.push_back("");
lut.push_back("abc");
lut.push_back("def");
lut.push_back("ghi");
lut.push_back("jkl");
lut.push_back("mno");
lut.push_back("pqrs");
lut.push_back("tuv");
lut.push_back("wxyz");
}
void generate_strings(int index, string& digits, vector<string>& lut, vector<string>& r, string& work) {
if(index >= digits.size()) {
r.push_back(work);
return;
}
char idx = digits[index] - '0';
for(char c : lut[idx]) {
work.push_back(c);
generate_strings(index+1, digits, lut, r, work);
work.pop_back();
}
}
vector<string> letterCombinations(string digits) {
vector<string> r;
vector<string> lut;
fill_LUT(lut);
if(digits.size() <= 0)
return r;
string work;
generate_strings(0, digits, lut, r, work);
return r;
}
};
I am a bit rusty with big-O, but it appears to me that the space complexity would be O(n) for the recursive call, i.e. its maximum depth, O(n) for the buffer string, and O(n*c^n) for the resulting strings. Would this sum together as O(n+n*c^n)?
For time complexity I am a bit confused. Each level of the recursion performs c pushes + pops + recursive calls multiplied by the number of operations by the next level, so it sounds like c^1 + c^2 + ... + c^n. In addition, there are c^n duplications of n length strings. How do I consolidate this into a nice big-O representation?
The second solution views the number of results as a mixed radix number and converts it to a string as you might perform an int to hex string conversion:
class Solution {
public:
void fill_LUT(vector<string>& lut) {
lut.clear();
lut.push_back(" ");
lut.push_back("");
lut.push_back("abc");
lut.push_back("def");
lut.push_back("ghi");
lut.push_back("jkl");
lut.push_back("mno");
lut.push_back("pqrs");
lut.push_back("tuv");
lut.push_back("wxyz");
}
vector<string> letterCombinations(string digits) {
vector<string> r;
vector<string> lut;
fill_LUT(lut);
if(digits.size() <= 0)
return r;
unsigned total = 1;
for(int i = 0; i < digits.size(); i++) {
digits[i] = digits[i]-'0';
auto m = lut[digits[i]].size();
if(m > 0) total *= m;
}
for(int i = 0; i < total; i++) {
int current = i;
r.push_back(string());
string& s = r.back();
for(char c : digits) {
int radix = lut[c].size();
if(radix != 0) {
s.push_back(lut[c][current % radix]);
current = current / radix;
}
}
}
return r;
}
};
In this case, I believe that the space complexity is O(n*c^n) similar to the first solution minus the buffer and recursion, and the time complexity must be O(n) for the first for loop and an additional O(n*c^n) to create a result string for each of the possible results. The final big-O for this is O(n+n*c^n). Is my thought process correct?
Edit: To add some clarification to the code, imagine an input string of "234". The first recursive solution will call generate_strings with the arguments (0, "234", lut, r, work). lut is a look up table that converts a number to its corresponding characters. r is the vector containing the resulting strings. work is a buffer where the work is performed.
The first recursive call will then see that the index 0 digit is 2 which corresponds with "abc", push a to work, and then call generate_strings with the arguments (1, "234", lut, r, work). Once the call returns it will then push b to work and rinse and repeat.
When index is equal to the size of digits then a unique string has been generated and the string is pushed onto r.
For the second solution, the input string is first converted from it's ascii representation to it's integer representation. For example "234" is converted to "\x02\x03\x04". Then the code uses those as indices to look up the number of corresponding characters in the lookup table and calculates the total number of strings that will be in the result. e.g. if the input string was "234", 2 corresponds with abc, which has 3 characters. 3 corresponds with def which has 3 characters. 4 corresponds with ghi which has 3 characters. The total number of possible strings is 3*3*3 = 27.
Then the code uses a counter to represent each of the possible strings. If i were 15 it would be evaluated by first finding 15 % 3 which is 0, corresponding with the first character for the first digit (a). Then divide 15 by 3 which is 5. 5 % 3 is 2 which corresponds with the third character for the second digit, which is f. Finally divide 5 by 3 and you get 1. 1 % 3 is 1 which corresponds with the second character for the third digit, h. Therefore the string that corresponds with the number 15 is afh. This is performed for each number and the resulting strings are stored in r.
Recursive algorithm:
Space: each level of recursion is O(1) and there are O(n) levels. Thus it is O(n) for the recursion. The space of result is O(c^n), where c = max(lut[i].length). Total space for the algorithm is O(c^n).
Time: Let T(n) be the cost for digit with length n. Then we have recursion formula : T(n) <= c T(n-1) + O(1). Solve this equation give T(n) = O(c^n).
Hashing algorithm:
Space: if you need the space to store all results, then it is still O(c^n).
Time: O(n+c^n) = O(c^n).
I like the Hashing algorithm because it is better if the question asks you to give a specific string result (suppose we order them by alphabet order). In that case, the space and time is only O(n).
This question reminds me to a similar question: generate all permutations of the set {1,2,3,...,n}. The hashing approach is better because by generating the permutation one by one and process it, we can save a lot of space.
Related
I have Rabin Karp implementation in C++ (Rabin Karp is a string pattern matching algorithm that uses hashing technique to match substrings [Wiki link to the algorithm] (https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm)), A trivial test case fails, I suspect precomputation of substring hashes routine is doing something wrong, because I tried replacing the precomputed value with the PolynomialHash function call ie. computing the hash of the substring in flight. I get the correct result with PolynomialHash function call but precomputed doesn't. What might have I done wrong here?
Algorithm pseudo code
1) Choose a large Prime p.
2) Let x be a random value in range [1, p-1].
3) Get the hash value for the pattern (p and x are used here).
4) For each substring which has length equal to the pattern compute the hash value of this substring.
5) If the hash values of pattern and the substring match then this substring could be a potential match, to ensure, check whether they are in fact the same.
The reason a good implementation should avoid using PolynomialHash is because the time complexity goes high, instead precomputing the Hash values for each substring is more efficient. So, my problem is the precomputed hashes, and the function call hash values don't match. Below is the relevant code and the failing testcase. Note the large prime I used is 1e9 + 7. ll is typedef for long long int.
bool AreEqual(const string &text,const string &pattern,int si,int ei){
for(int i =0;i<pattern.size();i++){
if(pattern[i]!=text[si+i]) return false;
}
return true;
}
ll PolynomialHash(const string &str,ll prime,ll x,int si,int ei){
ll hash_val = 0;
for(int i = ei;i>=si;i--) hash_val = (hash_val*x+str[i])%prime;
return hash_val;
}
ll GetInt(const char &x){
return x-'a';
}
void PrecomputeSubstringHashes(vector<ll> &substring_hashes,const string &text,const string &pattern,ll prime,ll x){
int text_len = text.length();
int pattern_len = pattern.length();
substring_hashes[text_len-pattern_len] = PolynomialHash(text,prime,x,text_len-pattern_len,text_len-1);
ll y = 1;
for(int i =0;i<pattern_len;i++) y = (y*x)%prime; // can still be optimized to O(log(|P|))
for(int i = text_len-pattern_len-1;i>=0;i--){
substring_hashes[i] = (prime + substring_hashes[i+1]*x + GetInt(text[i]) - y*GetInt(text[i+pattern_len]))%prime;
}
}
void RabinKarpSubstringSearch(const string &text,const string &pattern){
vector<int>positions;
ll prime = Mod; // This large prime used is 1e9 + 7
ll x = 1 + rand()%prime;
ll pattern_hash = PolynomialHash(pattern,prime,x,0,pattern.length()-1);
assert(text.length()>=pattern.length());
vector<ll>substring_hashes(text.length()-pattern.length()+1,0);
PrecomputeSubstringHashes(substring_hashes,text,pattern,prime,x);
for(int i =0;i<=text.length()-pattern.length();i++){
ll substr_hash = substring_hashes[i]; // Try with PolynomialHash it gives correct results
if(substr_hash!=pattern_hash) continue;
// cout<<"Hitting at "<<i<<' '; // checking if expected and more indices [the wrong ones] hit this line.
if(AreEqual(text,pattern,i,i+pattern.length()-1)) positions.push_back(i); /// The probablity of this condition being hit is too less thanks to a large prime number.
}
cout<<'\n';
for(const int &x : positions) cout<<x<<' ';
}
// Test case
aab
abxaabbbaaab
PolynomialHash gives [3,9] as expected
substring_hashes[i] gives only [9]
I Did some further analysis I was right to suspect the Hash returned by Function and the precomputed values don't match. Here are both of them with input same as in the testcase. The Pattern Hash value is 850147133 seen at index 3 and 9 in Function hash.
// Function computed Hashes [index,HashValue]
0 45760133
1 921924329
2 423268806
3 **850147133**
4 654436503
5 654436504
6 227558154
7 423268784
8 423268783
9 **850147133**
// Precomputed Hashes [index,HashValue]
0 317287043
1 159209231
2 90628189
3 807191256
4 327387316
5 934623271
6 740231484
7 428758105
8 399604110
9 **850147133**
I'm trying to solve a coding problem, the problem is:
Take a string input
Take a number input 'n'
Repeat the string up to n indexes
Count the number of 'a' characters that occur in the repeated string
This problem was authored by tunyash on Hackerrank with title 'Repeated String'
My current solution is taking too much time to run
This is what I am currently doing:
Use a variable to iterate through the original string
Each time the variable exceeds the original string length, reset it to 0
Iterate n times
I've made a function to do the counting as follows:
long long repeatedString(std::string s, long long n) {
long long sIndex{ 0 }, length = s.size(), result{ 0 };
for (long long i = 0; i < n; i++)
{
if (sIndex > (length - 1))
sIndex = 0;
if (s[sIndex] == 'a')
result += 1;
sIndex += 1;
}
return result;
}
I've tried modifying and using binary search algorithm by first writing the whole string then searching but the writing part takes too much time and seems not very intuitive
This is a typical beginner programming exercise. The idea is that you shouldn't blindly overengineer the problem, when a simple mathematical formula is right around the corner. In this case you can simply count the number of a's in the original string and multiply it by n to get the desired result:
std::count(s.begin(), s.end(), 'a') * n
where s is your input string.
Edit: I misinterpreted the question. I assumed n was the number of repetitions of the whole string, whereas it actually was the number of characters to concatenate by modularly concatenating the strings characters up until n number of characters. In this case, simply divide before multiplying: n / s.length() and adjust for the n % s.length() characters remaining with addition. I will leave this as an exercise.
I'm trying to figure out how to calculate the number of all strings of length n such that any substring of length 4 of string w, all three letters a, b, c occur. For example, abbcaabca should be printed when n = 9, but aabbcabac should not be included.
I was trying to make a math formula like
3^N - 3 * 2^N + 3 or (3^(N-3))*N!
Can it work this way or do I have to generate them and count them? I'm working with large numbers like 100, and I don't think I can generate them to count them.
You should probably be able to work your way up and start with let's say all possible words of length 4 and then add just one letter and count the possible allowed resulting words. Then you can iteratively go up to high numbers without having to explore all 3^N possibilities.
const unsigned w = 4;
unsigned n = 10;
vector<string> before,current;
// obtain all possible permutations of the strings "aabc", "abbc" and "abcc"
string base = "aabc";
before.emplace_back(base);
while(std::next_permutation(base.begin(),base.end())) before.emplace_back(base);
base = "abbc";
before.emplace_back(base);
while(std::next_permutation(base.begin(),base.end())) before.emplace_back(base);
base = "abcc";
before.emplace_back(base);
while(std::next_permutation(base.begin(),base.end())) before.emplace_back(base);
// iteratively add single letters to the words in the collection and add if it is a valid word
size_t posa,posb,posc;
for (unsigned k=1;k<n-w;++k)
{
current.clear();
for (const auto& it : before)
{
posa = it.find("a",k);
posb = it.find("b",k);
posc = it.find("c",k);
if (posb!= string::npos && posc!= string::npos) current.emplace_back(it+"a");
if (posa!= string::npos && posc!= string::npos) current.emplace_back(it+"b");
if (posa!= string::npos && posb!= string::npos) current.emplace_back(it+"c");
}
before = current;
}
for (const auto& it : current) cout<<it<<endl;
cout<<current.size()<<" valid words of length "<<n<<endl;
Note that with this you will still however run into the exponential wall pretty quickly... In a more efficient implementation I would represent words as integers (NOT vectors of integers, but rather integers in a base 3 representation), but the exponential scaling would still be there. If you are just interested in the number, #Jeffrey's approach is surely better.
The trick is to break down the problem. Consider:
Would knowing how many such strings, of length 50, ending in each pair of letter, help ?
Number of 50-string, ending in AA times
Number of 50-string, starting with B or C
+
Number of 50-string, ending in AB times
Number of 50-string, starting with C
+
All other combinations gives you the number of 100-long strings.
Continue breaking it down, recursively.
Look up dynamic programming.
Also look up large number libraries.
So, I am trying to solve the following question: https://www.codechef.com/TSTAM15/problems/ACM14AM3
The Mars Orbiter Mission probe lifted-off from the First Launch Pad at Satish Dhawan Space Centre (Sriharikota Range SHAR), Andhra
Pradesh, using a Polar Satellite Launch Vehicle (PSLV) rocket C25 at
09:08 UTC (14:38 IST) on 5 November 2013.
The secret behind this successful launch was the launch pad that ISRO
used. An important part of the launch pad is the launch tower. It is
the long vertical structure which supports the rocket.
ISRO now wants to build a better launch pad for their next mission.
For this, ISRO has acquired a long steel bar, and the launch tower can
be made by cutting a segment from the bar. As part of saving the cost,
the bar they have acquired is not homogeneous.
The bar is made up of several blocks, where the ith block has
durability S[i], which is a number between 0 and 9. A segment is
defined as any contiguous group of one or more blocks.
If they cut out a segment of the bar from ith block to jth block
(i<=j), then the durability of the resultant segment is given by (S[i]*10(j-i) + S[i+1]*10(j-i-1) + S[i+2]*10(j-i-2) + … + S[j] * 10(0)) % M. In other words, if W(i,j) is the base-10 number formed by
concatenating the digits S[i], S[i+1], S[i+2], …, S[j], then
the durability of the segment (i,j) is W(i,j) % M.
For technical reasons that ISRO will not disclose, the durability of
the segment used for building the launch tower should be exactly L.
Given S and M, find the number of ways ISRO can cut out a segment from
the steel bar whose durability is L. Input
The first line contains a string S. The ith character of this string
represents the durability of ith segment. The next line contains a
single integer Q, denoting the number of queries. Each of the next Q
lines contain two space separated integers, denoting M and L. Output
For each query, output the number of ways of cutting the bar on a
separate line. Constraints
1 ≤ |S| ≤ 2 * 10^4
Q ≤ 5
0 < M < 500
0 ≤ L < M
Example
Input:
23128765
3
7 2
9 3
15 5
Output:
9
4
5
Explanation
For M=9, L=3, the substrings whose remainder is 3 when divided by
9 are: 3, 31287, 12 and 876.
Now, what I did was, I initially generate all possible substrings of numbers of the given length, and tried to divide it by the given number to check if it is divisible and added it to the answer. Therefore, my code for the same was,
string s;
cin>>s;
int m,l,ans=0;
for ( i = 0; i < s.length(); i++ )
{
for ( j = i+1; j < s.length(); j++ )
{
string p = s.substr(i,j);
long long num = stoi(p);
if (num%m == l)
ans++;
}
}
cout<<ans<<"\n";
return 0;
But obviously since the input length is upto 10^4, this doesn't work in required time. How can I make it more optimal?
A little advice I can give you is to initialize a variable to s.length() to avoid calling the function each time for each for block.
Ok, here goes, with a working program at the bottom
Major optimization #1
Do not (ever) work with strings when it comes to integer arithmetic. You're converting string => integer over and over and over again (this is an O(n^2) problem), which is painstakingly slow. Besides, it also misses the point.
Solution: first convert your array-of-characters (string) to array-of-numbers. Integer arithmetic is fast.
Major optimization #2
Use a smart conversion from "substring" to number. After transforming the characters to actual integers, they become the factors in the the polynomial a_n * 10^n. To convert a substring of n segments into a number, it is enough to compute sum(a_i * 10^i) for 0 <= i < n.
And nicely enough, if the coefficients a_i are arranged the way they are in the problem's statement, you can use Horner's method (https://en.wikipedia.org/wiki/Horner%27s_method) to very quickly evaluate the numerical value of the substring.
In short: keep a running value of the current substring and growing it by one element is just * 10 + new element
Example: string "128472373".
First substring = "1", value = 1.
For the second substring we need to
add the digit "2" as follows: value = value * 10 + "2", thus: value = 1 * 10 + 2 = 12.
For 3rd substring need to add digit "8": value = value * 10 + "8", thus: value = 12 * 10 + 8 = 128.
Etcetera.
I had some issues with formatting the C++ code inline so I stuck it in IDEone: https://ideone.com/TbJiqK
The gist of the program:
In main loop, loop over all possible start points:
// For all startpoints in the segments array ...
for(int* f=segments; f<segments+n_segments; f++)
// add up the substrings that fullfill the question
n += count_segments(f, segments+n_segments, m, l);
// Output the answer for this question
cout << n << endl;
Implementation of the count_segments() function:
// Find all substrings that % m == l
// Use Horner's algorithm to quickly evaluate sum(a_n*10^n) where
// a_n are the segments' durabilities
int count_segments(int* first, int* last, int m, int l) {
int n = 0, number = 0;
while( first<last ) {
number = number * 10 + *first; // This is Horner's method
if( (number % m)==l ) {
n++;
// If you don't believe - enable this line of output and
// see the numbers matching the combinations of the
//cout << "[" << m << ", " << l << "]: " << number << endl;
}
first++;
}
return n;
}
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
I'm trying to efficiently list numbers between 1 and 100. However I have to get rid of numbers with same digits.
Example:
12 according to this rule is the same of 21
13 is 31
14 is 41
so the for loop it won't go over the same numbers.
I'm thinking a few tricks such as getting all the numbers from 1 to 100 and then deleting the found permutations of current number.
The reason I'm asking this because in large limits like 100000 it will fail.
Another example: 124 is equal to 142,241,214,412,421
You can apply recursion. Prototype of this function is then like:
print_digits(int num_of_remaining_digits,int start_from_digit, int current_number);
EDIT: for completion I present here my solution (i think it has better readbility than from Ben Voigt and ascending output order
void print_digits(int num_of_remaining_digits,int start_from_digit, int current_number)
{
if(num_of_remaining_digits == 0)
{
std::cout << current_number << std::endl;
return;
}
for(int i=start_from_digit;i<=9;i++)
{
print_digits(num_of_remaining_digits-1,i,10*current_number+i);
}
}
and here is testing code
http://ideone.com/Xm8Mv
How this works?
It is one of classics in recursion. First there is stopping condition. And then there is main loop.
Main loop where goes from start_from_digit because all generated digits will be in non decreasing order. For instance if current_number is 15 it will call print_digits whith
print_digits(num_of_remaining_digits-1,5,155)
print_digits(num_of_remaining_digits-1,6,156)
print_digits(num_of_remaining_digits-1,7,157)
print_digits(num_of_remaining_digits-1,8,158)
print_digits(num_of_remaining_digits-1,9,159)
In each call it will check if we reached end whit num_of_remaining_digits and if not will continue from digit that is pushed as start_from_digit (2nd param) using current_number
You're look for combination of some characters (0..9) with a certain length (100=2, 1000=3).
Take a look here Algorithm to return all combinations of k elements from n
I would write a class suiting your comparision needs by overloading the correct operators (from the top of my head that should be only less) and go with a std::set.
I would use a hash table, something like this
1) Derive a key from the number derived in such a way that digits with the same number have the same key (e.g. sum the digits, so "124" and "142" have the key 7, or take the product of the digits(+1), so "124" and "142" have the key 30 - have to +1 for the digit 0)
2) Put the numbers in a hash table indexed by its key
Now the test as to whether you already have a number with the same digits is limited to entities in the hash table with the same key. This algorithm requires linear storage and its performance depends on how good a key you can come up with.
#include <stdio.h>
size_t enum_canonical(char* begin, char* end, char min, char max)
{
if (begin == end) {
puts(begin);
putchar('\n');
return 1;
}
size_t result_count = 0;
--end;
for( *end = min; *end <= max; ++*end )
result_count += enum_canonical(begin, end, min, *end);
return result_count;
}
int main(void)
{
char buff[7];
printf("%d results\n", enum_canonical(buff, &(buff[6] = '\0'), '0', '9'));
}
Demo: http://ideone.com/BWGdg
First, observe that your rule excludes multiples of 11. (Why?)
Start by generating all 2-digit numbers with the first digit = 1.
Now, generate all 2-digit numbers with the first digit = 2, but don't generate any numbers that match numbers in the first list.
Repeat for 3, but don't generate any numbers from the first two lists.
Observe that, for any 2-digit number ab, for it to qualify, it must be the case that a < b, or you would have already generated the corresponding number ba.
In PASCAL, just because I'm feeling ornery:
var i:integer; j:integer;
begin
for i := 1 to 8 do
for j := i+1 to 9 do
println(i*10+j);
end;
ADDED A LITTLE LATER
Observe that the numbers you want to generate will always have their digits strictly monotonically increasing. For a number 2abc to qualify, observe that 2 < a < b < c. (Example: 2539 is a match for 2359 and should be rejected.)
Lets take 1 to 1000. Since there are 4 digits in 1000, I print 1 as 0001, so 0001, 0010, 0100, 1000 are same number as per my algorithm. Also 0120, 0012, 0210, 0102, 0201, 0021 are same numbers.
Here is the program:
int main()
{
int i=0, j=0, k=0;
while(i<=9)
{
int unique=(i*100 + j*10 + k);
printf("unique number : %3d\n", unique);
if(j==9 && k==9)
{
i++;
k=i;
j=i;
}
else if(k==9)
{
j++;
k=j;
}
else
k++;
}
}
Seems like it can be as simple as this:
list = {}
for (j = 1 to 100)
if (j is not excluded from list)
list += j;
Really, only the if condition is interesting: needs to examine all relevant properties of the list items.
Create a function which takes a string, and returns an array of strings with all the possible permutations of the characters in that string. It wouldn't be hard, but it would probably be easiest to make recursive. Though, easier said than done.
Once you have that function, and it returns the array, you simply go through the array and remove the indecies which share a common number with one in the array.
I'd use a set for the permutations of the digits of the number:
std::vector<int> list_unwanted = digit_permutations(number);
std::unordered_set<int> set_unwanted(begin(list_unwanted), end(list_unwanted));
Then loop from 0 to the limit, not adding unwanted numbers by checking if they're in the set set_unwanted:
std::vector<int> numbers;
numbers.reserve(limit - set_unwanted.count());
for (int i = 0; i < limit; ++i)
if (!set_unwanted.count(i))
If you have a set of digits, a whatever permutation of this set is not a valid solution, so first of all make a function to estabilish if a set of digits is a permutation of another set.
To get single digits you can divide by 10 recursively, until you get a zero value.
If you put all the digits in an array like [1,2,4], to check if antoher array is a permutation (you check it only if they have the same length) of antoher set:
bool permutation(int *a, int *b, int n) // n leading dimension
{
bool result=true, vector[n]={false};
for(int i=0;i<n;i++)
{
for(int j=0;j<n ;j++)
{
if(a[i]==b[j])
vector[i]=false;
}
}
for(int i=0;i<n && result;i++)
result=(vector[i]==true); // if vector[i] is false, result is false, is
// not a permutation and the loop ends
return result;
}
I haven't tested it, but I think it works, otherwise tell me.
As for putting all digits in an array, I think it's pretty easy.
Once generating all numbers, you check that a certain number is not a permutation of an already taken number.
Here's my idea, for each value put the digits of it in a set. Use that set as a key to another set that keeps track of which numbers have been used. In my case I use a bit field as a set for the digits, i.e. digit 0 is represented by a 1, digit 1 is represented by a 2 (2 by a 4 and so on). Too tired to explain, here's tha codez:
unsigned int get_digits(int v)
{
unsigned int rv = 0;
do
{
rv |= 1 << (v % 10);
v /= 10;
} while(v);
return rv;
}
void unique_ints(int n)
{
std::set<unsigned int> used_combinations;
for(int i = 0; i < n; ++i)
{
const unsigned int d = get_digits(i);
if(used_combinations.find(d) == used_combinations.end())
{
used_combinations.insert(d);
// cout or some other way to store the value
std::cout << i << std::endl;
}
}
}