Create() public static method

public static Create ( int count, int initialValue ) : int[]
count int
initialValue int
return int[]
Exemplo n.º 1
0
        private State FillInitState(Task task, Random rnd)
        {
            var pizza = task.Pizza;
            var count = rnd.Next(task.Size / task.H / 2, task.Size / task.H);

            var slices = new List <Slice>();
            var map    = ArrayHelper.Create(pizza.Length, _ => ArrayHelper.Create(pizza[0].Length, __ => (long)-1));

            for (var i = 0; i < count; i++)
            {
                while (true)
                {
                    var row = pizza.RandomIndex(rnd);
                    var col = pizza[0].RandomIndex(rnd);
                    if (map[row][col] < 0)
                    {
                        var slice = new Slice(maxSliceId)
                        {
                            Row = row, Col = col, Width = 1, Height = 1
                        };
                        maxSliceId++;
                        slices.Add(slice);
                        map[row][col] = slice.SliceId;
                        break;
                    }
                }
            }

            return(new State
            {
                Map = map,
                Slices = slices,
            });
        }
Exemplo n.º 2
0
        public static int[][] parents3(int[][] g, int root)
        {
            int n = g.Length;

            int[] par = ArrayHelper.Create(n, i => - 1);

            int[] depth = new int[n];
            depth[0] = 0;

            int[] q = new int[n];
            q[0] = root;
            for (int p = 0, r = 1; p < r; p++)
            {
                int cur = q[p];
                foreach (int nex in g[cur])
                {
                    if (par[cur] != nex)
                    {
                        q[r++]     = nex;
                        par[nex]   = cur;
                        depth[nex] = depth[cur] + 1;
                    }
                }
            }
            return(new int[][] { par, q, depth });
        }
Exemplo n.º 3
0
        public void FromFile_CommitFileHasTwoLineBodySeparatedByBlankLineWithCommentInTheMiddle_PopulatesBody()
        {
            const string filePath = "DoesntMatter";
            const string bodyL1   = "BodyLine1";
            const string bodyL2   = "BodyLine2";

            var lines = new[]
            {
                "Subject",
                "",
                bodyL1,
                "# This comment should be ignored",
                "",
                bodyL2
            };

            // Arrange

            var fileSystemMock = new Mock <IFileSystem>();

            fileSystemMock.Setup(fs => fs.FileExists(filePath)).Returns(true);
            fileSystemMock.Setup(fs => fs.ReadAllLines(filePath)).Returns(lines);

            // Act

            var commitFileReader = new CommitFileReader(fileSystemMock.Object);

            var commitDocument = commitFileReader.FromFile(filePath);

            // Assert

            var expectedLines = ArrayHelper.Create(bodyL1, "", bodyL2);

            commitDocument.Body.Should().BeEquivalentTo(expectedLines);
        }
Exemplo n.º 4
0
        public void Performance()
        {
            const int n = 1000;

            var rnd     = new Random(1337);
            var edges   = RandomGenerator.RandomUndirectedGraph_Edges(rnd, n, 2000);
            var weights = RandomGenerator.RandomIntArray(rnd, edges.Length, 1, 10000);

            for (var i = 0; i < edges.Length; i++)
            {
                edges[i] = new[] { edges[i][0] + 1, edges[i][1] + 1, weights[i] }
            }
            ;

            var T = ArrayHelper.Create(n, i => new int[0]);

            var shops = ArrayHelper.Create(n, i => i).Shuffle(rnd).Take(10).ToArray();

            for (var i = 0; i < shops.Length; i++)
            {
                T[shops[i]] = new[] { i + 1 }
            }
            ;

            Console.WriteLine(Solve(T, edges, n, 10));
        }
Exemplo n.º 5
0
        public static void Compare()
        {
            var rnd     = new Random(1337);
            var notzero = 0;

            var Aproto = ArrayHelper.Create(50, i => - 1L);

            for (var t = 0; t < 2000000; t++)
            {
                var len = rnd.Next(1, 5);

                var A = new long[len];
                for (var i = 1; i < A.Length; i++)
                {
                    A[i] = rnd.Next(-1, i + 1);
                }

                var brute  = SolveBrute(A.ToArray());
                var actual = Solve(A);

                if (actual != brute)
                {
                    Console.WriteLine(A.Join());
                    Console.WriteLine(new { t, brute, actual });
                    throw new InvalidOperationException();
                }

                if (brute != 0)
                {
                    notzero++;
                }
            }
            Console.WriteLine("Not zeroes " + notzero);
        }
Exemplo n.º 6
0
 public static void Example1()
 {
     for (var n = 2; n <= 10; n++)
     {
         Console.WriteLine(new { n, ans = SolveBrute(ArrayHelper.Create(n, i => i + 1)).Join() });
     }
 }
Exemplo n.º 7
0
        public static void ShowOneGameStats()
        {
            var maxN = 20;

            var subs = ArrayHelper.Create(100, i => i);

            for (var K = 2; K <= 7; K++)
            {
                if (K == 3)
                {
                    maxN = 90;
                }
                else
                {
                    maxN = 20;
                }

                var gr = new int[maxN + 1];

                for (var n = 2; n <= maxN; n++)
                {
                    var nSubs = ArrayHelper.Slice(subs, 1, n - 1);

                    var next = new HashSet <int>();

                    for (var k = 2; k <= K; k++)
                    {
                        foreach (var comb in new Combinations <int>(nSubs, k, GenerateOption.WithRepetition))
                        {
                            if (comb.Sum() == n)
                            {
                                var xor = 0;
                                foreach (var i in comb)
                                {
                                    xor ^= gr[i];
                                }

                                next.Add(xor);
                            }
                        }
                    }

                    gr[n] = SpragueGrundy(next);
                }

                Console.WriteLine("K = " + K);
                Console.WriteLine(gr.Join());

                if (K == 3)
                {
                    Console.WriteLine("Diff:");
                    Console.WriteLine(gr.Select((g, i) => i == 0 ? 0 : (gr[i] - gr[i - 1])).Join());
                    Console.WriteLine("N - gr");
                    Console.WriteLine(gr.Select((g, i) => i - g).Join());
                }

                Console.WriteLine();
            }
        }
Exemplo n.º 8
0
        public static void ShowData()
        {
            var arr = ArrayHelper.Create(4, i => (long)i);

            foreach (var comb in new Variations <long>(arr, arr.Length, GenerateOption.WithRepetition))
            {
                Console.WriteLine($"{comb.Join()} -> {CalcK_Brute(comb.ToList())}");
            }
        }
Exemplo n.º 9
0
        public static void Performance()
        {
            var rnd = new Random(1337);

            var len = 500000;

            var A = ArrayHelper.Create(len, i => - 1L);

            var timer = Stopwatch.StartNew();

            Console.WriteLine(Solve(A));
            Console.WriteLine("Solve time: " + timer.ElapsedMilliseconds);
        }
Exemplo n.º 10
0
        public static int[][] logstepParents(int[] par)
        {
            int n = par.Length;
            int m = BitHelper.NumberOfTrailingZeros(BitHelper.HighestOneBit(n - 1)) + 1;

            int[][] pars = ArrayHelper.Create <int>(m, n);
            pars[0] = par;
            for (int j = 1; j < m; j++)
            {
                for (int i = 0; i < n; i++)
                {
                    pars[j][i] = pars[j - 1][i] == -1 ? -1 : pars[j - 1][pars[j - 1][i]];
                }
            }
            return(pars);
        }
