简体   繁体   中英

Method to guess possible combination

For practice I want to write a program that will guess random positions of x and y. For example the first point would be

int x = 0;
int y = 0;

x += rand.Next(0, 4);
y += rand.Next(0, 4);

Then from that random point I will add the another random value to x and y to have a second point. However I want to go back to find those points randomly.

To make the points:

int x = 0;
int y = 0;
List<Point> points = new List<Point>();

for (int i = 0; i < numberOfPointsWanted; i++)
{
    x += rand.Next(0, 4);
    y += rand.Next(0, 4);
    points.Add(new Point(x, y));
}

Now I wish to guess those random points almost as if I did not have them stored in a list. Because each new point relies on its predecessor I assume some sort of recursion would be necessary. Almost like a brute force guessing application that will find those points. I am having trouble completing the method that would be able to guess every possible point given a number of desired points.

This is what I have thus far to find the rounds:

class Program
{
        static int nRounds = 2;
        static Point[] points = new Point[nRounds];
        static Point[] test = { new Point(1, 2), new Point(4, 1) };

        static bool CheckArray()
        {
            for (int i = 0; i < points.Length; i++)
                if (points[i] != test[i]) { return false; }

            return true;
        }

        static void PrintArray()
        {
            for (int i = 0; i < points.Length; i++)
                Console.Write("[" + tCount + "]\t" + points[i].X + " : " + points[i].Y + "\t");

            Console.Write("\n");
        }

        static int tCount = 0;
        static int rCount = 0;
        static void GetRounds(int inX, int inY)
        {
            for (int x = inX; x < 5; x++)
            {
                for (int y = inY; y < 5; y++)
                {
                    if (rCount < nRounds)
                    {
                        tCount++;
                        points[rCount] = new Point(x, y);
                        rCount++;
                        GetRounds(x, y);
                        if (CheckArray())
                        {
                            PrintArray();
                            return;
                        }
                        PrintArray();

                    }            
                }
            }
            rCount--;
        }

        static void Main(string[] args)
        {
            GetRounds(0, 0);
            Console.ReadKey();
        }
    }
}

I am trying to randomly generate points as shown above and then guess them based on a hashed value representing all of those points together.

This is what im expecting to see:

If only guessing two points

Point one :: Point two x and y respectively

x y :: x y
0 0 :: 0 1
0 0 :: 0 2
0 0 :: 0 3
0 0 :: 1 0
0 0 :: 1 1
0 0 :: 1 2
0 0 :: 1 3
0 0 :: 2 0
0 0 :: 2 1
0 0 :: 2 2
0 0 :: 2 3
0 0 :: 3 0
0 0 :: 3 1
0 0 :: 3 2
0 0 :: 3 3
0 1 :: 0 0
0 1 :: 0 1
0 1 :: 0 2

And so on until all possibilities of point one and point two are guessed

I'm not sure if this is exactly what you're looking for, but one way to get all those combinations is to use nested for loops:

for (int ax = 0; ax < 4; ax++)
{
    for (int ay = 0; ay < 4; ay++)
    {
        var pointA = new Point(ax, ay);

        for (int bx = 0; bx < 4; bx++)
        {
            for (int by = 0; by < 4; by++)
            {                    
                var pointB = new Point(bx, by);

                Console.WriteLine($"{pointA.X} {pointA.Y} :: {pointB.X} {pointB.Y}");
            }
        }
    }
}

Output

在此处输入图片说明


You were asking about a solution that would allow a variable number of points to be passed in. This is fairly simple to do - you just keep a List<List<Point>> of the results, and on each iteration you generate a list of possible point values (16 possible values when min is 0 and max is 3), and then generate a new list for every item in the existing results for each Point in the new set.

The problem is the size of the result set. Since a single point has 16 possible combinations of X and Y if we have a min value of 0 and a max value of 3, then for each additional point, we raise 16 to that power. So for 10 points, there are over a billion combinations.

private static List<List<Point>> GetAllCombinations(int min, int max, int count)
{
    var results = new List<List<Point>>();

    for (int i = 0; i < count; i++)
    {
        var thisSet = new List<Point>();

        for (int x = min; x <= max; x++)
        {
            for (int y = min; y <= max; y++)
            {
                thisSet.Add(new Point(x, y));
            }
        }

        // If this is our first time through, we just add each point
        // as a single-item list to our results
        if (results.Count == 0)
        {
            foreach (var item in thisSet)
            {
                results.Add(new List<Point> {item});
            }
        }
        // On subsequent iterations, for each list in our results, and
        // for each item in this set, we create a new list for each item,
        // adding to it a copy of the existing result list. We clear
        // the results in the beginning (after making a copy) and then
        // add each new list to it in the inner loop.
        else
        {
            // Make a copy of our existing results and clear the original list
            var tempResults = results.ToList();
            results.Clear();

            foreach (var existingItem in tempResults)
            {
                foreach (var newPoint in thisSet)
                {
                    // Now we populate our results again with a new set of 
                    // lists for each existingItem and each newPoint
                    var newItem = existingItem.ToList();
                    newItem.Add(newPoint);
                    results.Add(newItem);
                }
            }
        }
    }

    return results;
}

Example usage:

private static void Main()
{
    var results = GetAllCombinations(0, 3, 5);

    foreach (var result in results)
    {
        Console.WriteLine(string.Join(" :: ", result.Select(p => $"{p.X} {p.Y}")));
    }

    Console.WriteLine("With a min value of 0 and max value of 3, " +
                        $"5 points generated {results.Count} results.");

    GetKeyFromUser("Done! Press any key to exit...");
}

Output

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM