using 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 { 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 termeni = new List(); List termeni2 = new List(); List iPrimi = new List(); ///* 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>> maskStride = new Dictionary>>(); Dictionary> cbitsStride = new Dictionary>(); 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(cbitsStrideStart, cbitsStrideEnd)); cbitsStrideStart = i; cbitsStrideEnd = i; cbitsStrideVal = ti.cbits; } else { cbitsStride.Add(cbitsStrideVal, new KeyValuePair(cbitsStrideStart, cbitsStrideEnd)); cbitsStrideStart = i; cbitsStrideEnd = i; cbitsStrideVal = ti.cbits; maskStride.Add(maskStrideVal, cbitsStride); maskStrideVal = ti.mask; cbitsStride = new Dictionary>(); } } cbitsStride.Add(cbitsStrideVal, new KeyValuePair(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> stride = maskStride[mask]; if (stride.ContainsKey(cbits)) { KeyValuePair 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(); } } }