---
# System prepended metadata

title: Quine-McCluskey

---

# Quine-McCluskey
I hate this.cpp:
```=cpp
#include <iostream>
#include <vector>
#include <sstream>
#include <algorithm>
#include <set>
#include <bitset>
using namespace std;
int n;
void generateNumbers(const string& input, vector<int>& output)
{
    int count = 0;
    for (char ch:input)
        if (ch == '-') count++;
    int poss = pow(2, count);
    for (int i=0; i<poss; i++)
	{
        string binary = bitset<32>(i).to_string().substr(32 - count);
        string result = input;
        int binaryIndex = 0;
        for (char& ch:result)
		{
            if (ch == '-')
			{
                ch = binary[binaryIndex];
                binaryIndex++;
            }
        }
        output.push_back(std::stoi(result, nullptr, 2));
    }
}
bool cmp2(string a, string b) // hard to identify whether the answer is correct, not necessary
{
    int size = min(a.size(), b.size());
    for (int i = 0; i < size; i++)
    {
        if (a[i] != b[i])
        {
            if (a[i] == '\'') return false;
            if (b[i] == '\'') return true;
            return a[i] < b[i];
        }
    }
    return a.size() < b.size();
}

bool cmp(string a, string b) // sort the list, but kinda useless
{
    int cnta = count(a.begin(), a.end(), '1');
    int cntb = count(b.begin(), b.end(), '1');
    if (cnta != cntb)
        return cnta < cntb;
    return a < b;
}

string toBinary(string enter) // convert number to binary form
{
	string binary;
	int cur = stoi(enter);
	while(cur)
	{
		binary += to_string(cur%2);
		cur/=2;
	}
	while(binary.size()!=n)
	{
		binary += "0";
	}
	reverse(binary.begin(),binary.end());
	//cout << binary << endl;
	return binary;
}
int main(void)
{
	bool DontCare = false;
	string enter;
	cout << "Please Enter varible amount: ";
	cin >> n;
	vector<string> minterm, table, temp;
	set<string> res;
	cin.ignore();
	cout << "Please Enter minterm: ";
	getline(cin,enter);
	stringstream ss(enter);
	while(ss >> enter)
	{
		if(enter == "d") DontCare = true; // dontcare's switch on
		else if(DontCare == true)
		{
			minterm.push_back(toBinary(enter));
		}
		else
		{
			minterm.push_back(toBinary(enter));
			table.push_back(enter); // for prime implicant table
		}
	}
	sort(minterm.begin(), minterm.end(),cmp);
	
	int Mergetime = -1;
	while(Mergetime != 0) // find prime implicant
	{
		Mergetime = 0;
		vector<bool> usedlist(minterm.size(), false);
		for(int i=0;i<minterm.size();i++)
		{
			for(int j=i+1;j<minterm.size();j++)
			{
				int diff = 0;
				string cur = minterm[i];
				for(int index=0;index<n;index++)
				{
					//cout << minterm[i][index] << " vs " << minterm[i][index]
					if(minterm[i][index] != minterm[j][index])
					{
						diff++;
						cur[index] = '-';
					}
					if(diff >= 2) break;
				}
				if(diff == 1) 
				{
					usedlist[i] = usedlist[j]= true;
					//cout << "Merge!!!" << endl;
					//cout << cur << endl;
					Mergetime++;
					temp.push_back(cur);
				}
			}
		}
		for(int check = 0;check < usedlist.size();check++)
		{
			if(usedlist[check] == false)
				res.insert(minterm[check]);	
		}
		//for(auto cur: usedlist) cout << cur << endl;
		//for(auto cur: temp) cout << cur << endl;
		minterm.clear();
		for(auto cur: temp) minterm.push_back(cur);
		temp.clear(); 
	}
	/*
	for(auto it = res.begin();it != res.end();it++)
	{
		cout << *it << endl;
	}
	*/
	vector<vector<bool>> list(res.size(),vector<bool>(table.size(),0));
	int cnt = 0;
	for(auto it=res.begin();it!=res.end();it++,cnt++)
	{
		string cur = *it;
		//cout << "cur: " << cur << "  ";
		vector<int> output;
		generateNumbers(cur, output);
		//for(int i=0;i<output.size();i++) cout << to_string(output[i]) << endl;
		//for(int j=0;j<table.size();j++) cout << table[j] << endl;
		for(int i=0;i<output.size();i++)
		{
			for(int j=0;j<table.size();j++)
			{
				if(to_string(output[i]) == table[j])
				{
					list[cnt][j] = true;
				}
			}
		}
		output.clear();
	}
	/*
	cout << "Before:\n";
	for(int i=0;i<res.size();i++)
	{
	    for(int j=0;j<table.size();j++)
		{
			if(list[i][j])
			{
				cout << "X" << " ";
			}
	        else cout << list[i][j] << " ";
	    }
	    cout << endl;
	}
	*/
	vector<int> spot;
	for(int i=0;i<list[0].size();i++)
	{
		int c=0;
		for(int j=0;j<list.size();j++)
		{
			if(list[j][i] == 1) c++;
		}
		if(c == 1)
		{
			for(int x=0;x<list.size();x++)
			{
				if(list[x][i] == 1) // find the one in the count list
				{
					spot.push_back(x); 
					for(int y=0;y<list[0].size();y++) // delete the column that this one include
					{
						if(list[x][y] == 1) // if included
						{
							for(int reset=0;reset<list.size();reset++)
							{
								if(y != i)
									list[reset][y] = false;
							}
						}
					}
				}
			}
			for(int reset = 0;reset<list.size();reset++) // must be the last one deleted
			{
				list[reset][i] = false;
			}
		}
	}
	
	cout << "Essential Prime Implicant: " << endl;
	if(!spot.empty())
	{
		sort(spot.begin(),spot.end());	
		int x = 0,y = 0;
		vector<string> sortedans;
		for(auto it = res.begin();it != res.end();it++,x++)
		{
			string cur = *it;
			//cout << "x = " << x << ", cur = " << cur << endl;
			if(x == spot[y])
			{
				//cout << "x = " << x << ", getting spot" << endl;
				y++;
				string ans;
				for(int i=0;i<n;i++)
				{
					if(cur[i] != '-')ans+=char('a'+i);//cout << char('a'+i);
					if(cur[i] == '0') ans+="\'";//cout << "\'";
				}
				if (ans.empty()) ans = "1";
				sortedans.push_back(ans);
			}
		}
		sort(sortedans.begin(),sortedans.end(),cmp2);
		for(auto cur: sortedans) cout << cur << ", "[cur == sortedans[sortedans.size()-1]];
		cout << endl;
	}
	else cout << "None" << endl;

	
	
	bool stop = false;
	int round = 1;
	vector<int> spot2;
	while(!stop)
	{
		round++;
		//cout << "Round = " << round << endl;
		//cout << endl;
		int mx = 0;
		for(int i=0;i<list.size();i++) // = res.size()
		{
			int c=0;
			for(int j=0;j<list[0].size();j++)// = table.size()
			{
				if(list[i][j] == 1) c++;
			}
			if(c >= mx)
			{
				mx = max(mx,c);
				if(!spot2.empty()) spot2.pop_back();
				spot2.push_back(i);
			}
		}
		spot.push_back(spot2[0]);
		int i = spot2[spot2.size()-1];
		for(int j=0;j<list[0].size();j++)
		{
			if(list[i][j] == 1)
			{
				list[i][j] = 0;
				for(int x=0;x<list.size();x++)
				{
					list[x][j] = false;
				}
			}
		}
		stop = true;
		
		for(int i=0;i<res.size();i++)
		{
		    for(int j=0;j<table.size();j++)
			{
				if(list[i][j])
				{
					//cout << "X" << " ";
					stop = false;
				}
		        //else cout << list[i][j] << " ";
		    }
		    //cout << endl;
		}
		//cout << endl;
		if(round >= res.size()) stop = true;
		/*
			cout << "CurrentAns: " << endl;
		for(auto cur: spot) cout << cur << endl;
		for(auto cur: spot2) cout << cur << endl;
		*/
	}
	cout << "Ans: " << endl;
	sort(spot.begin(),spot.end());
	//for(auto cur: spot) cout << cur << endl;
	
	int x = 0,y = 0;
	vector<string> sortedans;
	for(auto it = res.begin();it != res.end();it++,x++)
	{
		string cur = *it;
		//cout << "x = " << x << ", cur = " << cur << endl;
		if(x == spot[y])
		{
			//cout << "x = " << x << ", getting spot" << endl;
			y++;
			string ans;
			for(int i=0;i<n;i++)
			{
				if(cur[i] != '-')ans+=char('a'+i);//cout << char('a'+i);
				if(cur[i] == '0') ans+="\'";//cout << "\'";
			}
			if (ans.empty()) ans = "1";
			sortedans.push_back(ans);
		}
	}
	sort(sortedans.begin(),sortedans.end(),cmp2);
	for(auto cur: sortedans) cout << cur << " + "[cur != sortedans[sortedans.size()-1]];
	
	//cout << endl;
	//for(auto cur: dontcare) cout << cur << endl;
}
/*
4
0 1 2 5 6 7 8 9 10 14
Essential Prime Implicant:
b'c',cd'
Ans:
a'bd+b'c'+cd'

3
0 1 2 5 6 7
Essential Prime Implicant:
None
Ans:
ab+ac+a'b'+a'c'(有三項的更簡解，但要使用 Petrick's Method)

4
2 3 7 9 11 13 d 1 10 15
Essential Prime Implicant:
ad,b'c,cd
Ans:
ad+b'c+cd

*/

```