PYnative

Python Programming

  • Learn Python ▼
    • Python Tutorials
    • Python Basics
    • Python Interview Q&As
  • Exercises ▼
    • Python Exercises
    • C++ Exercises
    • C Programming Exercises
    • Java Exercises
    • C# Exercises
  • Quizzes
  • Code Editor ▼
    • Online Python Code Editor
    • Online C Compiler
    • Online C++ Compiler
    • Online Java Compiler
    • Online C# Compiler
Home » C# Exercises » C# Random Data Generation Exercises: 20 Coding Problems with Solutions

C# Random Data Generation Exercises: 20 Coding Problems with Solutions

Updated on: July 15, 2026 | Leave a Comment

Generating random data is useful for everything from simulations and games to creating realistic test data for your applications.

This collection of 20 C# random data generation exercises covers the Random class in depth, generating random numbers within a range, random strings, shuffled collections, and weighted or seeded results for repeatable output.

Each exercise includes a Practice Problem, Purpose, Hint, and a full Solution with Explanation, so you understand how to generate randomness predictably and correctly.

Also, See: C# Exercises with  22 topic-wise sets and 620+ practice questions.

What You’ll Practice

  • Fundamentals: The Random class and generating numbers within a range.
  • Randomized Collections: Shuffling lists and picking random elements.
  • Custom Generation: Random strings, passwords, and test data sets.
  • Reproducibility: Using a seed for consistent, repeatable random results.
+ Table Of Contents (20 Exercises)

Table of contents

  • Exercise 1: Random Ranges
  • Exercise 2: Deterministic Randomness (Seeding)
  • Exercise 3: Random Char Matrix
  • Exercise 4: Weighted Coin Toss / True-False Bias
  • Exercise 5: Random Fixed-Length Password
  • Exercise 6: Cryptographically Secure Tokens
  • Exercise 7: Random Pronounceable String
  • Exercise 8: Random String from a Custom Alphabet
  • Exercise 9: Random Date in Range
  • Exercise 10: Random Coordinate Geo-Fencing
  • Exercise 11: Random RGB Colors
  • Exercise 12: Random TimeSpans
  • Exercise 13: Synthetic User Objects
  • Exercise 14: Random IP Addresses
  • Exercise 15: Random Credit Card Generator
  • Exercise 16: Array Shuffling (Fisher-Yates)
  • Exercise 17: Random Selection with Replacement
  • Exercise 18: Random Selection without Replacement
  • Exercise 19: Weighted Random Selection
  • Exercise 20: Weighted Random Selection

Exercise 1: Random Ranges

Practice Problem: Generate 5 random integers between 50 and 150 (inclusive) and 5 random double values between 10.0 and 50.0 using the System.Random class.

Purpose: This exercise helps you practice using Random.Next with an inclusive upper bound argument, and Random.NextDouble scaled into a custom range, since NextDouble alone only returns a value between 0.0 and 1.0.

Given Input: Integer range 50 to 150, double range 10.0 to 50.0, five values of each.

Expected Output (illustrative; the exact values will vary by run since no seed is used):

Random integers:
87
142
63
110
99
Random doubles:
24.61
41.08
15.92
38.47
29.03
▼ Hint
  • Create a single instance of Random and reuse it for every call, rather than creating a new instance inside a loop.
  • Use Next(minValue, maxValue + 1) to get an integer in an inclusive range, since Next‘s upper bound is exclusive by default.
  • Use NextDouble() to get a fraction between 0.0 and 1.0, then scale and shift it into the desired range.
  • Loop five times for each type of value, printing each result as it’s generated.
▼ Solution & Explanation
using System;

class Program
{
    static void Main()
    {
        Random random = new Random();

        Console.WriteLine("Random integers:");
        for (int i = 0; i < 5; i++)
        {
            int value = random.Next(50, 151);
            Console.WriteLine(value);
        }

        Console.WriteLine("Random doubles:");
        for (int i = 0; i < 5; i++)
        {
            double value = 10.0 + random.NextDouble() * (50.0 - 10.0);
            Console.WriteLine(value);
        }
    }
}Code language: C# (cs)

Explanation:

  • new Random(): A single shared instance is created once and reused for every call, since creating a new Random instance repeatedly in a tight loop can produce identical values on some systems due to the same seed being derived from the clock.
  • random.Next(50, 151): Generates an integer from 50 up to, but not including, 151, effectively covering the inclusive range from 50 to 150.
  • 10.0 + random.NextDouble() * (50.0 - 10.0): Scales the 0.0-to-1.0 value from NextDouble() into the desired 10.0-to-50.0 range, by multiplying by the range’s width and adding the minimum value as an offset.
  • Output varies by run: Since no fixed seed is provided, each execution of the program produces a different sequence of random values.

Exercise 2: Deterministic Randomness (Seeding)

Practice Problem: Initialize two instances of Random using the exact same integer seed. Generate a list of 10 numbers from both and verify that their outputs are perfectly identical.

Purpose: This exercise helps you practice using a fixed seed to make a Random instance’s output reproducible, which is useful for testing or replaying a specific sequence of “random” events.

Given Input: seed = 42

Expected Output: True

▼ Hint
  • Create two separate Random instances, passing the exact same integer seed to each one’s constructor.
  • Generate a list of 10 numbers from each instance using a loop and the Next method.
  • Compare the two lists for equality using SequenceEqual, since the default list equality check compares references rather than contents.
  • Confirm that both lists contain exactly the same numbers in exactly the same order.
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        int seed = 42;
        Random randomA = new Random(seed);
        Random randomB = new Random(seed);

        List<int> listA = new List<int>();
        List<int> listB = new List<int>();

        for (int i = 0; i < 10; i++)
        {
            listA.Add(randomA.Next(1, 100));
            listB.Add(randomB.Next(1, 100));
        }

        bool areIdentical = listA.SequenceEqual(listB);
        Console.WriteLine(areIdentical);
    }
}Code language: C# (cs)