Exemplo n.º 11
0
        public static byte[,] BaseBinarize(byte[,] grayImage)
        {
            int image_height   = grayImage.GetLength(0);
            int image_width    = grayImage.GetLength(1);
            var integral_image = ArrayHelper.Create <double>(image_height + 1, image_width + 1, -1, -1);
            var integral_sqimg = ArrayHelper.Create <double>(image_height + 1, image_width + 1, -1, -1);

            var result = new byte[image_height, image_width];

            for (int i = 0; i < image_height; i++)
            {
                for (int j = 0; j < image_width; j++)
                {
                    integral_image[i, j] = grayImage[i, j]
                                           + integral_image[i - 1, j] + integral_image[i, j - 1] - integral_image[i - 1, j - 1];;
                    integral_sqimg[i, j] = grayImage[i, j] * grayImage[i, j]
                                           + integral_sqimg[i - 1, j] + integral_sqimg[i, j - 1] - integral_sqimg[i - 1, j - 1];
                }
            }

            var whalf = W / 2;

            for (int i = 0; i < image_height; i++)
            {
                for (int j = 0; j < image_width; j++)
                {
                    var xmin = Math.Max(0, i - whalf);
                    var ymin = Math.Max(0, j - whalf);
                    var xmax = Math.Min(image_height - 1, i + whalf);
                    var ymax = Math.Min(image_width - 1, j + whalf);

                    var area = (xmax - xmin + 1) * (ymax - ymin + 1);

                    var diff   = integral_image[xmax, ymax] - integral_image[xmin - 1, ymax] - integral_image[xmax, ymin - 1] + integral_image[xmin - 1, ymin - 1];
                    var sqdiff = integral_sqimg[xmax, ymax] - integral_sqimg[xmin - 1, ymax] - integral_sqimg[xmax, ymin - 1] + integral_sqimg[xmin - 1, ymin - 1];
                    var mean   = (double)diff / area;
                    var std    = Math.Sqrt((sqdiff - diff * mean) / (area - 1));

                    var threshold = mean * (1 + K * ((std / 128) - 1));

                    result[i, j] = grayImage[i, j] > threshold ? (byte)255 : (byte)0;
                }
            }

            return(result);
        }
Exemplo n.º 12
0
        public static long SolveBrute(long[] X, long[] Y)
        {
            var best = long.MaxValue;

            foreach (var cand in new Permutations <int>(ArrayHelper.Create(X.Length, i => i), GenerateOption.WithoutRepetition))
            {
                var Z = cand.Select(i => Y[i]).ToArray();

                var count = 0L;

                for (var i = 0; i < X.Length; i++)
                {
                    if (X[i] != Z[i])
                    {
                        var op = Z[i] - X[i];

                        count += Math.Abs(op);

                        for (var j = i + 1; j < X.Length; j++)
                        {
                            if (op > 0 && Z[j] < X[j])
                            {
                                op--;
                                Z[j]++;
                                j--;
                            }
                            else if (op < 0 && Z[j] > X[j])
                            {
                                op++;
                                Z[j]--;
                                j--;
                            }

                            if (op == 0)
                            {
                                break;
                            }
                        }
                    }
                }

                best = Math.Min(count, best);
            }

            return(best);
        }
Exemplo n.º 13
0
Arquivo: 7.cs Projeto: qifanyyy/CLCDSA
        public void Compare()
        {
            var rnd = new Random(123);

            for (var t = 0; t < 200; t++)
            {
                var N  = 4;
                var NN = 3;
                var M  = rnd.Next(2, N * N);

                var board = ArrayHelper.Create(N, _ => new string('.', NN).ToCharArray()).ToTwoDimesional();

                for (var i = 0; i < M; i++)
                {
                    board[rnd.Next(0, N), rnd.Next(0, NN)] = "+xo".RandomElement(rnd);
                }
                if (!IsBoardOk(board))
                {
                    continue;
                }

                Console.WriteLine(new { t, N, M });

                var brute = SolveBrute(board.ShallowClone());
                var sol   = Solve(board.ShallowClone());

                if (brute.Score != sol.Score)
                {
                    Console.WriteLine("Original score {0}: ", Score(board));
                    Console.WriteLine(board.ToStringData(""));
                    Console.WriteLine();

                    Console.WriteLine("Brute solution score {0}: ", brute.Score);
                    Console.WriteLine(brute.Board == null ? "no solution" : brute.Board.ToStringData(""));
                    Console.WriteLine();

                    Console.WriteLine("Solve solution score {0}: ", sol.Score);
                    Console.WriteLine(sol.Board.ToStringData(""));
                    Console.WriteLine();

                    Console.WriteLine(new { t });
                    throw new InvalidOperationException();
                }
            }
        }
Exemplo n.º 14
0
Arquivo: 7.cs Projeto: qifanyyy/CLCDSA
        public void Performance()
        {
            var rnd = new Random(123);

            var N = 100;
            var M = rnd.Next(0, N * N);

            var board = ArrayHelper.Create(N, _ => new string('.', N).ToCharArray()).ToTwoDimesional();

            Console.WriteLine("Task: ");
            Console.WriteLine(board.ToStringData(""));

            var sol = Solve(board);

            Console.WriteLine();
            Console.WriteLine("Score: {0}", sol.Score);
            Console.WriteLine(sol.Board.ToStringData(""));
        }
Exemplo n.º 15
0
        public void Start_HasPathArgument_GetsFilesFromThePath()
        {
            const string path = @"C:\SomePath";
            // Arrange

            var fileSystemMock = new Mock <IFileSystem>();
            var consoleMock    = new Mock <IConsoleWrap>();

            // Act

            var appController = new AppController(fileSystemMock.Object, consoleMock.Object);

            appController.Start(ArrayHelper.Create(path));

            // Assert

            fileSystemMock.Verify(fs => fs.GetFiles(path), Times.Once);
        }
Exemplo n.º 16
0
        private void EnsureOk(State state)
        {
            if (!isDebug)
            {
                return;
            }

            var busy = ArrayHelper.Create(state.Map.Length, _ => new bool[state.Map[0].Length]);

            foreach (var slice in state.Slices)
            {
                for (var r = slice.Row; r < slice.Row + slice.Height; r++)
                {
                    for (var c = slice.Col; c < slice.Col + slice.Width; c++)
                    {
                        if (busy[r][c])
                        {
                            throw new InvalidOperationException(new { r, c, slice }.ToString());
                        }
                        busy[r][c] = true;
                        if (state.Map[r][c] != slice.SliceId)
                        {
                            throw new InvalidOperationException(new { r, c, slice }.ToString());
                        }
                    }
                }
            }

            for (var r = 0; r < busy.Length; r++)
            {
                for (var c = 0; c < busy[r].Length; c++)
                {
                    if (!busy[r][c] && state.Map[r][c] >= 0)
                    {
                        throw new InvalidOperationException(new { r, c, sliceId = state.Map[r][c] }.ToString());
                    }
                    else if (busy[r][c] && state.Map[r][c] < 0)
                    {
                        throw new InvalidOperationException(new { r, c, sliceId = state.Map[r][c] }.ToString());
                    }
                }
            }
        }
Exemplo n.º 17
0
        public static void Compare()
        {
            var rnd = new Random(1337);

            for (var n = 2; n <= 10; n++)
            {
                var arr    = ArrayHelper.Create(n, i => i + 1);
                var brute  = SolveBrute(arr);
                var actual = Solve(arr);

                if (!actual.SequenceEqual(brute))
                {
                    Console.WriteLine(brute.Join());
                    Console.WriteLine(actual.Join());
                    Console.WriteLine(new { n });
                    throw new InvalidOperationException();
                }

                Console.WriteLine(n + " ok");
            }
        }
