rendered paste bodyusing System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace QMC
{
class Program
{
class Termen
{
public int var;
public int mask;
public bool prime;
public byte cbits;
public Termen(int var, int mask)
{
this.var = var;
this.mask = mask;
this.prime = true;
while (var > 0)
{
cbits++;
var &= var - 1;
}
}
}
class TermComparer : IComparer<Termen>
{
public int Compare(Termen x, Termen y)
{
int dif;
dif = x.mask - y.mask;
if (dif != 0)
return dif;
dif = x.cbits - y.cbits;
if (dif != 0)
return dif;
return x.var - y.var;
}
}
struct Implicant
{
public int var;
public int mask;
public Implicant(Termen mintermen)
{
this.var = mintermen.var;
this.mask = mintermen.mask;
}
}
static string FormatTerm(int n, int mask)
{
string r1 = Convert.ToString(n, 2).PadLeft(nvar, '0');
string r2 = Convert.ToString(mask, 2).PadLeft(nvar, '0');
string r = "";
for (int i = 0; i < r1.Length; i++)
if (r2[i] == '1')
r += '-';
else
r += r1[i];
return r;
}
static int nvar;
static void Main(string[] args)
{
List<Termen> termeni = new List<Termen>();
List<Termen> termeni2 = new List<Termen>();
List<Implicant> iPrimi = new List<Implicant>();
///*
string[] numbers = File.ReadAllText("qmc.in").Replace("\r\n", " ").Split(' ');
int max = 0;
for (int i = 0; i < numbers.Length; i++)
{
int var;
int.TryParse(numbers[i], out var);
termeni2.Add(new Termen(var, 0));
if (var > max)
max = var;
}
do
{
max >>= 1;
nvar++;
} while (max > 0);
//*/
/*
nvar = 14;
termeni2.Clear();
Random r = new Random();
for (int i = 0; i < 1 << nvar; i++)
//if (r.Next(2) == 1)
termeni2.Add(new Termen(i, 0));
//*/
Dictionary<int, Dictionary<int, KeyValuePair<int, int>>> maskStride = new Dictionary<int, Dictionary<int, KeyValuePair<int, int>>>();
Dictionary<int, KeyValuePair<int, int>> cbitsStride = new Dictionary<int, KeyValuePair<int, int>>();
TermComparer termComparer = new TermComparer();
bool done;
System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();
stopWatch.Start();
do
{
done = true;
termeni.Clear();
termeni2.Sort(termComparer);
if (termeni2.Count > 0)
{
termeni.Add(termeni2[0]);
for (int i = 1; i < termeni2.Count; i++)
if (termeni2[i].var != termeni2[i - 1].var || termeni2[i].mask != termeni2[i - 1].mask)
termeni.Add(termeni2[i]);
termeni2.Clear();
}
maskStride.Clear();
cbitsStride.Clear();
int maskStrideVal = termeni[0].mask;
int cbitsStrideVal = termeni[0].cbits;
int cbitsStrideStart = 0;
int cbitsStrideEnd = 0;
for (int i = 1; i < termeni.Count; i++)
{
Termen ti = termeni[i];
if (ti.mask == maskStrideVal)
if (ti.cbits == cbitsStrideVal)
cbitsStrideEnd++;
else
{
cbitsStride.Add(cbitsStrideVal, new KeyValuePair<int, int>(cbitsStrideStart, cbitsStrideEnd));
cbitsStrideStart = i;
cbitsStrideEnd = i;
cbitsStrideVal = ti.cbits;
}
else
{
cbitsStride.Add(cbitsStrideVal, new KeyValuePair<int, int>(cbitsStrideStart, cbitsStrideEnd));
cbitsStrideStart = i;
cbitsStrideEnd = i;
cbitsStrideVal = ti.cbits;
maskStride.Add(maskStrideVal, cbitsStride);
maskStrideVal = ti.mask;
cbitsStride = new Dictionary<int, KeyValuePair<int, int>>();
}
}
cbitsStride.Add(cbitsStrideVal, new KeyValuePair<int, int>(cbitsStrideStart, cbitsStrideEnd));
maskStride.Add(maskStrideVal, cbitsStride);
for (int i = 0; i < termeni.Count; i++)
{
Termen ti = termeni[i];
int var = ti.var;
int mask = ti.mask;
int cbits = ti.cbits + 1;
Dictionary<int, KeyValuePair<int, int>> stride = maskStride[mask];
if (stride.ContainsKey(cbits))
{
KeyValuePair<int, int> kvp = stride[cbits];
for (int j = kvp.Key; j <= kvp.Value; j++)
{
int dif = var ^ termeni[j].var;
if (dif < 0)
dif = -dif;
if ((dif & (dif - 1)) == 0)
{
dif |= mask;
termeni2.Add(new Termen(var & ~dif, dif));
ti.prime = false;
termeni[j].prime = false;
done = false;
}
}
}
if (ti.prime)
iPrimi.Add(new Implicant(ti));
termeni[i] = null;
}
} while (done == false);
stopWatch.Stop();
Console.WriteLine(stopWatch.ElapsedMilliseconds);
foreach (Implicant implicant in iPrimi)
Console.WriteLine(FormatTerm(implicant.var, implicant.mask));
Console.ReadLine();
}
}
}