Explanation:

  • new Random(seed): Passing the same seed value to both constructors ensures each instance starts from the exact same internal state, producing the same sequence of “random” numbers.
  • Two separate loops: Generate ten numbers from each instance independently, but since both started from the same seed, their sequences end up matching value for value.
  • listA.SequenceEqual(listB): Compares the two lists element by element, returning true only if every corresponding pair of values is equal and both lists are the same length.
  • Practical use: Seeding is useful for testing, since it lets a “random” scenario be reproduced exactly on demand rather than varying unpredictably between runs.

Exercise 3: Random Char Matrix

Practice Problem: Generate a random 5×5 grid (2D array) consisting entirely of uppercase characters from ‘A’ to ‘Z’.

Purpose: This exercise helps you practice combining a nested loop over a 2D array with a random character generator, converting a random integer into a letter using its position in the alphabet.

Given Input: A 5×5 grid to fill with random uppercase letters.

Expected Output (illustrative; letters will vary by run):

QJZTM
XBLFK
NRYCS
HGVWD
AEPOU
▼ Hint
  • Declare a two-dimensional char array with 5 rows and 5 columns.
  • Loop through both dimensions using nested for loops, one for rows and one for columns.
  • Generate a random integer between 0 and 25 using Next, then add it to the character 'A' to get a random uppercase letter.
  • Print each row of the grid on its own line once the array has been fully populated.
▼ Solution & Explanation
using System;

class Program
{
    static void Main()
    {
        Random random = new Random();
        char[,] grid = new char[5, 5];

        for (int row = 0; row < 5; row++)
        {
            for (int col = 0; col < 5; col++)
            {
                grid[row, col] = (char)('A' + random.Next(0, 26));
            }
        }

        for (int row = 0; row < 5; row++)
        {
            for (int col = 0; col < 5; col++)
            {
                Console.Write(grid[row, col]);
            }
            Console.WriteLine();
        }
    }
}Code language: C# (cs)

Explanation:

  • char[5, 5] grid: Declares a two-dimensional array with 5 rows and 5 columns, capable of holding 25 individual characters.
  • random.Next(0, 26): Generates an integer from 0 to 25, matching the 26 letters of the alphabet.
  • (char)('A' + random.Next(0, 26)): Adds that random offset to the character 'A', producing a random uppercase letter, since characters can be treated as numeric values in C#.
  • Nested loops for printing: The outer loop moves through each row, while the inner loop prints every character in that row before a newline is written.

Exercise 4: Weighted Coin Toss / True-False Bias

Practice Problem: Create a method GetBiasedBool(double trueProbability) that returns a bool. If the input is 0.75, it should return true roughly 75% of the time.

Purpose: This exercise helps you practice comparing a random fraction against a probability threshold to bias the outcome of a boolean result, rather than a plain 50/50 split.

Given Input: trueProbability = 0.75, called 10000 times.

Expected Output (illustrative; the exact count will vary slightly by run): approximately 7500 out of 10000 were true

▼ Hint
  • Generate a random fraction between 0.0 and 1.0 using NextDouble.
  • Return true if that fraction is less than the given trueProbability, and false otherwise.
  • Test the method by calling it many times and counting how often it returns true.
  • Compare the resulting count against the expected proportion to confirm the bias is roughly correct.
▼ Solution & Explanation
using System;

class Program
{
    static Random random = new Random();

    static bool GetBiasedBool(double trueProbability)
    {
        return random.NextDouble() < trueProbability;
    }

    static void Main()
    {
        int trueCount = 0;
        int totalRuns = 10000;

        for (int i = 0; i < totalRuns; i++)
        {
            if (GetBiasedBool(0.75))
            {
                trueCount++;
            }
        }

        Console.WriteLine(trueCount + " out of " + totalRuns + " were true");
    }
}Code language: C# (cs)

Explanation:

  • random.NextDouble() < trueProbability: Compares a random fraction between 0.0 and 1.0 against the given probability, so a higher trueProbability makes the comparison succeed more often.
  • Proportional bias: Since NextDouble() produces a roughly uniform spread of values across its range, a threshold of 0.75 causes the comparison to succeed for about 75% of all generated fractions.
  • Repeated testing: Calling GetBiasedBool many times and counting the true results is the practical way to confirm a probability-based method behaves as expected, since any single call could go either way.
  • Static Random field: Reusing one shared Random instance across all 10000 calls avoids the correlated-output problem that can occur from creating many Random instances in quick succession.

Exercise 5: Random Fixed-Length Password

Practice Problem: Generate a 12-character random password containing at least 2 uppercase letters, 2 lowercase letters, 2 digits, and 2 special characters.

Purpose: This exercise helps you practice guaranteeing a mix of required character categories by seeding specific characters from each category first, then filling the remainder randomly and shuffling the result.

Given Input: length = 12

Expected Output (illustrative; the exact password will vary by run, but always contains at least 2 of each required category): Xk9@fQ2!mZ7#

▼ Hint
  • Define separate strings representing the uppercase, lowercase, digit, and special character sets.
  • Pick exactly 2 characters from each of the four sets first, guaranteeing the minimum requirement for each category.
  • Fill the remaining characters, up to the total length, by picking randomly from all four sets combined.
  • Shuffle the resulting list of characters before converting it into a final string, so the guaranteed characters aren’t always in the same positions.