Exemplo n.º 18
0
        // For a 1024 cubed asteroid, it takes approximately 6.5Gb of system memory.

        public static MyVoxelMap ReadModelAsteroidVolmetic(Model3DGroup model, IList <MyMeshModel> mappedMesh, ScaleTransform3D scale, Transform3D rotateTransform, TraceType traceType, TraceCount traceCount, TraceDirection traceDirection,
                                                           Action <double, double> resetProgress, Action incrementProgress, Func <bool> checkCancel, Action complete)
        {
            var traceDirectionCount = 0;
            var materials           = new List <byte>();
            var faceMaterials       = new List <byte>();

            foreach (var mesh in mappedMesh)
            {
                materials.Add(mesh.MaterialIndex ?? SpaceEngineersConsts.EmptyVoxelMaterial);
                faceMaterials.Add(mesh.FaceMaterialIndex ?? SpaceEngineersConsts.EmptyVoxelMaterial);
            }

            // How far to check in from the proposed Volumetric edge.
            // This number is just made up, but small enough that it still represents the corner edge of the Volumetric space.
            // But still large enough that it isn't the exact corner.
            const double offset = 0.0000045f;

            if (scale.ScaleX > 0 && scale.ScaleY > 0 && scale.ScaleZ > 0 && scale.ScaleX != 1.0f && scale.ScaleY != 1.0f && scale.ScaleZ != 1.0f)
            {
                model.TransformScale(scale.ScaleX, scale.ScaleY, scale.ScaleZ);
            }

            // Attempt to offset the model, so it's only caulated from zero (0) and up, instead of using zero (0) as origin.
            //model.Transform = new TranslateTransform3D(-model.Bounds.X, -model.Bounds.Y, -model.Bounds.Z);

            var      tbounds = model.Bounds;
            Matrix3D?rotate  = null;

            if (rotateTransform != null)
            {
                rotate  = rotateTransform.Value;
                tbounds = rotateTransform.TransformBounds(tbounds);
            }

            //model.Transform = new TranslateTransform3D(-tbounds.X, -tbounds.Y, -tbounds.Z);

            // Add 2 to either side, to allow for material padding to expose internal materials.
            const int bufferSize = 2;
            var       xMin       = (int)Math.Floor(tbounds.X) - bufferSize;
            var       yMin       = (int)Math.Floor(tbounds.Y) - bufferSize;
            var       zMin       = (int)Math.Floor(tbounds.Z) - bufferSize;

            var xMax = (int)Math.Ceiling(tbounds.X + tbounds.SizeX) + bufferSize;
            var yMax = (int)Math.Ceiling(tbounds.Y + tbounds.SizeY) + bufferSize;
            var zMax = (int)Math.Ceiling(tbounds.Z + tbounds.SizeZ) + bufferSize;

            // Do not rounnd up the array size, as this really isn't required, and it increases the calculation time.
            var xCount = (xMax - xMin);
            var yCount = (yMax - yMin);
            var zCount = (zMax - zMin);

            Debug.WriteLine("Approximate Size: {0}x{1}x{2}", Math.Ceiling(tbounds.X + tbounds.SizeX) - Math.Floor(tbounds.X), Math.Ceiling(tbounds.Y + tbounds.SizeY) - Math.Floor(tbounds.Y), Math.Ceiling(tbounds.Z + tbounds.SizeZ) - Math.Floor(tbounds.Z));
            Debug.WriteLine("Bounds Size: {0}x{1}x{2}", xCount, yCount, zCount);

            var finalCubic = ArrayHelper.Create <byte>(xCount, yCount, zCount);
            var finalMater = ArrayHelper.Create <byte>(xCount, yCount, zCount);

            if (resetProgress != null)
            {
                long triangles = (from GeometryModel3D gm in model.Children select gm.Geometry as MeshGeometry3D).Aggregate <MeshGeometry3D, long>(0, (current, g) => current + (g.TriangleIndices.Count / 3));
                long rays      = 0;

                if ((traceDirection & TraceDirection.X) == TraceDirection.X)
                {
                    rays += ((yMax - yMin) * (zMax - zMin));
                }
                if ((traceDirection & TraceDirection.Y) == TraceDirection.Y)
                {
                    rays += ((xMax - xMin) * (zMax - zMin));
                }
                if ((traceDirection & TraceDirection.Z) == TraceDirection.Z)
                {
                    rays += ((xMax - xMin) * (yMax - yMin));
                }

                resetProgress.Invoke(0, rays * triangles);
            }

            if (checkCancel != null && checkCancel.Invoke())
            {
                complete?.Invoke();
                return(null);
            }

            #region basic ray trace of every individual triangle.

            // Start from the last mesh, which represents the bottom of the UI stack, and overlay each other mesh on top of it.
            for (var modelIdx = mappedMesh.Count - 1; modelIdx >= 0; modelIdx--)
            {
                Debug.WriteLine("Model {0}", modelIdx);

                var modelCubic = new byte[xCount][][];
                var modelMater = new byte[xCount][][];

                for (var x = 0; x < xCount; x++)
                {
                    modelCubic[x] = new byte[yCount][];
                    modelMater[x] = new byte[yCount][];
                    for (var y = 0; y < yCount; y++)
                    {
                        modelCubic[x][y] = new byte[zCount];
                        modelMater[x][y] = new byte[zCount];
                    }
                }

                var meshes        = mappedMesh[modelIdx];
                var threadCounter = 0;

                var geometries = new GeometeryDetail[meshes.Geometery.Length];
                for (var i = 0; i < meshes.Geometery.Length; i++)
                {
                    geometries[i] = new GeometeryDetail(meshes.Geometery[i]);
                }

                var startOffset              = 0.5f;
                var endOffset                = 0.5f;
                var volumeOffset             = 0.5f;
                Func <double, int> roundFunc = null;
                if (traceType == TraceType.Odd)
                {
                    startOffset  = 0.5f;
                    endOffset    = 0.5f;
                    volumeOffset = 0.5f;
                    roundFunc    = delegate(double d) { return((int)Math.Round(d, 0)); };
                }
                else if (traceType == TraceType.Even)
                {
                    startOffset  = 0.0f;
                    endOffset    = 1.0f;
                    volumeOffset = 1.0f;
                    roundFunc    = delegate(double d) { return((int)Math.Floor(d)); };
                }

                #region X ray trace

                if ((traceDirection & TraceDirection.X) == TraceDirection.X)
                {
                    Debug.WriteLine("X Rays");
                    traceDirectionCount++;
                    threadCounter = (yMax - yMin) * (zMax - zMin);

                    for (var y = yMin; y < yMax; y++)
                    {
                        for (var z = zMin; z < zMax; z++)
                        {
                            if (checkCancel != null && checkCancel.Invoke())
                            {
                                complete?.Invoke();
                                return(null);
                            }

                            List <Point3D[]> testRays = null;
                            if (traceType == TraceType.Odd)
                            {
                                testRays = new List <Point3D[]>
                                {
                                    new [] { new Point3D(xMin, y + offset, z + offset), new Point3D(xMax, y + offset, z + offset) },
                                    new [] { new Point3D(xMin, y - 0.5f + offset, z - 0.5f + offset), new Point3D(xMax, y - 0.5f + offset, z - 0.5f + offset) },
                                    new [] { new Point3D(xMin, y + 0.5f - offset, z - 0.5f + offset), new Point3D(xMax, y + 0.5f - offset, z - 0.5f + offset) },
                                    new [] { new Point3D(xMin, y - 0.5f + offset, z + 0.5f - offset), new Point3D(xMax, y - 0.5f + offset, z + 0.5f - offset) },
                                    new [] { new Point3D(xMin, y + 0.5f - offset, z + 0.5f - offset), new Point3D(xMax, y + 0.5f - offset, z + 0.5f - offset) }
                                }
                            }
                            ;
                            else if (traceType == TraceType.Even)
                            {
                                testRays = new List <Point3D[]>
                                {
                                    new [] { new Point3D(xMin, y + 0.5f - offset, z + 0.5f - offset), new Point3D(xMax, y + 0.5f - offset, z + 0.5f - offset) },
                                    new [] { new Point3D(xMin, y + offset, z + offset), new Point3D(xMax, y + offset, z + offset) },
                                    new [] { new Point3D(xMin, y + 1.0f - offset, z + offset), new Point3D(xMax, y + 1.0f - offset, z + offset) },
                                    new [] { new Point3D(xMin, y + offset, z + 1.0f - offset), new Point3D(xMax, y + offset, z + 1.0f - offset) },
                                    new [] { new Point3D(xMin, y + 1.0f - offset, z + 1.0f - offset), new Point3D(xMax, y + 1.0f - offset, z + 1.0f - offset) }
                                }
                            }
                            ;

                            var task = new Task(obj =>
                            {
                                var bgw     = (RayTracerTaskWorker)obj;
                                var tracers = new List <Trace>();

                                foreach (var geometery in geometries)
                                {
                                    for (var t = 0; t < geometery.Triangles.Length; t += 3)
                                    {
                                        if (checkCancel != null && checkCancel.Invoke())
                                        {
                                            return;
                                        }

                                        if (incrementProgress != null)
                                        {
                                            lock (Locker)
                                            {
                                                incrementProgress.Invoke();
                                            }
                                        }

                                        var p1 = geometery.Positions[geometery.Triangles[t]];
                                        var p2 = geometery.Positions[geometery.Triangles[t + 1]];
                                        var p3 = geometery.Positions[geometery.Triangles[t + 2]];

                                        if (rotate.HasValue)
                                        {
                                            p1 = rotate.Value.Transform(p1);
                                            p2 = rotate.Value.Transform(p2);
                                            p3 = rotate.Value.Transform(p3);
                                        }

                                        foreach (var ray in testRays)
                                        {
                                            if ((p1.Y < ray[0].Y && p2.Y < ray[0].Y && p3.Y < ray[0].Y) ||
                                                (p1.Y > ray[0].Y && p2.Y > ray[0].Y && p3.Y > ray[0].Y) ||
                                                (p1.Z < ray[0].Z && p2.Z < ray[0].Z && p3.Z < ray[0].Z) ||
                                                (p1.Z > ray[0].Z && p2.Z > ray[0].Z && p3.Z > ray[0].Z))
                                            {
                                                continue;
                                            }

                                            Point3D intersect;
                                            int normal;
                                            if (MeshHelper.RayIntersetTriangleRound(p1, p2, p3, ray[0], ray[1], out intersect, out normal))
                                            {
                                                tracers.Add(new Trace(intersect, normal));
                                            }
                                        }
                                    }
                                }

                                if (tracers.Count > 1)
                                {
                                    var order      = tracers.GroupBy(t => new { t.Point, t.Face }).Select(g => g.First()).OrderBy(k => k.Point.X).ToArray();
                                    var startCoord = roundFunc(order[0].Point.X);
                                    var endCoord   = roundFunc(order[order.Length - 1].Point.X);
                                    var surfaces   = 0;

                                    for (var x = startCoord; x <= endCoord; x++)
                                    {
                                        var points = order.Where(p => p.Point.X > x - startOffset && p.Point.X < x + endOffset).ToArray();
                                        var volume = (byte)(0xff / testRays.Count * surfaces);

                                        foreach (var point in points)
                                        {
                                            if (point.Face == MeshFace.Farside)
                                            {
                                                volume += (byte)(Math.Round(Math.Abs(x + volumeOffset - point.Point.X) * 255 / testRays.Count, 0));
                                                surfaces++;
                                            }
                                            else if (point.Face == MeshFace.Nearside)
                                            {
                                                volume -= (byte)(Math.Round(Math.Abs(x + volumeOffset - point.Point.X) * 255 / testRays.Count, 0));
                                                surfaces--;
                                            }
                                        }

                                        // TODO: retest detailed model export.
                                        //volume = volume.RoundUpToNearest(8);

                                        modelCubic[x - xMin][bgw.Y - yMin][bgw.Z - zMin] = volume;
                                        modelMater[x - xMin][bgw.Y - yMin][bgw.Z - zMin] = materials[bgw.ModelIdx];
                                    }

                                    if (faceMaterials[bgw.ModelIdx] != 0xff)
                                    {
                                        for (var i = 1; i < 6; i++)
                                        {
                                            if (xMin < startCoord - i && modelCubic[startCoord - i - xMin][bgw.Y - yMin][bgw.Z - zMin] == 0)
                                            {
                                                modelMater[startCoord - i - xMin][bgw.Y - yMin][bgw.Z - zMin] = faceMaterials[bgw.ModelIdx];
                                            }
                                            if (endCoord + i < xMax && modelCubic[endCoord + i - xMin][bgw.Y - yMin][bgw.Z - zMin] == 0)
                                            {
                                                modelMater[endCoord + i - xMin][bgw.Y - yMin][bgw.Z - zMin] = faceMaterials[bgw.ModelIdx];
                                            }
                                        }
                                    }
                                }

                                lock (Locker)
                                {
                                    threadCounter--;
                                }
                            }, new RayTracerTaskWorker(modelIdx, 0, y, z));

                            task.Start();
                        }
                    }

                    // Wait for Multithread parts to finish.
                    while (threadCounter > 0)
                    {
                        System.Windows.Forms.Application.DoEvents();
                        if (checkCancel != null && checkCancel.Invoke())
                        {
                            break;
                        }
                    }

                    GC.Collect();
                }

                #endregion

                #region Y rays trace

                if ((traceDirection & TraceDirection.Y) == TraceDirection.Y)
                {
                    Debug.WriteLine("Y Rays");
                    traceDirectionCount++;
                    threadCounter = (xMax - xMin) * (zMax - zMin);

                    for (var x = xMin; x < xMax; x++)
                    {
                        for (var z = zMin; z < zMax; z++)
                        {
                            if (checkCancel != null && checkCancel.Invoke())
                            {
                                if (complete != null)
                                {
                                    complete.Invoke();
                                }
                                return(null);
                            }

                            List <Point3D[]> testRays = null;
                            if (traceType == TraceType.Odd)
                            {
                                testRays = new List <Point3D[]>
                                {
                                    new [] { new Point3D(x + offset, yMin, z + offset), new Point3D(x + offset, yMax, z + offset) },
                                    new [] { new Point3D(x - 0.5f + offset, yMin, z - 0.5f + offset), new Point3D(x - 0.5f + offset, yMax, z - 0.5f + offset) },
                                    new [] { new Point3D(x + 0.5f - offset, yMin, z - 0.5f + offset), new Point3D(x + 0.5f - offset, yMax, z - 0.5f + offset) },
                                    new [] { new Point3D(x - 0.5f + offset, yMin, z + 0.5f - offset), new Point3D(x - 0.5f + offset, yMax, z + 0.5f - offset) },
                                    new [] { new Point3D(x + 0.5f - offset, yMin, z + 0.5f - offset), new Point3D(x + 0.5f - offset, yMax, z + 0.5f - offset) }
                                }
                            }
                            ;
                            else if (traceType == TraceType.Even)
                            {
                                testRays = new List <Point3D[]>
                                {
                                    new [] { new Point3D(x + 0.5f - offset, yMin, z + 0.5f - offset), new Point3D(x + 0.5f - offset, yMax, z + 0.5f - offset) },
                                    new [] { new Point3D(x + offset, yMin, z + offset), new Point3D(x + offset, yMax, z + offset) },
                                    new [] { new Point3D(x + 1.0f - offset, yMin, z + offset), new Point3D(x + 1.0f - offset, yMax, z + offset) },
                                    new [] { new Point3D(x + offset, yMin, z + 1.0f - offset), new Point3D(x + offset, yMax, z + 1.0f - offset) },
                                    new [] { new Point3D(x + 1.0f - offset, yMin, z + 1.0f - offset), new Point3D(x + 1.0f - offset, yMax, z + 1.0f - offset) }
                                }
                            }
                            ;

                            var task = new Task(obj =>
                            {
                                var bgw     = (RayTracerTaskWorker)obj;
                                var tracers = new List <Trace>();

                                foreach (var geometery in geometries)
                                {
                                    for (var t = 0; t < geometery.Triangles.Length; t += 3)
                                    {
                                        if (checkCancel != null && checkCancel.Invoke())
                                        {
                                            return;
                                        }

                                        if (incrementProgress != null)
                                        {
                                            lock (Locker)
                                            {
                                                incrementProgress.Invoke();
                                            }
                                        }

                                        var p1 = geometery.Positions[geometery.Triangles[t]];
                                        var p2 = geometery.Positions[geometery.Triangles[t + 1]];
                                        var p3 = geometery.Positions[geometery.Triangles[t + 2]];

                                        if (rotate.HasValue)
                                        {
                                            p1 = rotate.Value.Transform(p1);
                                            p2 = rotate.Value.Transform(p2);
                                            p3 = rotate.Value.Transform(p3);
                                        }

                                        foreach (var ray in testRays)
                                        {
                                            if ((p1.X < ray[0].X && p2.X < ray[0].X && p3.X < ray[0].X) ||
                                                (p1.X > ray[0].X && p2.X > ray[0].X && p3.X > ray[0].X) ||
                                                (p1.Z < ray[0].Z && p2.Z < ray[0].Z && p3.Z < ray[0].Z) ||
                                                (p1.Z > ray[0].Z && p2.Z > ray[0].Z && p3.Z > ray[0].Z))
                                            {
                                                continue;
                                            }

                                            Point3D intersect;
                                            int normal;
                                            if (MeshHelper.RayIntersetTriangleRound(p1, p2, p3, ray[0], ray[1], out intersect, out normal))
                                            {
                                                tracers.Add(new Trace(intersect, normal));
                                            }
                                        }
                                    }
                                }

                                if (tracers.Count > 1)
                                {
                                    var order      = tracers.GroupBy(t => new { t.Point, t.Face }).Select(g => g.First()).OrderBy(k => k.Point.Y).ToArray();
                                    var startCoord = roundFunc(order[0].Point.Y);
                                    var endCoord   = roundFunc(order[order.Length - 1].Point.Y);
                                    var surfaces   = 0;

                                    for (var y = startCoord; y <= endCoord; y++)
                                    {
                                        var points = order.Where(p => p.Point.Y > y - startOffset && p.Point.Y < y + endOffset).ToArray();
                                        var volume = (byte)(0xff / testRays.Count * surfaces);

                                        foreach (var point in points)
                                        {
                                            if (point.Face == MeshFace.Farside)
                                            {
                                                volume += (byte)(Math.Round(Math.Abs(y + volumeOffset - point.Point.Y) * 255 / testRays.Count, 0));
                                                surfaces++;
                                            }
                                            else if (point.Face == MeshFace.Nearside)
                                            {
                                                volume -= (byte)(Math.Round(Math.Abs(y + volumeOffset - point.Point.Y) * 255 / testRays.Count, 0));
                                                surfaces--;
                                            }
                                        }

                                        if (traceDirectionCount > 1)
                                        {
                                            var prevolumme = modelCubic[bgw.X - xMin][y - yMin][bgw.Z - zMin];
                                            if (prevolumme != 0)
                                            {
                                                // average with the pre-existing X volume.
                                                volume = (byte)Math.Round(((float)prevolumme + (float)volume) / (float)traceDirectionCount, 0);
                                            }
                                        }

                                        //volume = volume.RoundUpToNearest(8);

                                        modelCubic[bgw.X - xMin][y - yMin][bgw.Z - zMin] = volume;
                                        modelMater[bgw.X - xMin][y - yMin][bgw.Z - zMin] = materials[bgw.ModelIdx];
                                    }

                                    if (faceMaterials[bgw.ModelIdx] != 0xff)
                                    {
                                        for (var i = 1; i < 6; i++)
                                        {
                                            if (yMin < startCoord - i && modelCubic[bgw.X - xMin][startCoord - i - yMin][bgw.Z - zMin] == 0)
                                            {
                                                modelMater[bgw.X - xMin][startCoord - i - yMin][bgw.Z - zMin] = faceMaterials[bgw.ModelIdx];
                                            }
                                            if (endCoord + i < yMax && modelCubic[bgw.X - xMin][endCoord + i - yMin][bgw.Z - zMin] == 0)
                                            {
                                                modelMater[bgw.X - xMin][endCoord + i - yMin][bgw.Z - zMin] = faceMaterials[bgw.ModelIdx];
                                            }
                                        }
                                    }
                                }

                                lock (Locker)
                                {
                                    threadCounter--;
                                }
                            }, new RayTracerTaskWorker(modelIdx, x, 0, z));

                            task.Start();
                        }
                    }

                    // Wait for Multithread parts to finish.
                    while (threadCounter > 0)
                    {
                        System.Windows.Forms.Application.DoEvents();
                        if (checkCancel != null && checkCancel.Invoke())
                        {
                            break;
                        }
                    }

                    GC.Collect();
                }

                #endregion

                #region Z ray trace

                if ((traceDirection & TraceDirection.Z) == TraceDirection.Z)
                {
                    Debug.WriteLine("Z Rays");
                    traceDirectionCount++;
                    threadCounter = (xMax - xMin) * (yMax - yMin);

                    for (var x = xMin; x < xMax; x++)
                    {
                        for (var y = yMin; y < yMax; y++)
                        {
                            if (checkCancel != null && checkCancel.Invoke())
                            {
                                if (complete != null)
                                {
                                    complete.Invoke();
                                }
                                return(null);
                            }

                            List <Point3D[]> testRays = null;
                            if (traceType == TraceType.Odd)
                            {
                                testRays = new List <Point3D[]>
                                {
                                    new [] { new Point3D(x + offset, y + offset, zMin), new Point3D(x + offset, y + offset, zMax) },
                                    new [] { new Point3D(x - 0.5f + offset, y - 0.5f + offset, zMin), new Point3D(x - 0.5f + offset, y - 0.5f + offset, zMax) },
                                    new [] { new Point3D(x + 0.5f - offset, y - 0.5f + offset, zMin), new Point3D(x + 0.5f - offset, y - 0.5f + offset, zMax) },
                                    new [] { new Point3D(x - 0.5f + offset, y + 0.5f - offset, zMin), new Point3D(x - 0.5f + offset, y + 0.5f - offset, zMax) },
                                    new [] { new Point3D(x + 0.5f - offset, y + 0.5f - offset, zMin), new Point3D(x + 0.5f - offset, y + 0.5f - offset, zMax) }
                                }
                            }
                            ;
                            else if (traceType == TraceType.Even)
                            {
                                testRays = new List <Point3D[]>
                                {
                                    new [] { new Point3D(x + 0.5f - offset, y + 0.5f - offset, zMin), new Point3D(x + 0.5f - offset, y + 0.5f - offset, zMax) },
                                    new [] { new Point3D(x + offset, y + offset, zMin), new Point3D(x + offset, y + offset, zMax) },
                                    new [] { new Point3D(x + 1.0f - offset, y + offset, zMin), new Point3D(x + 1.0f - offset, y + offset, zMax) },
                                    new [] { new Point3D(x + offset, y + 1.0f - offset, zMin), new Point3D(x + offset, y + 1.0f - offset, zMax) },
                                    new [] { new Point3D(x + 1.0f - offset, y + 1.0f - offset, zMin), new Point3D(x + 1.0f - offset, y + 1.0f - offset, zMax) }
                                }
                            }
                            ;

                            var task = new Task(obj =>
                            {
                                var bgw     = (RayTracerTaskWorker)obj;
                                var tracers = new List <Trace>();

                                foreach (var geometery in geometries)
                                {
                                    for (var t = 0; t < geometery.Triangles.Length; t += 3)
                                    {
                                        if (checkCancel != null && checkCancel.Invoke())
                                        {
                                            return;
                                        }

                                        if (incrementProgress != null)
                                        {
                                            lock (Locker)
                                            {
                                                incrementProgress.Invoke();
                                            }
                                        }

                                        var p1 = geometery.Positions[geometery.Triangles[t]];
                                        var p2 = geometery.Positions[geometery.Triangles[t + 1]];
                                        var p3 = geometery.Positions[geometery.Triangles[t + 2]];

                                        if (rotate.HasValue)
                                        {
                                            p1 = rotate.Value.Transform(p1);
                                            p2 = rotate.Value.Transform(p2);
                                            p3 = rotate.Value.Transform(p3);
                                        }

                                        foreach (var ray in testRays)
                                        {
                                            if ((p1.X < ray[0].X && p2.X < ray[0].X && p3.X < ray[0].X) ||
                                                (p1.X > ray[0].X && p2.X > ray[0].X && p3.X > ray[0].X) ||
                                                (p1.Y < ray[0].Y && p2.Y < ray[0].Y && p3.Y < ray[0].Y) ||
                                                (p1.Y > ray[0].Y && p2.Y > ray[0].Y && p3.Y > ray[0].Y))
                                            {
                                                continue;
                                            }

                                            Point3D intersect;
                                            int normal;
                                            if (MeshHelper.RayIntersetTriangleRound(p1, p2, p3, ray[0], ray[1], out intersect, out normal))
                                            {
                                                tracers.Add(new Trace(intersect, normal));
                                            }
                                        }
                                    }
                                }

                                if (tracers.Count > 1)
                                {
                                    var order      = tracers.GroupBy(t => new { t.Point, t.Face }).Select(g => g.First()).OrderBy(k => k.Point.Z).ToArray();
                                    var startCoord = roundFunc(order[0].Point.Z);
                                    var endCoord   = roundFunc(order[order.Length - 1].Point.Z);
                                    var surfaces   = 0;

                                    for (var z = startCoord; z <= endCoord; z++)
                                    {
                                        var points = order.Where(p => p.Point.Z > z - startOffset && p.Point.Z < z + endOffset).ToArray();
                                        var volume = (byte)(0xff / testRays.Count * surfaces);

                                        foreach (var point in points)
                                        {
                                            if (point.Face == MeshFace.Farside)
                                            {
                                                volume += (byte)(Math.Round(Math.Abs(z + volumeOffset - point.Point.Z) * 255 / testRays.Count, 0));
                                                surfaces++;
                                            }
                                            else if (point.Face == MeshFace.Nearside)
                                            {
                                                volume -= (byte)(Math.Round(Math.Abs(z + volumeOffset - point.Point.Z) * 255 / testRays.Count, 0));
                                                surfaces--;
                                            }
                                        }

                                        if (traceDirectionCount > 1)
                                        {
                                            var prevolumme = modelCubic[bgw.X - xMin][bgw.Y - yMin][z - zMin];
                                            if (prevolumme != 0)
                                            {
                                                // average with the pre-existing X and Y volumes.
                                                volume = (byte)Math.Round((((float)prevolumme * (traceDirectionCount - 1)) + (float)volume) / (float)traceDirectionCount, 0);
                                            }
                                        }

                                        //volume = volume.RoundUpToNearest(8);

                                        modelCubic[bgw.X - xMin][bgw.Y - yMin][z - zMin] = volume;
                                        modelMater[bgw.X - xMin][bgw.Y - yMin][z - zMin] = materials[bgw.ModelIdx];
                                    }

                                    if (faceMaterials[bgw.ModelIdx] != 0xff)
                                    {
                                        for (var i = 1; i < 6; i++)
                                        {
                                            if (zMin < startCoord - i && modelCubic[bgw.X - xMin][bgw.Y - yMin][startCoord - i - zMin] == 0)
                                            {
                                                modelMater[bgw.X - xMin][bgw.Y - yMin][startCoord - i - zMin] = faceMaterials[bgw.ModelIdx];
                                            }
                                            if (endCoord + i < zMax && modelCubic[bgw.X - xMin][bgw.Y - yMin][endCoord + i - zMin] == 0)
                                            {
                                                modelMater[bgw.X - xMin][bgw.Y - yMin][endCoord + i - zMin] = faceMaterials[bgw.ModelIdx];
                                            }
                                        }
                                    }
                                }

                                lock (Locker)
                                {
                                    threadCounter--;
                                }
                            }, new RayTracerTaskWorker(modelIdx, x, y, 0));

                            task.Start();
                        }
                    }

                    // Wait for Multithread parts to finish.
                    while (threadCounter > 0)
                    {
                        System.Windows.Forms.Application.DoEvents();
                        if (checkCancel != null && checkCancel.Invoke())
                        {
                            break;
                        }
                    }

                    GC.Collect();
                }

                #endregion

                if (checkCancel != null && checkCancel.Invoke())
                {
                    complete?.Invoke();
                    return(null);
                }

                #region merge individual model results into final

                for (var x = 0; x < xCount; x++)
                {
                    for (var y = 0; y < yCount; y++)
                    {
                        for (var z = 0; z < zCount; z++)
                        {
                            if (modelMater[x][y][z] == 0xff && modelCubic[x][y][z] != 0)
                            {
                                finalCubic[x][y][z] = (byte)Math.Max(finalCubic[x][y][z] - modelCubic[x][y][z], 0);
                            }
                            else if (modelCubic[x][y][z] != 0)
                            {
                                finalCubic[x][y][z] = Math.Max(finalCubic[x][y][z], modelCubic[x][y][z]);
                                finalMater[x][y][z] = modelMater[x][y][z];
                            }
                            else if (finalCubic[x][y][z] == 0 && finalMater[x][y][z] == 0 && modelMater[x][y][z] != 0xff)
                            {
                                finalMater[x][y][z] = modelMater[x][y][z];
                            }
                        }
                    }
                }

                #endregion
            } // end models

            #endregion

            if (checkCancel != null && checkCancel.Invoke())
            {
                complete?.Invoke();
                return(null);
            }

            var size = new Vector3I(xCount, yCount, zCount);
            // TODO: at the moment the Mesh list is not complete, so the faceMaterial setting is kind of vague.
            var defaultMaterial = mappedMesh[0].MaterialIndex;     // Use the FaceMaterial from the first Mesh in the object list.
            var faceMaterial    = mappedMesh[0].FaceMaterialIndex; // Use the FaceMaterial from the first Mesh in the object list.

            var action = (Action <MyVoxelBuilderArgs>) delegate(MyVoxelBuilderArgs e)
            {
                // center the finalCubic structure within the voxel Volume.
                Vector3I pointOffset = (e.Size - size) / 2;

                // the model is only shaped according to its volume, not the voxel which is cubic.
                if (e.CoordinatePoint.X >= pointOffset.X && e.CoordinatePoint.X < pointOffset.X + xCount &&
                    e.CoordinatePoint.Y >= pointOffset.Y && e.CoordinatePoint.Y < pointOffset.Y + yCount &&
                    e.CoordinatePoint.Z >= pointOffset.Z && e.CoordinatePoint.Z < pointOffset.Z + zCount)
                {
                    e.Volume        = finalCubic[e.CoordinatePoint.X - pointOffset.X][e.CoordinatePoint.Y - pointOffset.Y][e.CoordinatePoint.Z - pointOffset.Z];
                    e.MaterialIndex = finalMater[e.CoordinatePoint.X - pointOffset.X][e.CoordinatePoint.Y - pointOffset.Y][e.CoordinatePoint.Z - pointOffset.Z];
                }
            };

            var voxelMap = MyVoxelBuilder.BuildAsteroid(true, size, defaultMaterial.Value, faceMaterial, action);

            complete?.Invoke();

            return(voxelMap);
        }
