All pastes #274119 Raw Edit

GrayShade

public text v1 · immutable
·published 2006-12-10 13:10 UTC
rendered paste body
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<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();
		}
	}
}