▼ Solution & Explanation
using System;
using System.Linq;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        Random random = new Random();

        string upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        string lower = "abcdefghijklmnopqrstuvwxyz";
        string digits = "0123456789";
        string special = "!@#$%";
        string all = upper + lower + digits + special;

        List<char> passwordChars = new List<char>();

        for (int i = 0; i < 2; i++)
        {
            passwordChars.Add(upper[random.Next(upper.Length)]);
            passwordChars.Add(lower[random.Next(lower.Length)]);
            passwordChars.Add(digits[random.Next(digits.Length)]);
            passwordChars.Add(special[random.Next(special.Length)]);
        }

        while (passwordChars.Count < 12)
        {
            passwordChars.Add(all[random.Next(all.Length)]);
        }

        string password = new string(passwordChars.OrderBy(c => random.Next()).ToArray());
        Console.WriteLine(password);
    }
}Code language: C# (cs)

Explanation:

  • Four separate character sets: upper, lower, digits, and special each represent one required category, kept apart so exactly 2 characters can be drawn from each.
  • Guaranteed minimums: The first loop adds 2 characters from every category before anything else, ensuring the final password can never fall short of the requirement no matter how the rest of the fill turns out.
  • while (passwordChars.Count < 12): Fills any remaining slots by drawing randomly from the combined all string, which includes every category.
  • OrderBy(c => random.Next()): Shuffles the list of characters into a random order before joining them into the final string, so the guaranteed characters don’t always appear in the same fixed positions.

Exercise 6: Cryptographically Secure Tokens

Practice Problem: Use System.Security.Cryptography.RandomNumberGenerator to generate a secure, 32-byte hex string token suitable for password reset links.

Purpose: This exercise helps you practice using a cryptographically secure random number generator instead of System.Random, which matters whenever generated values need to be unpredictable for security purposes, such as a password reset link.

Given Input: Token length of 32 bytes.

Expected Output (illustrative; the exact token will vary by run): a 64-character hex string, e.g. 3f2a9b7c1e4d6f8a0b2c4d6e8f1a3b5c7d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a

▼ Hint
  • Use RandomNumberGenerator.Fill to populate a byte array with cryptographically secure random values.
  • Allocate a byte array of exactly 32 bytes before filling it.
  • Convert the byte array into a readable string using Convert.ToHexString.
  • Print the resulting string to see the final token.
▼ Solution & Explanation
using System;
using System.Security.Cryptography;

class Program
{
    static void Main()
    {
        byte[] tokenBytes = new byte[32];
        RandomNumberGenerator.Fill(tokenBytes);

        string token = Convert.ToHexString(tokenBytes);
        Console.WriteLine(token);
    }
}Code language: C# (cs)

Explanation:

  • new byte[32]: Allocates an empty array with room for exactly 32 random bytes, matching the requested token size.
  • RandomNumberGenerator.Fill(tokenBytes): Populates the array with cryptographically secure random values, generated by the operating system’s secure random source rather than a predictable algorithm.
  • Convert.ToHexString(tokenBytes): Converts the raw bytes into a readable hexadecimal string, doubling the character count since each byte becomes two hex characters.
  • Why not System.Random: System.Random is designed for speed and statistical distribution, not unpredictability against an attacker, so it isn’t suitable for anything security-sensitive like a password reset token.

Exercise 7: Random Pronounceable String

Practice Problem: Generate a random “pronounceable” 6-letter string by alternating between random vowels and random consonants.

Purpose: This exercise helps you practice building a string character by character using two separate random choices, alternating between two different character sets based on the current position.

Given Input: length = 6

Expected Output (illustrative; letters will vary by run): sokuve

▼ Hint
  • Define two separate strings, one containing the vowels and one containing the consonants.
  • Loop through each position of the desired length, checking whether the current index is even or odd.
  • Pick a random character from the consonants string on one type of position and from the vowels string on the other.
  • Build the final string by appending each randomly chosen character in sequence.
▼ Solution & Explanation
using System;
using System.Text;

class Program
{
    static void Main()
    {
        Random random = new Random();
        string vowels = "aeiou";
        string consonants = "bcdfghjklmnpqrstvwxyz";

        StringBuilder result = new StringBuilder();

        for (int i = 0; i < 6; i++)
        {
            if (i % 2 == 0)
            {
                result.Append(consonants[random.Next(consonants.Length)]);
            }
            else
            {
                result.Append(vowels[random.Next(vowels.Length)]);
            }
        }

        Console.WriteLine(result.ToString());
    }
}Code language: C# (cs)

Explanation:

  • vowels and consonants: Two separate strings acting as the pools to randomly choose from, depending on which type of letter belongs at the current position.
  • i % 2 == 0: Alternates between the two pools based on whether the current index is even or odd, starting with a consonant at position 0.
  • consonants[random.Next(consonants.Length)]: Picks one random character from the consonants string, using a random index within its valid range.
  • StringBuilder: Accumulates each chosen character efficiently before converting the whole sequence into a final string with ToString().

Exercise 8: Random String from a Custom Alphabet

Practice Problem: Given a string mask like "ABC-###-XY", write a function to generate a random identifier where # is replaced by a random digit (0-9).

Purpose: This exercise helps you practice scanning a template character by character and substituting only the characters that match a specific placeholder, leaving every other character untouched.

Given Input: mask = "ABC-###-XY"

Expected Output (illustrative; digits will vary by run): ABC-482-XY

▼ Hint
  • Loop through the mask string one character at a time.
  • Check whether the current character is the placeholder symbol, #.
  • If it is, append a randomly generated digit to the result instead of the placeholder itself.
  • If it isn’t, append the original character unchanged, so the rest of the mask’s structure is preserved.
▼ Solution & Explanation
using System;
using System.Text;

class Program
{
    static string GenerateFromMask(string mask)
    {
        Random random = new Random();
        StringBuilder result = new StringBuilder();

        foreach (char c in mask)
        {
            if (c == '#')
            {
                result.Append(random.Next(0, 10));
            }
            else
            {
                result.Append(c);
            }
        }

        return result.ToString();
    }

    static void Main()
    {
        string identifier = GenerateFromMask("ABC-###-XY");
        Console.WriteLine(identifier);
    }
}Code language: C# (cs)

Explanation:

  • foreach (char c in mask): Walks through the mask one character at a time, examining each one individually.
  • if (c == '#'): Checks whether the current character is the designated placeholder symbol.
  • random.Next(0, 10): Generates a single random digit from 0 to 9 whenever a placeholder is encountered, appending it in place of the #.
  • else { result.Append(c); }: Preserves every non-placeholder character exactly as it appears in the original mask, keeping the surrounding structure like “ABC-” and “-XY” intact.

Exercise 9: Random Date in Range

Practice Problem: Write a method that generates a random DateTime between January 1, 2020 and December 31, 2025. Ensure both the date and time parts are randomized.

Purpose: This exercise helps you practice converting a random fraction into a random position along a span of time, using the difference between two DateTime values measured in ticks.

Given Input: start = January 1, 2020, end = December 31, 2025

Expected Output (illustrative; the exact date and time will vary by run): 3/17/2023 8:42:19 AM

▼ Hint
  • Calculate the total span between the start and end dates as a TimeSpan.
  • Generate a random number of ticks somewhere within that span’s total tick count.
  • Add that random number of ticks to the start date to land on a random point within the range.
  • Print the resulting DateTime to see both its date and time portions.
▼ Solution & Explanation
using System;

class Program
{
    static void Main()
    {
        Random random = new Random();
        DateTime start = new DateTime(2020, 1, 1);
        DateTime end = new DateTime(2025, 12, 31);

        TimeSpan span = end - start;
        long randomTicks = (long)(random.NextDouble() * span.Ticks);

        DateTime randomDate = start.AddTicks(randomTicks);
        Console.WriteLine(randomDate);
    }
}Code language: C# (cs)

Explanation:

  • TimeSpan span = end - start: Measures the total duration between the two boundary dates, expressed as a TimeSpan with an underlying tick count.
  • random.NextDouble() * span.Ticks: Scales a random fraction between 0.0 and 1.0 by the total number of ticks in the span, producing a random offset somewhere within that duration.
  • start.AddTicks(randomTicks): Adds that random offset to the start date, landing on a random point that could fall on any day and at any time within the entire range.
  • Randomizing both date and time together: Since ticks represent the smallest unit of time in a DateTime, this approach naturally randomizes the time of day along with the date, rather than only picking a random day and defaulting to midnight.

Exercise 10: Random Coordinate Geo-Fencing

Practice Problem: Given a central latitude and longitude, generate 10 random geographic coordinates that fall within a 5-kilometer radius.

Purpose: This exercise helps you practice converting a random angle and a random distance into an offset latitude and longitude, approximating a circular area around a central point.

Given Input: centerLatitude = 40.7128, centerLongitude = -74.0060, radiusKm = 5

Expected Output (illustrative; coordinates will vary by run): 10 lines of latitude/longitude pairs, each within roughly 5 kilometers of the center point, e.g. 40.7168, -74.0102

▼ Hint
  • Generate a random angle between 0 and 2π (a full circle) using NextDouble scaled by 2 * Math.PI.
  • Generate a random distance between 0 and the maximum radius, using the square root of a random fraction to keep points evenly distributed across the circle’s area rather than clustered near the center.
  • Convert the random distance and angle into a latitude offset and a longitude offset, using basic trigonometry and an approximate conversion factor for degrees per kilometer.
  • Add each offset to the central latitude and longitude to produce one random coordinate, then repeat the process 10 times.
▼ Solution & Explanation
using System;

class Program
{
    static void Main()
    {
        Random random = new Random();
        double centerLatitude = 40.7128;
        double centerLongitude = -74.0060;
        double radiusKm = 5;

        for (int i = 0; i < 10; i++)
        {
            double angle = random.NextDouble() * 2 * Math.PI;
            double distance = radiusKm * Math.Sqrt(random.NextDouble());

            double latOffset = (distance / 111.0) * Math.Cos(angle);
            double lngOffset = (distance / (111.0 * Math.Cos(centerLatitude * Math.PI / 180))) * Math.Sin(angle);

            double randomLat = centerLatitude + latOffset;
            double randomLng = centerLongitude + lngOffset;

            Console.WriteLine(randomLat + ", " + randomLng);
        }
    }
}Code language: C# (cs)

Explanation:

  • random.NextDouble() * 2 * Math.PI: Picks a random direction around the center point, covering the full 360 degrees of a circle expressed in radians.
  • radiusKm * Math.Sqrt(random.NextDouble()): Picks a random distance from the center, using a square root so points are spread evenly across the circle’s entire area rather than bunching up near the middle.
  • distance / 111.0: Converts a distance in kilometers into an approximate change in latitude degrees, since one degree of latitude is roughly 111 kilometers everywhere on Earth.
  • Longitude adjustment with Math.Cos(centerLatitude * Math.PI / 180): Accounts for the fact that a degree of longitude covers less physical distance the farther a point is from the equator, since lines of longitude converge toward the poles.

Exercise 11: Random RGB Colors

