Pertaining to random and non-repeating numbers - c#

My code is supposed to generate random and non-repeating numbers, but when I print it it doesn't do it properly and sometimes it repeats itself. How can I fix?
Console.WriteLine("choose how many digits your password should be\nminimum 5 maximum 10 digits");
Console.Write("number of digits:");
int digit = int.Parse(Console.ReadLine());
int[] passwordarray = new int[digit];
Random r = new Random();
for (int i = 0; i < passwordarray.Length; i++)
{
if (digit <= 10 && digit >= 5)
{
do
{
passwordarray[i] = r.Next(0, 10);
} while (!(passwordarray.Contains(passwordarray[i])));
}
else
{
Console.WriteLine("your number of digits is less than 5 or more than 10");
}
}

I restructured your code:
Console.WriteLine("choose how many digits your password should be\nminimum 5 maximum 10 digits");
Console.Write("number of digits:");
int digit = int.Parse(Console.ReadLine());
int[] passwordarray = new int[digit];
Random r = new Random();
// check the digits first
if (digit <= 10 && digit >= 5)
{
int tempVal;
for (int i = 0; i < passwordarray.Length; i++)
{
// generate values until you have a value thats not in the array
do
{
tempVal = r.Next(0, 10);
} while (passwordarray.Contains(tempVal));
// add the value
passwordarray[i] = tempVal;
}
}
Basically you want to check first if the digits are between 5 and 10, then iterate trough your array, generate random values until you have one that isn't in the password array yet, and add this value. I just restructured your code, I didn't run it.
EDIT: obviously there are better solutions to implement this behavior, like Dmitrys answer, I restructured the code just to show you where your logic is wrong

Related

How to generate a number from first or last digits of an array and check if it is divisible by a certain number in C#?

