简体   繁体   中英

Program to guess number gets incredibly slow

So, I decided to have some fun and make a program that will come up with a number and you have to guess it with it telling you if you're too high/too low. However, I decided it would be more fun if the computer could come up with the random numbers itself.

I use a simple method here which basically has the program check if a value is in an array , and if it is, come up with another random number. And when a number is too high, start from the size of how large the number can be and go down to that number (that way if it's too high of a number, it never guesses that high or higher again).

So, this works great for small numbers. I think when doing a number like 1,000 or something, it guessed it within 15 tries. However, when I did a 10,000,000 (I know, it's a bit extreme, but I wanted to see C#'s power since I'm fairly new to the language).

The program got about 10 guesses in and it started slowing down incredibly. I had put in a 250ms sleep timer to make it look more like it was guessing (since it is instant for things like 1,000 or 10,000), but when taking it out, it still slowed down. I think this is probably because if it guesses a number like 3 million, it has to add 7 million values to an array (I'm using a List so that it has an "infinite" value).

So what exactly can I do at this point? I want it to be able guess big numbers, but it doesn't really seem possible at this point. How could I do this?

Here's my code:

using System;
using System.Collections.Generic;
using System.Linq;

namespace Program {
    class Program {
        static void Main(string[] args) {
            Random random = new Random();
            int selectedNumber = random.Next(1, 101);
            int maxNumber;
            int guessNumber = 0;
            int inputNumber = 0;
            // Intro
            Console.ForegroundColor = ConsoleColor.DarkGreen;
            Console.WriteLine("Welcome to the High Low - Computer version program!");
            System.Threading.Thread.Sleep(4000);
            Console.WriteLine("\n--------------------------------------------------------");
            Console.ForegroundColor = ConsoleColor.DarkYellow;
            // This way the computer guesses rather than you
            char who = 'C';
            Console.Write("\nHow high do you want the computer's number to be max > ");
            maxNumber = Convert.ToInt32(Console.ReadLine());
            List<int> guessedNumbers = new List<int>();
            selectedNumber = random.Next(1, maxNumber);
            do {
                // System.Threading.Thread.Sleep(250);
                Console.ForegroundColor = ConsoleColor.DarkYellow;
                if (who == 'M') {
                    Console.Write("\nPlease enter your guess > ");
                    guessNumber = Convert.ToInt32(Console.ReadLine());
                }
                else {
                    while (true) {
                        guessNumber = random.Next(1, maxNumber);
                        if (!(guessedNumbers.Contains(guessNumber))) {
                            guessedNumbers.Add(guessNumber);
                            inputNumber++;
                            break;
                        }
                    }
                    Console.WriteLine("Please enter your guess > {0}", guessNumber);
                }
                Console.ForegroundColor = ConsoleColor.DarkGreen;
                if (guessNumber < selectedNumber) {
                    Console.WriteLine("\nYou're guessing too low!\n");
                    for (int i = 0; i < guessNumber; i++) {
                        guessedNumbers.Add(i);
                        inputNumber++;
                    }
                }
                else if (guessNumber > selectedNumber) {
                    Console.WriteLine("\nYou're guessing too high!\n");
                    for (int i = maxNumber; i > guessNumber; i--) {
                        guessedNumbers.Add(i);
                        inputNumber++;
                    }
                }
            } while (guessNumber != selectedNumber);
            Console.ForegroundColor = ConsoleColor.DarkGreen;
            Console.WriteLine("\nCongratulations! You correctly guessed that {0} is the computer's number!", selectedNumber);
            Console.ReadKey();
        }
    }
}

Edit: I think I'll try a way to make it so that it only adds the numbers that are higher or lower if they aren't already in there, to keep from having duplicate numbers.

for (int i = 0; i < guessNumber; i++) 
{
    guessedNumbers.Add(i);
    inputNumber++;
}

Everytime you enter these types of loops, you add 'guessnumber' items to the list, possibly millions.

Consider re-reading your code and understanding what it does.

Also, you should consider encapsulating your code to avoid making a behemoth of your main()

Another way is to use a Binary Search approach to guess the number and avoid the additional overhead caused by writing and searching for guess values.

This should run in O(log n).

int minGuess = 0;
int maxGuess = 1000000;

Random random = new Random();
int selectedNumber = random.Next(minGuess, maxGuess);

Console.WriteLine($"Selected number: {selectedNumber}");

int guess;

int count = 0;

do
{
    count++;

    guess = (minGuess + maxGuess) / 2;

    Console.WriteLine($"Guess: {guess}");

    if (selectedNumber < guess)
        maxGuess = guess - 1;
    else
        minGuess = guess + 1;

} while (guess != selectedNumber);

Console.WriteLine($"Guessed it in {count} tries");
Console.ReadLine();

The way you're trying to find the number using the computer's power isn't really efficient, why don't you just change the ranges of the possible guessing numbers based on if the previously guessed number is higher or lower than the correct number like so:

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Highest number:");
            int maxNumber = Convert.ToInt32(Console.ReadLine());
            Random rand = new Random();
            int correctNumber = rand.Next(0, maxNumber);

            Console.WriteLine("Trying to guess number now..");
            int guessedNumber = 0;

            int lowBound = 0;
            int highBound = maxNumber;
            int guesses = 0;
            while(guessedNumber != correctNumber)
            {
                guessedNumber = rand.Next(lowBound, highBound);
                if(guessedNumber > correctNumber)
                {
                    highBound /= 2;
                    lowBound /= 2;
                }
                else if(guessedNumber < correctNumber)
                {
                    lowBound *= 2;
                    highBound *= 2;
                }
                ++guesses;
            }
            Console.WriteLine($"Took me {guesses} guesses.");
            Console.ReadKey();
        }
    }

This takes less than a second for 10,000,000 entries on my machine.

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