Practice Problem: Generate a random (byte R, byte G, byte B) tuple representing an RGB color value, then format it into a valid hex color string (e.g., “#FF5733”).

Purpose: This exercise helps you practice generating three independent random byte values and combining them into a formatted string using a specific numeric format, in this case two-digit hexadecimal.

Given Input: None; three random byte values are generated for R, G, and B.

Expected Output (illustrative; values vary by run): #3FA9C2

▼ Hint
  • Generate three separate random byte values, one each for R, G, and B, using Next with a range of 0 to 255.
  • Store the three values together as a tuple, such as (byte R, byte G, byte B).
  • Format each byte as a two-digit hexadecimal string using ToString("X2"), which also pads a single hex digit with a leading zero.
  • Concatenate the three formatted values together with a leading # to build the final hex color string.
▼ Solution & Explanation
using System;

class Program
{
    static void Main()
    {
        Random random = new Random();

        byte r = (byte)random.Next(0, 256);
        byte g = (byte)random.Next(0, 256);
        byte b = (byte)random.Next(0, 256);

        (byte R, byte G, byte B) color = (r, g, b);

        string hex = "#" + color.R.ToString("X2") + color.G.ToString("X2") + color.B.ToString("X2");
        Console.WriteLine(hex);
    }
}Code language: C# (cs)

Explanation:

  • random.Next(0, 256): Generates an integer from 0 to 255, matching the full valid range of a single byte.
  • (byte)random.Next(0, 256): Casts that integer down to a byte, since Next itself returns an int rather than a byte directly.
  • (byte R, byte G, byte B) color = (r, g, b): Packages the three separate byte values into a single named tuple, making them easy to pass around or return together.
  • ToString("X2"): Formats each byte as exactly two uppercase hexadecimal digits, padding with a leading zero for values below 16 so every channel always contributes exactly two characters to the final string.

Exercise 12: Random TimeSpans

Practice Problem: Generate a random TimeSpan duration that is at least 30 minutes long but does not exceed 8 hours.

Purpose: This exercise helps you practice generating a random duration by picking a random number of minutes within a bounded range and converting that count into a TimeSpan.

Given Input: minMinutes = 30, maxMinutes = 480 (8 hours)

Expected Output (illustrative; duration varies by run): 03:47:00

▼ Hint
  • Convert both boundary durations, 30 minutes and 8 hours, into a common unit such as total minutes.
  • Generate a random integer number of minutes somewhere between those two boundary values, inclusive.
  • Convert that random minute count into a TimeSpan using TimeSpan.FromMinutes.
  • Print the resulting TimeSpan to see it displayed in a familiar hours-minutes-seconds format.
▼ Solution & Explanation
using System;

class Program
{
    static void Main()
    {
        Random random = new Random();
        int minMinutes = 30;
        int maxMinutes = 8 * 60;

        int randomMinutes = random.Next(minMinutes, maxMinutes + 1);
        TimeSpan duration = TimeSpan.FromMinutes(randomMinutes);

        Console.WriteLine(duration);
    }
}Code language: C# (cs)

Explanation:

  • int maxMinutes = 8 * 60: Converts the 8-hour upper boundary into its equivalent number of minutes, so both boundaries are expressed in the same unit.
  • random.Next(minMinutes, maxMinutes + 1): Generates a random integer between 30 and 480 minutes, inclusive, since Next‘s upper bound is normally exclusive.
  • TimeSpan.FromMinutes(randomMinutes): Converts the random minute count into a proper TimeSpan value, which automatically handles the conversion into hours, minutes, and seconds internally.
  • Console.WriteLine(duration): Prints the TimeSpan using its default format, displaying the duration as hours, minutes, and seconds.

Exercise 13: Synthetic User Objects

Practice Problem: Define a User class with Id (Guid), Username (string), Age (int), and IsActive (bool). Generate a list containing 100 entries filled with random but realistic dummy data.

Purpose: This exercise helps you practice combining several different random generation techniques, a GUID, a random name built from parts, a bounded random age, and a random boolean, into one cohesive object, then repeating that process to build a larger collection.

Given Input: count = 100

Expected Output (illustrative; values vary by run, showing the first entry only): Id: 3fa85f64-5717-4562-b3fc-2c963f66afa6, Username: user482, Age: 34, IsActive: True

▼ Hint
  • Define the User class with properties for Id, Username, Age, and IsActive matching the required types.
  • Use Guid.NewGuid() to generate a unique identifier for each user automatically.
  • Build a random username by combining a fixed prefix with a random number.
  • Generate a random age within a reasonable adult range and a random boolean for IsActive, then repeat the whole object-creation process in a loop to build the full list.
▼ Solution & Explanation
using System;
using System.Collections.Generic;

class User
{
    public Guid Id { get; set; }
    public string Username { get; set; }
    public int Age { get; set; }
    public bool IsActive { get; set; }
}

class Program
{
    static void Main()
    {
        Random random = new Random();
        List<User> users = new List<User>();

        for (int i = 0; i < 100; i++)
        {
            User user = new User
            {
                Id = Guid.NewGuid(),
                Username = "user" + random.Next(100, 1000),
                Age = random.Next(18, 66),
                IsActive = random.Next(0, 2) == 1
            };

            users.Add(user);
        }

        Console.WriteLine("Id: " + users[0].Id + ", Username: " + users[0].Username + ", Age: " + users[0].Age + ", IsActive: " + users[0].IsActive);
    }
}Code language: C# (cs)

Explanation:

  • Guid.NewGuid(): Generates a statistically unique identifier for each user, without needing to track previously used values to avoid collisions.
  • "user" + random.Next(100, 1000): Builds a simple but varied username by appending a random three-digit number to a fixed prefix.
  • random.Next(18, 66): Generates a random age within a realistic adult range, from 18 up to 65 inclusive.
  • random.Next(0, 2) == 1: Generates a random boolean by picking either 0 or 1 and comparing it to 1, since Random doesn’t have a dedicated method for generating booleans directly.

Exercise 14: Random IP Addresses

Practice Problem: Generate a random, valid IPv4 string where each octet is randomly chosen between 0 and 255, while avoiding networking edge cases like 0.0.0.0.

Purpose: This exercise helps you practice generating four independent random octet values and joining them into a properly formatted address, while explicitly guarding against a reserved edge-case value.

Given Input: None; four random octets are generated.

Expected Output (illustrative; values vary by run): 192.168.47.203

▼ Hint
  • Generate four separate random integers, each between 0 and 255, one for every octet of the address.
  • Join the four octet values together into a single string, separated by literal periods.
  • Check whether the very first octet came out to 0, since an address starting that way isn’t a valid usable address.
  • If the first octet is 0, regenerate that value so the final result avoids the reserved case.
▼ Solution & Explanation
using System;

class Program
{
    static void Main()
    {
        Random random = new Random();
        int firstOctet;

        do
        {
            firstOctet = random.Next(0, 256);
        } while (firstOctet == 0);

        int secondOctet = random.Next(0, 256);
        int thirdOctet = random.Next(0, 256);
        int fourthOctet = random.Next(0, 256);

        string ipAddress = firstOctet + "." + secondOctet + "." + thirdOctet + "." + fourthOctet;
        Console.WriteLine(ipAddress);
    }
}Code language: C# (cs)

Explanation:

  • do { firstOctet = random.Next(0, 256); } while (firstOctet == 0);: Keeps regenerating the first octet specifically until it produces a value other than 0, avoiding the reserved 0.0.0.0-style address.
  • The remaining three octets: Each generated independently using the full 0-to-255 range, since only the first octet needs the extra restriction in this exercise.
  • String concatenation with periods: Joins the four octet values into the standard dotted format expected of an IPv4 address.
  • do-while loop: Chosen over a plain if check because it guarantees the value is generated at least once and keeps retrying only when the excluded case actually occurs.

Exercise 15: Random Credit Card Generator

Practice Problem: Write a function to mock a random 16-digit credit card number string, implementing the Luhn algorithm so the generated number passes basic numerical validation checks.

Purpose: This exercise helps you practice generating a sequence of random digits and then calculating a check digit using the Luhn algorithm, so the resulting number passes the same validation formula real card numbers are checked against.

Given Input: None; 15 random digits are generated before the check digit is calculated.

Expected Output (illustrative; the digits before the final check digit vary by run, but the complete 16-digit number always passes Luhn validation): 4539148803436467

▼ Hint
  • Generate the first 15 digits of the card number randomly, one digit at a time.
  • Apply the Luhn algorithm to those 15 digits to calculate the correct final check digit.
  • The Luhn algorithm doubles every second digit from the right, subtracting 9 from any result over 9, then sums all the digits together.
  • Choose the check digit that makes the total sum a multiple of 10, and append it as the 16th and final digit.
▼ Solution & Explanation
using System;
using System.Text;

class Program
{
    static int CalculateLuhnCheckDigit(string digits)
    {
        int sum = 0;
        bool doubleDigit = true;

        for (int i = digits.Length - 1; i >= 0; i--)
        {
            int digit = digits[i] - '0';

            if (doubleDigit)
            {
                digit *= 2;
                if (digit > 9)
                {
                    digit -= 9;
                }
            }

            sum += digit;
            doubleDigit = !doubleDigit;
        }

        int remainder = sum % 10;
        return remainder == 0 ? 0 : 10 - remainder;
    }

    static void Main()
    {
        Random random = new Random();
        StringBuilder cardDigits = new StringBuilder();

        for (int i = 0; i < 15; i++)
        {
            cardDigits.Append(random.Next(0, 10));
        }

        int checkDigit = CalculateLuhnCheckDigit(cardDigits.ToString());
        string cardNumber = cardDigits.ToString() + checkDigit;

        Console.WriteLine(cardNumber);
    }
}Code language: C# (cs)

Explanation:

  • for (int i = 0; i < 15; i++): Generates the first fifteen digits of the card number completely at random, one at a time.
  • CalculateLuhnCheckDigit: Implements the Luhn algorithm, doubling every second digit counted from the right and subtracting 9 whenever that doubled value exceeds 9, then summing every digit together.
  • 10 - remainder: Determines the specific check digit needed to bring the total sum up to the next multiple of 10, which is the exact rule the Luhn algorithm’s validation check relies on.
  • Appending the check digit last: Completes the 16-digit number so that running the same Luhn calculation over the full number, including the new check digit, confirms it as valid.

Exercise 16: Array Shuffling (Fisher-Yates)

Practice Problem: Create a generic method void Shuffle<T>(List<T> list) that implements the Fisher-Yates algorithm to randomly reorder any collection in place.

Purpose: This exercise helps you practice implementing the Fisher-Yates algorithm, a proven method for shuffling a list in place with a genuinely uniform random distribution, unlike naive approaches that can introduce bias.

Given Input: numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Expected Output (illustrative; order varies by run): 7, 2, 9, 4, 1, 10, 3, 6, 8, 5

▼ Hint
  • Write the method as generic using <T>, so it can shuffle a list of any element type.
  • Loop backward through the list, starting at the last index and moving toward the first.
  • At each step, pick a random index from 0 up to and including the current position.
  • Swap the element at the current position with the element at that randomly chosen index.
▼ Solution & Explanation
using System;
using System.Collections.Generic;

class Program
{
    static Random random = new Random();

    static void Shuffle<T>(List<T> list)
    {
        for (int i = list.Count - 1; i > 0; i--)
        {
            int j = random.Next(0, i + 1);
            T temp = list[i];
            list[i] = list[j];
            list[j] = temp;
        }
    }

    static void Main()
    {
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        Shuffle(numbers);

        Console.WriteLine(string.Join(", ", numbers));
    }
}Code language: C# (cs)

Explanation:

  • static void Shuffle<T>(List<T> list): The <T> type parameter lets this single method shuffle a list of integers, strings, or any other type without rewriting it for each one.
  • for (int i = list.Count - 1; i > 0; i--): Walks backward through the list, treating each position as the “current” slot to be finalized.
  • random.Next(0, i + 1): Picks a random index from anywhere in the still-unshuffled portion of the list, including the current position itself.
  • Swapping list[i] and list[j]: Exchanges the two elements in place, which is what makes Fisher-Yates modify the original list directly rather than producing a new one.

Exercise 17: Random Selection with Replacement

Practice Problem: Write a program that picks 5 random elements from an array of strings (e.g., names of cities), allowing the same city to be picked multiple times.

Purpose: This exercise helps you practice selecting random elements from a collection independently, where each pick has no effect on future picks, allowing the same value to be chosen more than once.

Given Input: cities = ["Tokyo", "Paris", "Cairo", "Lima", "Oslo"]

Expected Output (illustrative; selections vary by run):

Paris
Lima
Paris
Tokyo
Oslo
▼ Hint
  • Store the pool of possible values in an array.
  • Loop for the number of picks you want, five in this case.
  • Each time through the loop, generate a random index within the array’s valid range and select that element.
  • Since each pick uses a fresh random index independent of previous picks, the same element can be selected more than once.
▼ Solution & Explanation
using System;

class Program
{
    static void Main()
    {
        Random random = new Random();
        string[] cities = { "Tokyo", "Paris", "Cairo", "Lima", "Oslo" };

        for (int i = 0; i < 5; i++)
        {
            string selected = cities[random.Next(cities.Length)];
            Console.WriteLine(selected);
        }
    }
}Code language: C# (cs)

Explanation:

  • cities[random.Next(cities.Length)]: Picks one random element from the array using a freshly generated random index each time.
  • Independent picks: Since every loop iteration generates a brand new random index without excluding any previous selections, the same city can legitimately appear more than once in the results.
  • for (int i = 0; i < 5; i++): Controls the total number of picks, regardless of how many distinct values end up appearing.
  • No tracking needed: Unlike selection without replacement, this approach doesn’t need to remove or mark previously chosen elements, since repeats are allowed by design.

Exercise 18: Random Selection without Replacement

Practice Problem: Using LINQ, pick 3 unique, non-repeating elements from a list of 10 items.

Purpose: This exercise helps you practice selecting a random subset of distinct elements from a larger collection, ensuring no single element is picked more than once.

Given Input: A list of 10 items, "Item1" through "Item10".

Expected Output (illustrative; selections vary by run): Item7, Item2, Item9

▼ Hint
  • Use OrderBy with a random key to shuffle the entire list into a random order.
  • Take the first however-many elements you need from that shuffled sequence using Take.
  • Since the shuffle rearranges every element without duplicating any of them, the elements taken from the front are guaranteed to be unique.
  • Convert the result to a list to use it further.
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        Random random = new Random();
        List<string> items = new List<string>();

        for (int i = 1; i <= 10; i++)
        {
            items.Add("Item" + i);
        }

        List<string> selected = items.OrderBy(x => random.Next()).Take(3).ToList();

        Console.WriteLine(string.Join(", ", selected));
    }
}Code language: C# (cs)

