How can i use ' ++ i ' inside this situation? - c#

I want to draw a random name for an event where users can win items specified by their ID (1,2,3 etc.). The random name part is ok by now but how can i display the result like:
The ID : 1 winner is: 'the random name'
The ID : 2 winner is: 'the random name'
etc...
till ID : 27
static void Main(string[] args)
{
string[] Names = { "Erik", "Levente", "Noel", "Áron", "Krisztián", "Kristóf", "Bence", "Roland", "Máté", "László", "Bálint" ,
"Regina", "Brigitta", "Gréta", "Hédi", "Hanna", "Boglárka", "Jázmin", "Réka", "Alexandra", "Rebeka", "Lili", "Luca", "Zsófi"};
List<string> alreadyUsed = new List<string>();
Random r = new Random();
while (alreadyUsed.Count < Names.Length)
{
int index = r.Next(0, Names.Length);
if (!alreadyUsed.Contains(Names[index]))
{
alreadyUsed.Add(Names[index]);
Console.WriteLine("The ID : 1 winner is: " + Names[index]);
}
}
Console.ReadKey(true);
}

Here is a refactored appraoch without that bad performing alreadyUsed. First I randomize the array, second I iterate and display each item with a incrementing index / id.
string[] Names = { "Erik", "Levente", "Noel", "Áron", "Krisztián", "Kristóf", "Bence", "Roland", "Máté", "László", "Bálint" , "Regina", "Brigitta", "Gréta", "Hédi", "Hanna", "Boglárka", "Jázmin", "Réka", "Alexandra", "Rebeka", "Lili", "Luca", "Zsófi"};
Random r = new Random();
Names = Names.OrderBy(_ => r.Next()).ToArray();
for(int i=0;i< Names.Length;i++)
{
Console.WriteLine("The ID : " + (i+1) + " winner is: " + Names[i]);
}

while (alreadyUsed.Count < Names.Length)
{
int index = r.Next(0, Names.Length);
if (!alreadyUsed.Contains(Names[index]))
{
alreadyUsed.Add(Names[index]);
Console.WriteLine("The ID : " + alreadyUsed.Count + " winner is: " + Names[index]);
}
}
You do not need ++i, you already have the position contained in alreadyUsed.Count that will increment itself as you use alreadyUsed.Add(...).
Try it online

Related

Cannot create different random numbers in loop

I am new to C# and am having difficulty understanding where I am going wrong in this random number guessing game I have created. I have tried to add a random.next command in the do while loop on line 30, when I run the program it says my guess is either too high or too low, I do not understand what is going wrong. Here is the unfinished code:
static void Main(string[] args)
{
Random random = new Random();
int numberToGuess = random.Next(100) + 1;
int userGuess = 0;
string name;
Console.WriteLine("What is your name?");
name = Convert.ToString(Console.ReadLine());
Console.WriteLine("In this game you need to guess which number the computer has picked in the range of 1 to 100."
+ Environment.NewLine + "If the number you enter is too high or too low the program will display this, " +
Environment.NewLine + "try to make the least amount of guesses as possible!" + Environment.NewLine
+ "==========================================================================================================");
do
{
do
{
Console.Write("Enter your guess: ");
userGuess = Convert.ToInt32(Console.ReadLine());
if (userGuess > numberToGuess)
{
Console.WriteLine(userGuess + " is too high!");
}
else if (userGuess < numberToGuess)
{
Console.WriteLine(userGuess + " is too low!");
}
else
{
Console.WriteLine(userGuess + " SPOT ON! Congratulations.");
}
numberToGuess = random.Next(100) + 1;
} while (userGuess != numberToGuess);
Console.WriteLine("Do you want to continue?");
} while (Console.ReadLine().ToUpper() == "YES");
}
If I remove numberToGuess = random.Next(100) + 1; the code works fine but repeats the same random number.
Please Help.
Debug your application replacing
Console.Write("Enter your guess: ");
With
Console.Write("Enter your guess (" + numberToGuess + "): ");
You will see that the numberToGuess is changing every time... you should comment that line and use only the fist random number generated.
Your number of guess range is very high 1 to 100 and after every time you are generating random number again. Just reduce you size of random generator number for example
int numberToGuess = random.Next(5) + 1;
First check its working good or not then think about expanding it.
This method will return a truly random number.
Public Shared Function RandomInteger(min As Integer, max As Integer) As Integer
Dim Rand As New System.Security.Cryptography.RNGCryptoServiceProvider
Dim scale As UInteger = UInteger.MaxValue
While scale = UInteger.MaxValue
' Get four random bytes.
Dim four_bytes As Byte() = New Byte(3) {}
Rand.GetBytes(four_bytes)
' Convert that into an uint.
scale = BitConverter.ToUInt32(four_bytes, 0)
End While
' Add min to the scaled difference between max and min.
Return CInt(min + (max - min) * (scale / CDbl(UInteger.MaxValue)))
End Function

Random Sequence Generator in C#