Exemplo n.º 19
0
        public static long Solve(int[][] T, int[][] edges, int n, int K)
        {
            var adjEdges = ToAdjacencyList_UnDirected_WithWeights(edges, n + 1);

            var maskSize = 1 << K;

            var stats = ArrayHelper.Create(n + 1, i => ArrayHelper.Create(maskSize, j => long.MaxValue));

            stats[1][CalcMask(T[0])] = 0;

            var nodeMasks = ArrayHelper.Create(n + 1, i => i == 0 ? 0u : CalcMask(T[i - 1]));

            var queue = new Queue <int>();

            queue.Enqueue(1);

            while (queue.Count > 0)
            {
                var node = queue.Dequeue();

                foreach (var nodeEdge in adjEdges[node])
                {
                    var nextNode = nodeEdge[1];
                    var weight   = nodeEdge[2];

                    var nextNodeMask = nodeMasks[nextNode];

                    var doExplore = false;
                    for (var mask = 0u; mask < maskSize; mask++)
                    {
                        if (stats[node][mask] < long.MaxValue)
                        {
                            if (stats[nextNode][mask | nextNodeMask] > stats[node][mask] + weight)
                            {
                                stats[nextNode][mask | nextNodeMask] = stats[node][mask] + weight;
                                doExplore = true;
                            }
                        }
                    }

                    if (doExplore)
                    {
                        queue.Enqueue(nextNode);
                    }
                }
            }

            {
                var nStats = stats[n];
                var best   = long.MaxValue;
                var full   = maskSize - 1;
                for (var i = 0; i < nStats.Length; i++)
                {
                    if (i == full)
                    {
                        best = Math.Min(best, nStats[i]);
                    }

                    for (var j = i + 1; j < nStats.Length; j++)
                    {
                        if ((i | j) == full)
                        {
                            best = Math.Min(best, Math.Max(nStats[i], nStats[j]));
                        }
                    }
                }

                return(best);
            }
        }