Explanation:

  • items.OrderBy(x => random.Next()): Reorders the entire list into a random sequence by sorting according to a freshly generated random number for each element.
  • .Take(3): Grabs the first three elements from that shuffled sequence, effectively selecting three random items from the original list.
  • Guaranteed uniqueness: Since OrderBy simply rearranges existing elements rather than duplicating them, no single item can appear twice in the shuffled sequence or in the final selection.
  • .ToList(): Converts the resulting LINQ query into a concrete List<string>, so it can be printed, stored, or passed around like any other list.

Exercise 19: Weighted Random Selection

Practice Problem: Given an array of items and an array of their corresponding weights (e.g., ["Common Item", "Rare Item", "Epic Item"] with weights [80, 15, 5]), select one item at random according to those weights.

Purpose: This exercise helps you practice mapping a single random number onto a cumulative distribution of weights, so items with larger weights are proportionally more likely to be selected.

Given Input: items = ["Common Item", "Rare Item", "Epic Item"], weights = [80, 15, 5]

Expected Output (illustrative; the result varies by run, but “Common Item” should appear roughly 80% of the time across many calls): Common Item

▼ Hint
  • Calculate the total sum of all the weights combined.
  • Generate a single random number between 0 and that total sum.
  • Loop through the items, subtracting each item’s weight from the random number until the number drops below the current item’s weight.
  • Return the item at the point where the running subtraction causes the number to cross that threshold, since items with larger weights consume more of the random number’s range.