I want to build a sequence randomiser mobile app in c#. I would like to retrieve the smallest and the largest number in an interval from two diffrent text boxes, and after I click the Generate button to display the random sequence of all the numbers in a new text box.
My code only displays one number. What's wrong with it?
Thanks.
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private void button_Click(object sender, RoutedEventArgs e)
{
int seed = 345;
var result = "";
int min = Convert.ToInt32(textBox.Text);
int max = Convert.ToInt32(textBox2.Text);
Random r3 = new Random(seed);
for (int i = min; i < max; i++)
{
ecran.Text = (/*"," + r3.Next(min, max)*/i).ToString();
}
}
To clarify what was wrong with your solution:
Inside the loop you were constantly reassigning the value of ecran.Text.
i.e.
1st loop cycle > ecran.Text = ", " + 77
2nd loop cycle > ecran.Text = ", " + 89
//Value of ecran.Text after 1st cycle is ", 77"
//Value of ecran.Text after 2nd cycle is ", 89"
Overriding the value of ecran.Text with each iteration.
Fixed by adding a plus symbol in front of equals ecran.Text += ", " + LOGIC
This happens because you assign sequence values to ecran.Text in a loop. Instead, you should create a string representation of the sequence, and assign it at the end.
Use Shuffle<T> method from this Q&A:
int min = Convert.ToInt32(textBox.Text);
int max = Convert.ToInt32(textBox2.Text);
if (max < min) return;
var sequence = Enumerable.Range(min, max-min+1).ToList();
Shuffle(sequence);
ecran.Text = string.Join(",", sequence);

C#, Extensive wage calculation with Arrays

Here's a description of what I need to do:
Write a program that first initializes arrays via user input with the names and wages of all employees, then prompts the user for the hours worked for each employee and computes their regular pay, overtime pay, gross income, federal tax deduction (10% of gross), state tax deduction (5% of gross), and net income. After the last employee is processed, the program displays totals for regular pay and overtime pay and the names and gross incomes for the employees that earned the most and least amount.
I'm stuck at the if-else statement, I'm fairly new to c# and still don't know a lot, basically I'm stuck, and I'm in a rush to get this done, I would appreciate any help on this.
using System;
using static System.Console;
namespace Exercise3
{
class ArrayCalculations
{
static void Main(string[] args)
{
double hours,
regularPay,
overtimePay,
grossPay,
netPay,
stateTax,
fedTax;
const double FED_TAX = .10;
const double STATE_TAX = .05;
const double REG_HOURS = 40.0;
const double OVERTIME = 1.5;
string[] name = new string[5];
double[] wage = new double[5];
for (int i = 0; i < name.Length; i++)
{
Write("Please enter name: ", (i + 1));
name[i] = ReadLine();
Write("Please enter your hourly wage: ", (i + 1));
wage[i] = Convert.ToDouble(ReadLine());
Write("Please enter hours worked this week", (i + 1));
hours = Convert.ToDouble(ReadLine());
}
WriteLine();
for (int i = 0; i < name.Length; i++)
{
WriteLine("Name: " + name[i] + " Wage: " + wage[i]);
}
if (hours <= 40)
{
regularPay = hours * wage;
overtimePay = 0;
}
else
{
// ??
}
}
}
}
1.) Try to split your code into logic pieces:
private double CalculateWage(double hours, double wage)
{
return (hours * wage);
}
Or like this:
private string GetUserInput_String(string message, int index)
{
Write(message, index);
return ReadLine();
}
Now you can call it like this:
name[i] = GetUserInput_String("Please enter name: ", (i + 1))
Same for doubles.
private string GetUserInput_Double(string message, int index)
{
try
{
Write("Please enter wage: ", (i + 1));
return Convert.ToDouble(ReadLine());
//OR
double result;
double.TryParse(ReadLine(),out result);
if(result != 0)
{
return result;
}
return null;
}
catch(Exception ex) //Catch all thrown Exception
{
Write(ex.Message);//Handle Exceptions (log, retry,..)
return null; //When retunring null check for null when working with the returned value !!!
}
}
2.) Use Try {} catch {}
Catch and handle exception ALWAYS when casting, converting, etc.
Check out Linq:
private void PrintWages(string[] names, double[] wages)
{
names.ToList().ForEach(x => Console.WriteLine($"Name: {x} Wage: {wages[names.ToList().IndexOf(x)]}"));
}
This does the following:
string[] names = {"Anna", "Peter", "Marc"};
string[] wages = { "1500", "2000", "3500" };
names.ToList().ForEach(x => Console.WriteLine($"Name: {x} Wage: {wages[names.ToList().IndexOf(x)]}"));
Output:
Name: Anna Wage: 1500
Name: Peter Wage: 2000
Name: Marc Wage: 3500
So what have I done here:
using System.Linq; - Adds the "Foreach" and other extension methods to Collections
array.ToList() => array converted to list
Foreach element in names I called WriteLine();
names.ToList().IndexOf(x) gives me the index of the current element to use in wages[index]
I condesed the output via Interplated Strings
So the more or less complete result would be sth. like this
//Care of naming !
// string[] names - its a sort of collection of names so dont call it name.
// name would be ONE item of that array
//I recommend using List<sting> / List<double> here !
List<string> employees = new List<string>();
List<double> wages = new List<double>();
//Or way better => Dictionairy<string, double>(),
//A Dictionairy has a Key (unique) and a correlating value
Dictionary<string, double> EmployeeWages = new Dictionary<string, double>();
int employeesToAdd = 0;
try
{
Console.Write("How many employees would you like to add ?");
employeesToAdd = int.Parse(Console.ReadLine());
}
catch (Exception ex)
{
Console.Write($"Error: {ex.Message}");
return;
}
//We reach this line only if employeesToAdd has a value !
for (int i = 0; i < employeesToAdd; i++)
{
EmployeeWages.Add(GetUserInput_String("Please enter name: "), GetUserInput_Double("Please enter your wage: "));
}
PrintResult(EmployeeWages);