Exemplo n.º 20
0
        public static long Solve_Bad(int[][] T, int[][] edges, int n, int K)
        {
            var adjEdges = ToAdjacencyList_UnDirected_WithWeights(edges, n + 1);

            var maskSize = 1 << K;

            var stats = ArrayHelper.Create(n + 1, i => ArrayHelper.Create(maskSize, j => long.MaxValue));

            stats[1][CalcMask(T[0])] = 0;

            var visited = new bool[n + 1];

            visited[1] = true;

            var visitedMask = CalcMask(T[0]);

            var front = new Queue <int>();

            foreach (var edge in adjEdges[1])
            {
                if (!visited[edge[1]])
                {
                    front.Enqueue(edge[1]);
                }
            }

            while (front.Count > 0)
            {
                var x = front.Dequeue();
                if (visited[x])
                {
                    continue;
                }

                var xMask = CalcMask(T[x - 1]);

                foreach (var xEdge in adjEdges[x])
                {
                    var a = xEdge[1];
                    var w = xEdge[2];

                    if (!visited[a])
                    {
                        front.Enqueue(a);
                    }
                    else
                    {
                        if (!visited[x])
                        {
                            visited[x] = true;

                            for (var mask = 0u; mask < maskSize; mask++)
                            {
                                if (stats[a][mask] < long.MaxValue)
                                {
                                    stats[x][mask | xMask] = Math.Min(stats[x][mask | xMask], stats[a][mask] + w);
                                }
                            }

                            if ((xMask & visitedMask) > 0)
                            {
                                // В X есть новый тип
                            }

                            visitedMask |= xMask;
                        }
                        else
                        {
                        }
                    }
                }
            }

            {
                var nStats = stats[n];
                var best   = long.MaxValue;
                var full   = maskSize - 1;
                for (var i = 0; i < nStats.Length; i++)
                {
                    for (var j = i + 1; j < nStats.Length; j++)
                    {
                        if ((i | j) == full)
                        {
                            best = Math.Min(best, Math.Max(nStats[i], nStats[j]));
                        }
                    }
                }

                return(best);
            }
        }