▼ Solution & Explanation
using System;

class Program
{
    static string GetWeightedRandomItem(string[] items, int[] weights)
    {
        Random random = new Random();
        int totalWeight = 0;

        foreach (int weight in weights)
        {
            totalWeight += weight;
        }

        int randomValue = random.Next(0, totalWeight);

        for (int i = 0; i < items.Length; i++)
        {
            if (randomValue < weights[i])
            {
                return items[i];
            }
            randomValue -= weights[i];
        }

        return items[items.Length - 1];
    }

    static void Main()
    {
        string[] items = { "Common Item", "Rare Item", "Epic Item" };
        int[] weights = { 80, 15, 5 };

        string result = GetWeightedRandomItem(items, weights);
        Console.WriteLine(result);
    }
}Code language: C# (cs)

Explanation:

  • int totalWeight: Sums every weight in the array together, establishing the full range that the random number needs to cover.
  • random.Next(0, totalWeight): Generates a single random number somewhere within that combined range, from 0 up to just under the total.
  • if (randomValue < weights[i]): Checks whether the random number falls within the current item’s “slice” of the total range; if so, that item is the selected result.
  • randomValue -= weights[i]: Shrinks the random number by the current item’s weight whenever it doesn’t fall within that item’s slice, moving on to check the next item’s slice using the same, now-reduced number.