IEnumberable.Except to display differences in textbox c sharp

I am new to C # and I am getting stuck on using IEnumerable.Except. What I am trying to do is get the difference of 2 sequences of 100 random dice rolls using 2 die. I have my die rolls and totals good to go. My differences are not showing in my txtDifference textbox at all. I am not sure if I have it placed in the correct spot or if it isn't written correctly. The code itself has no errors and I am not sure how to fix it. Here is my code, any help is greatly appreciated!!
private void btnRoll_Click(object sender, EventArgs e)
{
//create random and lists
randomizer = new Random();
List<int> numbers = new List<int>();
List<int> secondNumbers = new List<int>();
//for loop for 1st sequence
for (i = 1; i < 100; i++)
{
string mssg = string.Empty;
die1 = randomizer.Next(1, 7);
die2 = randomizer.Next(1, 7);
dieRoll1.Text = die1.ToString();
dieRoll2.Text = die2.ToString();
rollValue = die1 + die2;
//add to collection.
numbers.Add(i);
//display results
txtResults.Text += string.Concat(dieRoll1.Text, " ", dieRoll2.Text, " ", rollValue, " ", Environment.NewLine);
}
//loop for second sequence.
for (i = 1; i < 100; i++)
{
string mssg = string.Empty;
die1 = randomizer.Next(1, 7);
die2 = randomizer.Next(1, 7);
dieRoll1.Text = die1.ToString();
dieRoll2.Text = die2.ToString();
rollValue = die1 + die2;
//add to collection.
secondNumbers.Add(i);
//display results in second text box
txtResults2.Text += string.Concat(dieRoll1.Text, " ", dieRoll2.Text, " ", rollValue, " ", Environment.NewLine);
}
// IEnumerable for comparison between the two sequences
IEnumerable<int> onlyInFirstSet = numbers.Except(secondNumbers);
//foreach to display the differences between the sequences
foreach (int number in onlyInFirstSet)
txtDifference.Text = number.ToString();
}
txtDifference.Text = number.ToString(); will show only last number in the set as you are overwriting the value on each iteration.
I think you are looking for showing all of the values:
txtDifference.Text = String.Join(",", onlyInFirstSet);
Both loops iterate from 1 to 100. Then, in both cases, you're adding the value of i to the lists... which means both lists end up with the values 1 to 100 in them.
numbers.Add(i);
secondNumbers.Add(i);
So the following line of code always results in an empty list. It removes the second collection of numbers 1 to 100 from the first collection of numbers 1 to 100.
IEnumerable<int> onlyInFirstSet = numbers.Except(secondNumbers);
Instead, add the rollValue value to your list, not the variable your foreach loop is iterating over:
rollValue = die1 + die2;
//add to collection.
numbers.Add(rollValue);
Same goes for your second loop and collection:
rollValue = die1 + die2;
//add to collection.
secondNumbers.Add(rollValue);

proper way assign numer to elements in a List Collection

I am looping through a list of elements, and would like to assign a number to where each element resides in the Collection for deletion puposes. My code below, just gives me the count, is there another option to achieve this. Ex.
0 cat
1 dog
2 fish
ect..
foreach (string x in localList)
{
{
Console.WriteLine( localList.Count + " " + x);
}
}
be old school and go back to a standard for loop:
for(int i = 0; i < localList.Count; ++i)
{
string x = localList[i];
// i is the index of x
Console.WriteLine(i + " " + x);
}
If you really want to get fancy, you can use LINQ
foreach (var item in localList.Select((s, i) => new { Animal = s, Index = i }))
{
Console.WriteLine(item.Index + " " + item.Animal);
}
you have to use a for loop or use a separate index:
for(int i = 0; i < localList.Count;i++)
{
Console.WriteLine( i + " " + localList[i]);
}
Depending on the collection type you are using you can use something like
foreach (string x in locallist)
{
Console.WriteLine(locallist.IndexOf(x) + " " + x);
}
regds, perry

Categories

Resources