Exemplo n.º 21
0
        public int[] Solve(int n, int e, List <int>[] adj, int domainSize)
        {
            var solution = ArrayHelper.Create(n, _ => - 1);

            var allColors = ArrayHelper.Create(domainSize, i => i);
            var domains   = ArrayHelper.Create(n, _ => allColors.ToHashSet());

            var decisions = new Stack <Decision>();

            while (true)
            {
                var v = solution.FirstIndexOf(_ => _ < 0);
                if (v < 0)
                {
                    break;
                }

                var doBacktrack = false;

                if (domains[v].Count == 0)
                {
                    doBacktrack = true;
                }
                else
                {
                    var color = domains[v].First();

                    var neighboorsAffected = new List <int>();

                    foreach (var neighboor in adj[v])
                    {
                        if (solution[neighboor] == color)
                        {
                            doBacktrack = true;
                            break;
                        }
                        else if (solution[neighboor] < 0 && domains[neighboor].Contains(color))
                        {
                            neighboorsAffected.Add(neighboor);
                        }
                    }

                    if (!doBacktrack)
                    {
                        solution[v] = color;
                        foreach (var neighboor in neighboorsAffected)
                        {
                            domains[neighboor].Remove(color);
                        }

                        decisions.Push(new Decision
                        {
                            Node  = v,
                            Color = color,
                            NeighboorsAffected = neighboorsAffected
                        });
                    }
                }

                if (doBacktrack)
                {
                    var decision = decisions.Pop();
                    solution[decision.Node] = -1;
                    foreach (var neighboor in decision.NeighboorsAffected)
                    {
                        domains[neighboor].Add(decision.Color);
                    }
                }
            }

            return(solution);
        }
