Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Random Word Generator #2

Tags:

c#

So I made a pretty simple word generator program in c# that works relatively well. It generates a word based on the length defined by the user.

The algorithm adds a consonant and then a vowel for each consecutive letter in the sequence, which isn't ideal, but works well enough for basic words.

My only issue is that I told it to add a "u" to the letter sequence if a "q" shows up right before it, but no matter what I've done it makes the word at least 1 letter too long.

I have marked my problem area with a star in the comment above it. Here is the code:

public void WordFinder()
{
    string word = null;
    int cons;
    int vow;
    //counter
    int i = 0;
    bool isword = false;
    Random rnd = new Random();
    //set a new string array of consonants
    string[] consonant = new string[]{"b","c","d","f","g","h","j","k","l","m","n","p","q","r","s","t","v","w","x","y","z"};
    //set a new string array of vowels
    string[] vowel = new string[]{"a","e","i","o","u"};
    while (isword == false)
    {
        word = null;
        Console.WriteLine("Pick the length of a word");
        int num = Convert.ToInt32(Console.ReadLine());
        //set the counter "i" to 1
        i = 1;
        if (num%2 == 0)
        {
            while (i <= num)
            {
                if (num != 1)
                {
                    // current consonant = random consonant
                    cons = rnd.Next(0, 20);
                    // get the consonant from the string array "consonant" and add it to word
                    word = word + consonant[cons];
                    // add 1 to counter
                    i ++;
                    //* if the consonant is "q"
                    if (cons == 12)
                    {
                        // add "u" right after it
                        word = word + vowel[4];
                        // add 1 to counter
                        i++;
                    }
                }
                vow = rnd.Next(0, 4);
                word = word + vowel[vow];
                i ++;
            }
        }
        if (num % 2 != 0)
        {
            while (i <= num - 1)
            {
                //repeat same code as done to even length
                if (num != 1)
                {
                    cons = rnd.Next(0, 20);
                    word = word + consonant[cons];
                    i ++;
                    if (cons == 12)
                    {
                        word = word + vowel[4];
                        i ++;
                    }
                }
                vow = rnd.Next(0, 4);
                word = word + vowel[vow];
                i ++;
            }
            // if the length is not equal to 1
            if (num != 1)
            {
                // add a consonant to the end of the word
                cons = rnd.Next(0, 20);
                word = word + consonant[cons];
            }
            //if the length is 1
            else if (num == 1)
            {
                // pick a vowel
                vow = rnd.Next(0, 4);
                word = word + vowel[vow];
            }
        }
        i = 1;
        Console.WriteLine(word);
        Console.WriteLine("Is this a word? (y/n)");
        string q = Console.ReadLine();
        q = q.ToLower();
        //if the answer is yes, then it is a word and end the loop
        if (q == "y" || q == "yes")
        {
            isword = true;
        }
        //if the answer is no try the loop again
        else if (q == "n" || q == "no")
        {
            isword = false;
        }
    }
}
// main method
static void Main(string[] args)
{
    Program prog = new Program();
    prog.WordFinder();
    //wait for user input
    Console.ReadLine();
}
}
like image 707
Orren Ravid Avatar asked Aug 07 '13 17:08

Orren Ravid


2 Answers

I refactored your answer and after some debugging I got it to work. Sorry I couldn't just do a tweak on it to fix it. I believe it does not allow a word to end in "qu" or "q".

public void WordFinder()
{
    bool isWord = false;
    Random rnd = new Random();
    string[] consonants = { "b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z" };
    string[] vowels = { "a", "e", "i", "o", "u" };


    while (isWord == false)
    {
        string word = "";

        Console.WriteLine("Pick the length of a word");
        int requestedLength = Convert.ToInt32(Console.ReadLine());

        // Generate the word in consonant / vowel pairs
        while (word.Length < requestedLength)
        {
            if (requestedLength != 1)
            {
                // Add the consonant
                string consonant = GetRandomLetter(rnd, consonants);

                if (consonant == "q" && word.Length + 3 <= requestedLength) // check +3 because we'd add 3 characters in this case, the "qu" and the vowel.  Change 3 to 2 to allow words that end in "qu"
                {
                    word += "qu";
                }
                else
                {
                    while( consonant == "q")
                    {
                        // Replace an orphaned "q"
                        consonant = GetRandomLetter(rnd, consonants); 
                    }

                    if (word.Length + 1 <= requestedLength)
                    {
                        // Only add a consonant if there's enough room remaining
                        word += consonant;
                    }
                }
            }

            if (word.Length + 1 <= requestedLength)
            {
                // Only add a vowel if there's enough room remaining
                word += GetRandomLetter(rnd, vowels);
            }
        }

        Console.WriteLine(word);
        Console.WriteLine("Is this a word? (y/n)");
        string q = Console.ReadLine().ToLower();

        if (q == "y" || q == "yes")
        {
            isWord = true;
        }
    }
}

private static string GetRandomLetter(Random rnd, string[] letters)
{
    return letters[rnd.Next(0, letters.Length - 1)];
}

Edit: However, that's still pretty unruly. How about generating a random string, and then replacing "q" with "qu" after you're done?

public string WordFinder2(int requestedLength)
{
    Random rnd = new Random();
    string[] consonants = { "b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z" };
    string[] vowels = { "a", "e", "i", "o", "u" };

    string word = "";

    if (requestedLength == 1)
    {
        word = GetRandomLetter(rnd, vowels);
    }
    else
    {
        for (int i = 0; i < requestedLength; i+=2)
        {
            word += GetRandomLetter(rnd, consonants) + GetRandomLetter(rnd, vowels);
        }

        word = word.Replace("q", "qu").Substring(0, requestedLength); // We may generate a string longer than requested length, but it doesn't matter if cut off the excess.
    }

    return word;
}

private static string GetRandomLetter(Random rnd, string[] letters)
{
    return letters[rnd.Next(0, letters.Length - 1)];
}
like image 191
Greg Avatar answered Oct 05 '22 09:10

Greg


Your problem is occurring because of the way you are constructing your loops.

You use two separate loops, depending on whether the length is even or odd, and assume in each that the loop will add two characters. However, when a Q is encountered, the loop adds 3 characters, which causes the loop to execute one additional time, and you end up with one extra character.

Try this method:

    string GenerateWord(int length)
    {
        if (length < 1) // do not allow words of zero length
            throw new ArgumentException("Length must be greater than 0");

        string word = string.Empty;

        if (rand.Next() % 2 == 0) // randomly choose a vowel or consonant to start the word
            word += cons[rand.Next(0, 20)];
        else
            word += vowel[rand.Next(0, 4)];

        for (int i = 1; i < length; i += 2) // the counter starts at 1 to account for the initial letter
        { // and increments by two since we append two characters per pass
            char c = cons[rand.Next(0, 20)];
            char v = vowel[rand.Next(0, 4)];

            if (c == 'q') // append qu if the random consonant is a q
                word += "qu";
            else // otherwise just append a random consant and vowel
                word += c + v;
        }

        // the word may be short a letter because of the way the for loop above is constructed
        if (word.Length < length) // we'll just append a random consonant if that's the case
            word += cons[rand.Next(0, 20)];

        return word;
    }
like image 33
Michael Avatar answered Oct 05 '22 07:10

Michael