Exercise 20: Weighted Random Selection

Practice Problem: Given an array of items and an array of their corresponding weights (e.g., ["Common Item", "Rare Item", "Epic Item"] with weights [80, 15, 5]), select one item at random according to those weights.

Purpose: This exercise helps you practice mapping a single random number onto a cumulative distribution of weights, so items with larger weights are proportionally more likely to be selected.

Given Input: items = ["Common Item", "Rare Item", "Epic Item"], weights = [80, 15, 5]

Expected Output (illustrative; the result varies by run, but “Common Item” should appear roughly 80% of the time across many calls): Common Item

▼ Hint
  • Calculate the total sum of all the weights combined.
  • Generate a single random number between 0 and that total sum.
  • Loop through the items, subtracting each item’s weight from the random number until the number drops below the current item’s weight.
  • Return the item at the point where the running subtraction causes the number to cross that threshold, since items with larger weights consume more of the random number’s range.
▼ Solution & Explanation
using System;

class Program
{
    static string GetWeightedRandomItem(string[] items, int[] weights)
    {
        Random random = new Random();
        int totalWeight = 0;

        foreach (int weight in weights)
        {
            totalWeight += weight;
        }

        int randomValue = random.Next(0, totalWeight);

        for (int i = 0; i < items.Length; i++)
        {
            if (randomValue < weights[i])
            {
                return items[i];
            }
            randomValue -= weights[i];
        }

        return items[items.Length - 1];
    }

    static void Main()
    {
        string[] items = { "Common Item", "Rare Item", "Epic Item" };
        int[] weights = { 80, 15, 5 };

        string result = GetWeightedRandomItem(items, weights);
        Console.WriteLine(result);
    }
}Code language: C# (cs)

Explanation:

  • int totalWeight: Sums every weight in the array together, establishing the full range that the random number needs to cover.
  • random.Next(0, totalWeight): Generates a single random number somewhere within that combined range, from 0 up to just under the total.
  • if (randomValue < weights[i]): Checks whether the random number falls within the current item’s “slice” of the total range; if so, that item is the selected result.
  • randomValue -= weights[i]: Shrinks the random number by the current item’s weight whenever it doesn’t fall within that item’s slice, moving on to check the next item’s slice using the same, now-reduced number.

Filed Under: C# Exercises

Did you find this page helpful? Let others know about it. Sharing helps me continue to create free Python resources.

TweetF  sharein  shareP  Pin

About Vishal

I’m Vishal Hule, the Founder of PYnative.com. As a Python developer, I enjoy assisting students, developers, and learners. Follow me on Twitter.

Related Tutorial Topics:

C# Exercises

All Coding Exercises:

C Exercises
C++ Exercises
Python Exercises
Java Exercises
C# Exercises

Python Exercises and Quizzes

Free coding exercises and quizzes cover Python basics, data structure, data analytics, and more.

  • 15+ Topic-specific Exercises and Quizzes
  • Each Exercise contains 25+ questions
  • Each Quiz contains 25 MCQ
Exercises
Quizzes

Leave a Reply Cancel reply

your email address will NOT be published. all comments are moderated according to our comment policy.

Use <pre> tag for posting code. E.g. <pre> Your entire code </pre>

In: C# Exercises
TweetF  sharein  shareP  Pin

  C# Exercises

  • C# Exercise for Beginners
  • C# Loops Exercise
  • C# Array Exercise
  • C# String Exercise
  • C# OOP Exercise
  • C# Structs, Records and Enums Exercise
  • C# Collections Exercise
  • C# List Exercise
  • C# Dictionary Exercise
  • C# LINQ Exercise
  • C# Exception Handling Exercise
  • C# File Handling Exercise
  • C# Date and Time Exercise
  • C# Generics Exercise
  • C# Lambda Expressions Exercise
  • C# Delegates and Events Exercise
  • C# Extension Methods Exercise
  • C# Regex Exercise
  • C# Pattern Matching Exercise
  • C# Iterators and Yield Exercise
  • C# Indexers and Operator Overloading Exercise
  • C# Random Data Generation Exercise

All Coding Exercises

Python Exercises C Exercises C++ Exercises Java Exercises C# Exercises

About PYnative

PYnative.com is for Python lovers. Here, You can get Tutorials, Exercises, and Quizzes to practice and improve your Python skills.

Follow Us

To get New Python Tutorials, Exercises, and Quizzes

  • Twitter
  • Facebook
  • Sitemap

Explore Python

  • Learn Python
  • Python Basics
  • Python Databases
  • Python Exercises
  • Python Quizzes
  • Online Python Code Editor
  • Python Tricks

Coding Exercises

  • C Exercises
  • C++ Exercises
  • Python Exercises
  • Java Exercises
  • C# Exercises

Legal Stuff

  • About Us
  • Contact Us

We use cookies to improve your experience. While using PYnative, you agree to have read and accepted our:

  • Terms Of Use
  • Privacy Policy
  • Cookie Policy

Copyright © 2018–2026 pynative.com