Exemplo n.º 22
0
Arquivo: 7.cs Projeto: qifanyyy/CLCDSA
        public IEnumerable <string> SolveFullTask(string[] lines)
        {
            var result = new List <string>();

            var line = 0;
            var T    = int.Parse(lines[line++]);

            for (var t = 0; t < T; t++)
            {
                var NM = lines[line++].Split();
                var N  = int.Parse(NM[0]);
                var M  = int.Parse(NM[1]);

                var board = ArrayHelper.Create(N, N, (i, j) => '.').ToTwoDimesional();

                for (var i = 0; i < M; i++)
                {
                    var code = lines[line++].Split();
                    board[int.Parse(code[1]) - 1, int.Parse(code[2]) - 1] = code[0][0];
                }

                var sol = Solve(board.ShallowClone());

                var changes = new List <string>();

                foreach (var point in board.ToPoints())
                {
                    if (board.Get(point) != sol.Board.Get(point))
                    {
                        changes.Add($"{sol.Board.Get(point)} {point.X + 1} {point.Y + 1}");
                    }
                }

                result.Add($"Case #{t + 1}: {sol.Score} {changes.Count}");
                result.AddRange(changes);

                {
                    var checkBoard = board.ShallowClone();
                    foreach (var change in changes)
                    {
                        var code   = change.Split();
                        var r      = int.Parse(code[1]) - 1;
                        var c      = int.Parse(code[2]) - 1;
                        var after  = code[0][0];
                        var before = checkBoard[r, c];
                        checkBoard[r, c] = after;

                        var isOk = (before == '.' && (after == 'x' || after == '+' || after == 'o')) ||
                                   (before == 'x' && after == 'o') ||
                                   (before == '+' && after == 'o');

                        if (!isOk)
                        {
                            throw new InvalidOperationException();
                        }
                    }
                    if (!IsBoardOk(checkBoard) || Score(checkBoard) != sol.Score)
                    {
                        throw new InvalidOperationException();
                    }
                }
            }

            return(result);
        }