I am a beginner in C# and I am struck with this problem. To question is as follows
You are given an array of size n that contains integers. Here, n is an even number. You are required to perform the following operations:
1. Divide the array of numbers in two equal halves
Note: Here, two equal parts of a test case are created by dividing the array into two equal parts.
2. Take the first digit of the numbers that are available in the first half of the array (first 50% of
the test case)
3. Take the last digit of the numbers that are available in the second half of the array (second 50% of
the test case)
4. Generate a number by using the digits that have been selected in the above steps
Your task is to determine whether the newly-generated number is divisible by 11.
And this is my code-
using System;
namespace IsDivisible
{
class Program
{
static void Main(string[] args)
{
int n = Convert.ToInt32(Console.ReadLine());
int div = 0, digit;
string str = " ";
string[] numArray = Console.ReadLine().Split(' ');
int[] arr = new int[n];
for (int i = 0; i < n; i++)
{
arr[i] = Convert.ToInt32(str[i]);
if (i <= n / 2)
{
while (arr[i] >= 10)
{
div = arr[i] / 10;
}
str += div;
}
else
{
digit = arr[i] % 10;
str += digit;
}
}
long newNumber = Convert.ToInt64(str);
if (newNumber % 11 == 0)
Console.WriteLine("YES");
else
Console.WriteLine("NO");
Console.Read();
}
}
}```
It has no errors during compile time in visual studio. The code is not printing anything after I input the array and I am unable to figure out what's wrong. Please help.

For loop for calculating score, how to combine two methods

In my method public static int PointsCalculator() I seem to be unable to use my values from my two other methods in order to compare the values in the two array and give points.
I'm not really sure how to call or initialize the values to begin but tried to do a quick mockup.
My goal is to add one point for every user value in the GetUserGuesses method that is the same as the random values in the RandomBingoNumbers method.
class UserBingo // Creates a class to store all user related
{
static int[] RandomNrs;
static int[] userGuesses;
static int num = 0;
public static int[] GetUserGuess() // A method for collecting user guesses and displaying them (SPLIT THEM UP)
{
userGuesses = new int[10]; // Creates the array to store 10 user inputs
for (int i = 0; i < userGuesses.Length; i++) // For loop itterates until 10 user values are put into the array
{
try
{
int input = Convert.ToInt32(Console.ReadLine());
if (input < 1 || input > 25) // Only values between 1-25
{
Console.WriteLine("Only enter a number between 1-25");
i--;
}
else if (userGuesses.Contains(input)) // Checks for repeated values
{
Console.WriteLine("You have already entered {0}", input);
i--;
}
else
{
userGuesses[i] = input; //When they do meet the correct values
Console.WriteLine("Thanks for entering the number " + input);
}
}
catch (Exception)
{
Console.WriteLine("Only numbers can be entered, ");
i--;
}
}
for (int i = 0; i < userGuesses.Length; i++) // Loop to display all the input values in the array
{
Console.Write(userGuesses[i]);
}
return userGuesses;
}
public static int[] RandomBingoNumbers() // Method for creating 10 random integers
{
RandomNrs = new int[10]; // Creates an array to store 10 integer
Random rnd = new Random();
for (int i = 0; i < RandomNrs.Length; i++)
{
num = rnd.Next(1, 25);
if (RandomNrs.Contains(num))
i--;
else
RandomNrs[i] = num;
}
return RandomNrs;
}
public static int PointsCalculator() //Method for calculating score
{
int points = 0; // Integer to hold the amount of correct guesses
for (int i = 0; i < 10; i++)
{
if (RandomNrs[i] == userGuesses[i]) // Check if the 10 user inputs is the same as the 10 randomized numbers
{
points++;
}
}
Console.WriteLine("Your Numbers: \n [{0}]", string.Join(", ", userGuesses)); // Display user inputed numbers
Console.WriteLine("Bingo Numbers: \n [{0}]", string.Join(", ", RandomNrs)); // Display the random bingo numbers
Console.WriteLine("You got: " + points + "poäng"); // Display the amount of correct guesses
return points;
}
}
}
Add a using System.Linq;
Lot of mistakes.
if (GetUserGuess == RandomBingoNumbers
) // Check if the 10 user inputs is the same as the 10 randomized numbers
{
points++;
}
should be
if (GetUserGuess().SequenceEqual(RandomBingoNumbers())
// Check if the 10 user inputs is the same as the 10 randomized numbers
{
points++;
}
And so many other mistakes, like the RandomNrs must be a static int[] declared outside the function. etc. etc..
This assignment is wrong RandomNrs[i] = new UserBingoNrs;. I'd suggest you to go over the entire syntax and usage of functions.
UPDATE 1
Instead of this
int[] RandomNrs = new int[10]; // Creates an array to store 10 integer
int[] userGuesses = new int[10]; // Creates the array to store 10 user inputs
you should use
RandomNrs = new int[10]; // Creates an array to store 10 integer
userGuesses = new int[10]; // Creates the array to store 10 user inputs
because RandomNrs and userGuesses is already defined globally.
and instead of
RandomNrs == userGuesses and RandomNrs != userGuesses
you must use
RandomNrs[i] == userGuesses[i]) and RandomNrs[i]!=userGuesses[i]
else if (RandomNrs[i] != userGuesses[i]) // If user guesses are not equal to array points
i--;
This will probably cause an infinite loop, instead of i--, do points--;
UPDATE 2
As simple as this
int num= rnd.Next(1, 25);
while(RandomNrs.Contains(num))
num = rnd.Next(1,25);
UPDATE 3
Change your PointsCalculator for loop to this
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
if (RandomNrs[i] == userGuesses[j]) // Check if the 10 user inputs is the same as the 10 randomized numbers
{
points++;
}
}

C# Code Verification Program

Alright so I am making a program to verify a 4 digit code.
The computer generates a 4 digit code
The user types in a 4 digit code. Their guess.
the computer tells them how many digits are
guessed correctly in the correct place and how many digits have
been guessed correctly but in the wrong place.
The user gets 12 guesses to either win – guess the right code. Or
lose – run out of guesses.
So basically, my program doesn't seem to actually verify whether the code is correct but i cant see why not because i have if and for loops for verification, please take a look.
class Program
{
public static Random random = new Random();
static void Main(string[] args)
{
int DigitOne = random.Next(0, 10);
int DigitTwo = random.Next(0, 10);
int DigitThree = random.Next(0, 10);
int DigitFour = random.Next(0, 10);
byte[] code = new byte[4];
code[0] = Convert.ToByte(DigitOne);
code[1] = Convert.ToByte(DigitTwo);
code[2] = Convert.ToByte(DigitThree);
code[3] = Convert.ToByte(DigitFour);
bool CodeCorrect = false;
Console.WriteLine(code[0] +""+ code[1] +""+ code[2]+""+code [3] );
Console.WriteLine("You have 12 guesses before you will be permenantly locked out.\n");
int AmountOfGuesses = 0;
while (AmountOfGuesses < 12 && !CodeCorrect)
{
Console.WriteLine("Enter 4 digit code to unlock the safe: ");
int[] UserCode = new int[4];
for (int i = 0; i < 4; i++)
{
UserCode[i] = Convert.ToInt32(Console.Read()) - 48;
}
if (UserCode.Length != 4)
{
Console.WriteLine("Error. Try Again.\n");
}
else
{
int UserDigitOne = UserCode[0];
int UserDigitTwo = UserCode[1];
int UserDigitThree = UserCode[2];
int UserDigitFour = UserCode[3];
for (int i = 0; i < 4; i++)
{
if (UserCode[i] == code[i])
{
Console.WriteLine("The digit at position " + (i + 1) + " is correct.");
}
}
if (UserCode[0] == code[0] && UserCode[1] == code[1] && UserCode[2] == code[2] && UserCode[3] == code[3])
{
CodeCorrect = true;
Console.WriteLine("Code Correct. Safe unlocked.");
}
}
AmountOfGuesses++;
}
if (AmountOfGuesses > 12)
{
Console.WriteLine("Code Incorrect. Safe Locked permenantly.");
}
Console.ReadLine();
}
If you step through the code after it generated the number 1246, and then input the same number from the command line, convert it to a char array, then convert each char to a byte, you'll get the following four bytes:
49 50 52 54
These correspond to the ASCII representations of each char, NOT the actual numbers.
Try something like this:
int[] input = new int[4];
for(int i = 0; i < 4; i++ )
{
input[i] = Convert.ToInt32(Console.Read()) - 48;
}
The -48 should turn your ASCII code into the actual numerical representation that was provided. Console.Read() reads individual characters rather than the full line.
Also, you don't have to say:
CodeCorrect == false
This is more simply represented as:
!CodeCorrect
Similarly, if it was set to true, it would just be:
CodeCorrect
I also suggest using a for loop to set multiple elements in an array rather than manually writing out each line of code. It's not a big deal for small arrays, but it's good practice.
UPDATE: Here's a revised version of the full program:
class Program
{
public static Random random = new Random();
static void Main(string[] args)
{
int[] randCombination = new int[4];
for (int i = 0; i < 4; i++)
{
randCombination[i] = random.Next(0, 10);
Console.Write(randCombination[i].ToString());
}
bool CodeCorrect = false;
Console.WriteLine("\nYou have 12 guesses before you will be permenantly locked out.\n");
int AmountOfGuesses = 0;
while(AmountOfGuesses < 12 && !CodeCorrect)
{
Console.WriteLine("Enter 4 digit code to unlock the safe: ");
int[] UserCode = new int[4];
string input = Console.ReadLine();
int n;
bool isNumeric = int.TryParse(input, out n);
int correctCount = 0;
if(input.Length != 4 || !isNumeric)
{
Console.WriteLine("Error. Input code was not a 4 digit number.\n");
}
else
{
for(int i = 0; i < 4; i++)
{
UserCode[i] = Convert.ToInt32(input[i]) - 48;
if(UserCode[i] == randCombination[i])
{
Console.WriteLine("The digit at position " + (i + 1) + " is correct.");
correctCount++;
}
}
if(correctCount == 4)
{
CodeCorrect = true;
Console.WriteLine("Code Correct. Safe unlocked.");
}
}
AmountOfGuesses++;
}
if(AmountOfGuesses >= 12)
{
Console.WriteLine("Code Incorrect. Safe Locked permenantly.");
}
Console.ReadLine();
}
}
A couple of things were changed:
Added a for loop at the top that generates a random number, enters it into an array of ints and then prints it to standard output.
I changed the way user input is read back to the Console.ReadLine(). The reason for this is to check if the user inputted a four digit integer. the int.TryParse statement makes sure the input is an int, and the Length property checks the length.
I also used a counter to count each correct guess. If 4 correct digit guesses were made, the safe is unlocked.
Your final if statement would never have evaluated because Amount of Guesses would equal 12, not be greater than it. Changed it to >= from >. Always be on the lookout for small things like this.
EDIT #2: For more information on int.TryParse, see the following:
http://www.dotnetperls.com/int-tryparse
How the int.TryParse actually works
You are comparing numbers with the character representation of a number. Each value of code[] represents an actual number. You then compare those values with the values in UserCode which is a string, meaning there is a character at each index. It is never the case that ((byte)'4') == ((byte)4) (using 4 as an example, but works for any numerical digit).
One way around this is to parse each user input character into a byte using the byte.Parse method.
For fun learning purposes look at the output from the following code:
for (char i = '0'; i <= '9'; i++)
{
Console.WriteLine("char: " + i + "; value: " + ((byte)i));
}
The output is actually:
char: 0; value: 48
char: 1; value: 49
char: 2; value: 50
char: 3; value: 51
char: 4; value: 52
char: 5; value: 53
char: 6; value: 54
char: 7; value: 55
char: 8; value: 56
char: 9; value: 57
This is due to string encoding.
I would also recommend that one you have your code working that you submit it to the fine folks at the Code Review site to review other aspects of the code which could use work.

Different random outcomes

How can i generate different random numbers in short time?
For example:
Number = 20;
if (Number > 0)
{
AddEffect(rand.Next(0,100);
Number--;
}
In this example, rand.Next gives me twenty times the same number. Is there any way to force a change?
I think you're trying to say:
var rand = new Random();
var Number = 20;
while (Number > 0)
{
// rand.Next(0,100); // this will give 20 different numbers btw
AddEffect(rand.Next(0,100));
Number--;
}
but otherwise, seems fine
int totalNumbers = 20;
Random rand = new Random();
for (int i = 0; i < totalNumbers; i++)
{
AddEffect(rand.Next(0, 101)); // a number between -1 and 101, min: 0, max: 100
}
Is this what you mean? This is an easy and clear way to generate some random numbers.
More info here: http://www.dotnetperls.com/for

How do you make an array of 1000 random integers between 1-100

How do you program c# to make an array of 1000 random integers between 1-100.
And then how do you get when a person enters a number e.g. 68 how can you make the program say 68 appears so and so many times or that it doesn't work at all!
I am not asking for the complete answer I just need a hint where to get started.
Here is what I know:
I have to use the random function and an if but I dont know what to put where!
int[] iArray = new int[1000];
int counter = 0;
Random random = new Random();
for(int i = 0; i < 1000; i++){
iArray[i] = random.Next(1, 101); //1 - 100, including 100
}
int number = Convert.ToInt32(Console.ReadLine());
foreach(int i in iArray){
if(i == number)count++;
}
Console.WriteLine("The number "+ number+" appears "+count+" times!");
Start with a for loop, in each iterative you call the random function and put the result in a public list. After that you make an dialog for the user to type a number. You can serach with lambda expression in the list to see how many matches you get.
Make an array of 1000 random integers between 1-100 and when a person enters a number e.g. 68 how can you make the program say 68 appears so and so many times
I think you're looking for a method like this:
private static Random rnd = new Random();
public static IEnumerable<int> getRandomNumbers(int count, int lowerbound, int upperbound, int specialNumber = int.MinValue, int specialNumberCount = int.MinValue)
{
List<int> list = new List<int>(count);
HashSet<int> specialNumPositions = new HashSet<int>();
if (specialNumberCount > 0)
{
// generate random positions for the number that must be create at least n-times
for (int i = 0; i < specialNumberCount; i++)
{
while (!specialNumPositions.Add(rnd.Next(0, count)))
;
}
}
while (list.Count < count)
{
if (specialNumPositions.Contains(list.Count))
list.Add(specialNumber);
else
list.Add(rnd.Next(lowerbound, upperbound + 1));
}
return list;
}
which you can use in this way:
// ensure that 68 is generated at least 10 times
var list = getRandomNumbers(1000, 1, 100, 68, 10);
Demo
If you instead just want to know how often a number appears in the list, you can ue Linq:
int count = list.Count(i => i == 68);

Categories