Exemplo n.º 23
0
        public static IEnumerable <string> Solve_HZ2(int n, int m, string[] commands)
        {
            var setsCount = 1 << n;

            var bits = new int[n];

            for (var i = 0; i < bits.Length; i++)
            {
                bits[i] = 1 << i;
            }

            var graphPar = new List <int> [setsCount];

            for (var i = 0; i < graphPar.Length; i++)
            {
                var list = new List <int>();
                foreach (var b in bits)
                {
                    if ((i & b) == 0)
                    {
                        list.Add(i | b);
                    }
                }
                graphPar[i] = list;
            }

            var sets      = new ulong[setsCount];
            var setsTimes = ArrayHelper.Create(setsCount, i => - 1);
            var xors      = new ulong[setsCount];
            var xorsTimes = ArrayHelper.Create(setsCount, i => - 1);
            var visited   = new bool[setsCount];

            for (var time = 0; time < commands.Length; time++)
            {
                var command = commands[time];

                var type = command[0];

                var si1 = 1;
                var si2 = command.LastIndexOf(' ');

                var x     = si1 == si2 ? 0ul : ulong.Parse(command.Substring(si1 + 1, si2 - si1 - 1));
                var S     = command.Substring(si2 + 1);
                var smask = GetMask(S);

                if (type == '1')
                {
                    sets[smask]      = x;
                    setsTimes[smask] = time;
                    xors[smask]      = 0;
                    xorsTimes[smask] = -1;
                }
                else if (type == '2')
                {
                    xors[smask]     ^= x;
                    xorsTimes[smask] = time;
                }
                else if (type == '3')
                {
                    var lastTime = -1;
                    var value    = 0ul;

                    Array.Clear(visited, 0, visited.Length);
                    var queue = new Queue <int>();
                    queue.Enqueue(smask);
                    while (queue.Count > 0)
                    {
                        var node = queue.Dequeue();
                        if (setsTimes[node] > lastTime)
                        {
                            lastTime = setsTimes[node];
                            value    = sets[node];
                        }
                        foreach (var par in graphPar[node])
                        {
                            if (!visited[par])
                            {
                                queue.Enqueue(par);
                                visited[par] = true;
                            }
                        }
                    }

                    Array.Clear(visited, 0, visited.Length);
                    queue.Enqueue(smask);
                    while (queue.Count > 0)
                    {
                        var node = queue.Dequeue();
                        if (xors[node] > 0 && xorsTimes[node] > lastTime)
                        {
                            value ^= xors[node];
                        }
                        foreach (var par in graphPar[node])
                        {
                            if (!visited[par])
                            {
                                queue.Enqueue(par);
                                visited[par] = true;
                            }
                        }
                    }

                    yield return(value.ToString());
                }
            }
        }
Exemplo n.º 24
0
        public static IEnumerable <string> Solve_HZ(int n, int m, string[] commands)
        {
            var setsCount     = 1 << n;
            var trueBitsCount = n / 2;

            var bits = new int[n];

            for (var i = 0; i < bits.Length; i++)
            {
                bits[i] = 1 << i;
            }

            var graphSub = new List <int> [setsCount];

            for (var i = 0; i < graphSub.Length; i++)
            {
                var list = new List <int>();
                foreach (var b in bits)
                {
                    if ((i & b) > 0)
                    {
                        list.Add(i & ~b);
                    }
                }
                graphSub[i] = list;
            }

            var bitsCount = new int[setsCount];

            // TODO: build by graphSub
            var graphPar = new List <int> [setsCount];

            for (var i = 0; i < graphPar.Length; i++)
            {
                var list = new List <int>();
                foreach (var b in bits)
                {
                    if ((i & b) == 0)
                    {
                        list.Add(i | b);
                        bitsCount[i | b] = bitsCount[i] + 1;
                    }
                }
                graphPar[i] = list;
            }

            var sets      = new ulong[setsCount];
            var setsTimes = ArrayHelper.Create(setsCount, i => - 1);
            var xors      = new ulong[setsCount];
            var xorsTimes = ArrayHelper.Create(setsCount, i => - 1);

            var trueMasks = new List <int>();

            for (var i = 0; i < bitsCount.Length; i++)
            {
                if (bitsCount[i] == trueBitsCount)
                {
                    trueMasks.Add(i);
                }
            }

            for (var time = 0; time < commands.Length; time++)
            {
                var command = commands[time];

                var type = command[0];

                var si1 = 1;
                var si2 = command.LastIndexOf(' ');

                var x     = si1 == si2 ? 0ul : ulong.Parse(command.Substring(si1 + 1, si2 - si1 - 1));
                var S     = command.Substring(si2 + 1);
                var smask = GetMask(S);

                if (type == '1')
                {
                    //var i = setsCount / 2 + 1; TODO!

                    var queue = new Queue <int>();
                    queue.Enqueue(smask);

                    while (queue.Count > 0)
                    {
                        var node = queue.Dequeue();

                        if (setsTimes[node] == time)
                        {
                            continue;
                        }

                        sets[node]      = x;
                        setsTimes[node] = time;
                        xors[node]      = 0;
                        xorsTimes[node] = -1;

                        if (bitsCount[node] > trueBitsCount)
                        {
                            foreach (var child in graphSub[node])
                            {
                                queue.Enqueue(child);
                            }
                        }
                    }
                }
                else if (type == '2')
                {
                    //var i = setsCount / 2 + 1; TODO!

                    var queue = new Queue <int>();
                    queue.Enqueue(smask);

                    while (queue.Count > 0)
                    {
                        var node = queue.Dequeue();

                        if (xorsTimes[node] == time)
                        {
                            continue;
                        }

                        xors[node]     ^= x;
                        xorsTimes[node] = time;

                        if (bitsCount[node] > trueBitsCount)
                        {
                            foreach (var child in graphSub[node])
                            {
                                queue.Enqueue(child);
                            }
                        }
                    }
                }
                else if (type == '3')
                {
                    if (bitsCount[smask] >= trueBitsCount)
                    {
                        var result = setsTimes[smask] <= xorsTimes[smask] ? (sets[smask] ^ xors[smask]) : sets[smask];
                        yield return(result.ToString());
                    }
                    else
                    {
                        var parents = new HashSet <int>(trueMasks);
                        while (parents.Count > 0)
                        {
                            var changeme = new HashSet <int>();
                            foreach (var parent in parents)
                            {
                                foreach (var child in graphSub[parent])
                                {
                                    changeme.Add(child);
                                }
                            }

                            foreach (var node in changeme)
                            {
                                var lastTime = Math.Max(setsTimes[node], graphPar[node].Max(p => setsTimes[p]));

                                foreach (var p in graphPar[node])
                                {
                                    if (setsTimes[p] > setsTimes[node])
                                    {
                                        sets[node]      = sets[p];
                                        setsTimes[node] = setsTimes[p];

                                        if (xorsTimes[p] > xorsTimes[node])
                                        {
                                            xors[node]      = 0;
                                            xorsTimes[node] = -1;
                                        }
                                    }

                                    if (xors[p] > 0 && xorsTimes[p] > setsTimes[node])
                                    {
                                        xors[node]     ^= xors[p];
                                        xorsTimes[node] = xorsTimes[p];
                                    }
                                }

                                if (node == smask)
                                {
                                    changeme.Clear();
                                    break;
                                }
                            }

                            parents = changeme;
                        }

                        var result = setsTimes[smask] <= xorsTimes[smask] ? (sets[smask] ^ xors[smask]) : sets[smask];
                        yield return(result.ToString());
                    }
                }
            }
        }