I am making a lottery program, it's basic and only view-able via console at the moment.
The program executes the following:
User enters 6 numbers ranging from 1 - 46.
Program generates 6 random numbers with the same range.
Program compares indexes to see which numbers the user managed to match with the program.
Program displays the same numbers which the user got right.
But, currently, there is a bug in my code and I am not sure how to proceed.
For example, my inputs are: 1 , 2 , 3 , 4 , 5 , 6
The program generated 6 numbers and I've managed to hit number 2 and 6.
But, the program only displayed number 2.
This means that my code is not comparing each and every index, and I am not sure why.
The user array is lucky, and the program generated array is numbers.
Console.WriteLine("The winning numbers are: , " );
int[] winning = new int[6];
int w = 0;
var x = 0;
var j = 0;
Console.WriteLine("The winning numbers are: , " );
int[] winning = new int[6];
int w = 0;
var x = 0;
var j = 0;
while (x< 6)
{
if (lucky[j] == numbers[x])
{
winning[w] = numbers[x];
Console.WriteLine(winning[w]);
w++;
}
j++;
if (j == 5)
{
x++;
j = 0;
}
}
There is no need to do all that looping these days. LINQ's Intersect function makes it a single function call:
var Matches = lucky.Intersect(numbers);
will return all matching numbers from the two lists in Matches.
A looping equivalent might look like this (writing off the top of my head):
List<int> winning = new List<int>();
for(int i=0; i<numbers.Length; i++)
{
if(numbers.Contains(lucky[i])
winning.Add(lucky[i]);
}
To display it on console, use a simple loop:
for(int i=0; i<winning.Length; i++)
{
Console.WriteLine(winning[i]);
}
Since you run over an array, the standard procedure would be to use a for loop.
Here are three solutions that solve the problem.
Each one is complete and can be tested on https://dotnetfiddle.net/
Linq: Use the Intersects method to find the common items between two IEnumerables.
using System;
using System.Linq;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
// at this point unique numbers have been generated and inputted
int[] numbers = { 1, 2, 3, 4, 5, 6 };
int[] guesses = { 2, 6, 7, 8, 9, 10 };
List<int> matches = new List<int>(numbers.Intersect(guesses));
foreach (int n in matches)
{
Console.WriteLine("Hit: " + n.ToString());
}
}
}
Using a single for loop and checking with the Contains method (Array implements the IList interface) if the other array contains the number at the current index. You could also use a foreach loop, since you don't care about the indexes.
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
// at this point unique numbers have been generated and inputted
int[] numbers = { 1, 2, 3, 4, 5, 6 };
int[] guesses = { 2, 6, 7, 8, 9, 10 };
List<int> matches = new List<int>();
for (int i = 0; i < guesses.Length; i++)
{
if (numbers.Contains(guesses[i]))
{
Console.WriteLine("Hit: " + guesses[i].ToString());
matches.Add(guesses[i]);
}
}
}
}
Of you could use a nested for loops, one for each array, to check each number from one array against every number of the other one.
Again you could use foreach loops.
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
// at this point unique numbers have been generated and inputted
int[] numbers = { 1, 2, 3, 4, 5, 6 };
int[] guesses = { 2, 6, 7, 8, 9, 10 };
List<int> matches = new List<int>();
for (int i = 0; i < guesses.Length; i++)
{
for (int j = 0; j < numbers.Length; j++)
{
if (guesses[i] == numbers[j])
{
Console.WriteLine("Hit: " + guesses[i].ToString());
matches.Add(guesses[i]);
break; // optional, we found the number and can leave the loop. Not optional if your lottery allows numbers to happen more than once.
}
}
}
}
}
As for the question why your code isn't working:
You set j = 0 when j == 5 just after j++, meaning you set j to 0 after checking index 4. While I do not want to encourage such unorthodox styles you could fix it by comparing j == 6. Again, this approach makes your code unreadable, please use one of the other solutions.
using System;
public class Program
{
public static void Main()
{
// at this point unique numbers have been generated and inputted
int[] numbers = { 1, 2, 3, 4, 5, 6 };
int[] guesses = { 2, 6, 7, 8, 9, 10 };
int[] winning = new int[6];
int w = 0;
var x = 0;
var j = 0;
while (x < 6)
{
if (guesses[j] == numbers[x])
{
winning[w] = numbers[x];
Console.WriteLine(winning[w]);
w++;
}
j++;
if (j == 6)
{
x++;
j = 0;
}
}
}
}
I think what you are looking for is that finding common items from two arrays.
var ar1 = new int[] {1,2,3,4,5,6};
var ar2 = new int[] {2,3,4,6,7,8};
var common = ar1.Intersect(ar2);
In your case
var common = lucky.Intersect(numbers);
Using loops
// Array size is fixed here.
for (int i = 0; i < 6; i++) // OR i < lucky.Length (guessing numbers)
{
if (numbers.Contains(lucky[i]))
{
// NUMBERS DETECTED
}
}
The issue is with the checking of last index(5 in this case). It is never happening!
//say j = 4
lucky[4] == numbers[x] //false/true, whatever value of x is
You increment j
//j is now 5
if(j==5)
Yes and then you are resetting it to 0.
last index which is 5 in this case will never be checked in the next iteration
Solution-
if(j == 6)
I ended up building 2 methods that basically do what everyone here has told me.
Since I did not yet learn LinQ I couldn't understand , I didn't learn LIST as well so I couldn't use it as well.
My functions are like this:
First function: checks the indexes of a specified array
code:
static bool DoesExists(int[] a, int Value)
{
for (int i = 0; i < a.Length; i++)
{
if (Value == a[i])
{
return true;
}
}
return false;
}
second function checks how many repeated elements are in 2 arrays
code:
static int CountCorrect(int[] pc, int[] user)
{
int count = 0;
for (int i = 0; i < user.Length; i++)
{
if (DoesExists(pc, user[i]))
{
count++;
}
}
return count;
}
when using these 2 in conjunction , it solves my problem.
thanks to everyone for taking the time to give me good ideas.
I'm working on a project. The user inputs a value(n) and that value is multiplied by 2. Then the user inputs the exact same times a new number (n*2). So I have to figure out if every couple of numbers are equal and if not to print the biggest difference between one of the couples. In order to do that I need Biggest value in an array and somehow to check if all elements in an array are equal. I'm new to C# and I don't know much about arrays.(btw sorry about the use of language, I'm foreigner)
I came up with this code so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EqualPairs
{
class Program
{
static void Main(string[] args)
{
int n = int.Parse(Console.ReadLine());
int sum = 0;
int diff = 0;
int[] sumAll = new int[n];
int[] differ = new int[n];
for (int i = 1; i <= n; i++)
{
sum = 0;
diff = 0;
for (int j = 1; j <= 2; j++)
{
int number = int.Parse(Console.ReadLine());
sum = sum + number;
diff = Math.Abs(diff - number);
}
sumAll[i - 1] = sum;
differ[i - 1] = diff;
}
}
}
}
I'm not sure exactly what you're trying to do with your program, but to answer your questions:
Find max value in an array:
int maxValue = yourArray.Max();
Check if all values in your array are equal (using System.Linq):
int first = yourArray.First();
bool allElementsEqual = yourArray.All(x => x == first);
Edit based on OP's comment:
If I were you, I'd create an intermediate array couplesArray. Not sure how you're planning to set up your inputs and all that, but I'm assuming yourArray has an even number of values. I don't know how you're defining max difference and all that, so perhaps drop some of my Math.Abs() calls:
int[] yourArray = { 1, 2, 0, 3, 4, -1};
int[] couplesArray = new int[yourArray.Count() / 2];
for (int i = 0; i < couplesArray.Length; i++)
{
couplesArray[i] = yourArray[2 * i] + yourArray[2 * i + 1];
}
int first = couplesArray.First();
bool allElementsEqual = couplesArray.All(x => x == first);
int maxDifference = Math.Max(Math.Abs(couplesArray.Max()), Math.Abs(couplesArray.Min()));
string outputString = allElementsEqual ? "Equal" : maxDifference.ToString();
Console.WriteLine(outputString);
My task is to add a very big number to another and print the result.
Here is my implementation, it should give 1000 as output but it writes 0000.
How it should work:
if the two number has equal length:
just /10 for the digit %10 for the remainder. If the length of the result is bigger than the original add the last remainder to the last element of the output array.
if the two number has different length:
sum the intersection part and add the remainder (in temp) to the relative complementl.
What is wrong?
static int[] SumOfBigNumbers(int[] firstNumber, int[] secondNumber)
{
int temp = 0;
int maxLength = (Math.Max(firstNumber.Length, secondNumber.Length));
int minLength = (Math.Min(firstNumber.Length, secondNumber.Length));
int[] output = new int[maxLength + 1];
//sum of equal part
for (int counter = 0; counter < minLength; counter++)
{
output[counter] = (firstNumber[counter] + secondNumber[counter] + temp) % 10;
temp = (firstNumber[counter] + secondNumber[counter] + temp) / 10;
}
//exceptions add the temp to the bigger array
if (temp!=0)
{
//if first array is bigger than the second
if (firstNumber.Length > secondNumber.Length)
{
for (int i = minLength; i < maxLength + 1; i++)
{
output[i] = (firstNumber[i] + temp) % 10;
temp = (firstNumber[i] + temp) / 10;
}
}
//if second array is bigger than the first
else if (firstNumber.Length < secondNumber.Length)
{
for (int i = minLength; i < maxLength + 1; i++)
{
output[i] = (secondNumber[i] + temp) % 10;
temp = (secondNumber[i] + temp) / 10;
}
}
//if two number has equal length but there is temp left
else
{
output[maxLength] = temp;
}
}
return output;
}
static void Main()
{
int[] firstArray = new int[3] { 0, 0, 5 };
int[] secondArray = new int[3] { 0, 0,5 };
int[] output = SumOfBigNumbers(firstArray, secondArray);
foreach (var i in output)
{
Console.WriteLine(output[i]);
}
}
Edit: better if I copy the task: Write a method that calculates the sum of two very long positive integer numbers. The numbers are represented as array digits and the last digit (the ones) is stored in the array at index 0. Make the method work for all numbers with length up to 10,000 digits.
While BigInteger is a better way to handle big numbers, I think your bug is in while printing the output. try this:
foreach (var i in output)
{
Console.WriteLine(i);
}
also this will print 0001, better reverse it while printing
Your code works fine but you have a small bug where you display the output array.
You do a foreach (var i in output) {, but you use the i as an index, which it isn't. It is already the actual value. Just write the i to the console.
foreach (var i in output)
{
Console.WriteLine(i);
}
// Output:
// 0
// 0
// 0
// 1
Or use a for loop to go through the array by index.
for (int i = 0; i < output.Length; i++)
{
Console.WriteLine(output[i]);
}
// Output:
// 0
// 0
// 0
// 1
The problem in project Euler says:
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.
When I test it with the numbers < 10, it calculates 23, but when I try it with 1000, it gives the wrong answer. Please help :)
Code:
using System;
using System.Diagnostics;
using System.Collections.Generic;
namespace Test
{
class MainClass
{
public static void Main (string[] args)
{
//Initialisation
Console.WriteLine ("==============================");
Console.WriteLine ("Project Euler - Problem 1 - Multiples of 3 and 5 - Test");
Console.WriteLine ("Initialising");
Stopwatch stopwatch = new Stopwatch ();
stopwatch.Start ();
Console.WriteLine ("==============================");
HashSet<int> list = new HashSet<int> (); //Creates a list
int sum = 0;
//Add every multiple of 3 to the list
for (int x = 3; x < 10; x = x + 3) {
list.Add (x);
}
//Add every multiple of 5 to the list
for (int y = 5; y < 10; y = y + 5) {
list.Add (y);
}
//Remove every duplicate from the list
for (int z = 15; z <= 1000; z = z +15) {
list.Remove (z);
}
foreach (int x in list) {
sum = sum + x;
}
//Termination
Console.BackgroundColor = ConsoleColor.DarkRed;
Console.WriteLine ("==============================");
stopwatch.Stop ();
Console.WriteLine ("Time elapsed: {0}", stopwatch.Elapsed);
Console.WriteLine ("==============================");
Console.WriteLine ("Sum: " + sum);
Console.WriteLine ("==============================");
Console.WriteLine ("Terminating");
Console.WriteLine ("==============================");
}
}
}
You are using HashSet.
HashSet is an unordered collection containing unique elements
It doesn't store duplicate entries. You don't need to remove it.
Just remove your 3rd for loop.
Instead of having multiple for loops you could also have one and use the modulus operator. This will void the duplicates you are adding.
for(int i = 0; i < 1000; ++i)
{
if(i % 3 == 0 || i % 5 == 0)
{
// Add to list
}
}
You don't need to remove multiples of 15:
const int N = 1000;
//Add every multiple of 3 to the list
for (int x = 3; x < N; x += 3) {
list.Add(x);
}
//Add every multiple of 5 to the list
for (int y = 5; y < N; y += 5) {
list.Add(y);
}
int sum = list.Sum();
I've been working on this assignment for my programming class for a little bit and though I had it solved. A little info for anyone interested: My task is to find the score of the competitor from an array of scores (eg, int[] scores = 4, 5, 6 , 7, 8, 9). BUT I must not include the highest and lowest values when adding the rest of the scores together (eg, score would = 5+6+7+8 (no including 4 and 9)).
My solution when we were allowed to use linq was as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Scoring {
class Program {
static void Main(string[] args) {
int[] scores = { 4, 7, 9, 3, 8, 6 };
remove_duplicates(scores);
console_text(scores);
ExitProgram();
}
static void remove_duplicates(int[] scores) { //removes duplicat values from array
var pScores = scores.Distinct().ToArray();
}
static int result(int[] pScores) { //calculates results by removing max and min scores, then adding the remaining.
return pScores.Sum() - pScores.Max() - pScores.Min();
}
static void console_text(int[] pScores) { //renders the text in the consol window
int final_score = result(pScores);
Console.Write("Competitor your scores were " );
foreach (int i in pScores) {
Console.Write(" " + i);
}
Console.WriteLine("\r\n" + " and your score was " + final_score);
}
static void ExitProgram() {
Console.Write("\n\nPress any key to exit program: ");
Console.ReadKey();
}//end ExitProgram
}
}
So I thought I was done, but now I have recieved and email stating:
"cannot use any system.array methods nor can you use any functionality of Linq or any other library class you may discover"
This has me a bit lost and confused, any help at all would be appreciated.
Thanks
Here is one option. The only thing that is not very clear is weather if there are two equal values which are also min values or max values they should be removed both or only one max value and one min. I remove just one min and one max value:
int[] arr = new int[] { 2, 2, 3, 4, 5, 6, 6 };
int Lowest = arr[0];
int Highest = arr[0];
int sum = 0;
for (int i = 0; i < arr.Length; i++)
{
if (Lowest > arr[i])
{
Lowest = arr[i];
}
if (Highest < arr[i])
{
Highest = arr[i];
}
sum += arr[i];
}
sum -= (Lowest + Highest);
Console.WriteLine("The sum withot the highest and lowest score is : {0}", sum);
and if you and to remove all duplicated min and max scores add this before summing the final score:
int[] arrOfHighest = new int[arr.Length];
int[] arrOfLowest = new int[arr.Length];
int minCounter = 0;
int maxCounter = 0;
for (int i = 0; i < arr.Length; i++)
{
if (Lowest == arr[i])
{
arrOfLowest[minCounter] = arr[i];
minCounter++;
}
if (Highest == arr[i])
{
arrOfHighest[maxCounter] = arr[i];
maxCounter++;
}
}
int sumLoewst = 0;
for (int i = 0; i < arrOfLowest.Length; i++)
{
sumLoewst += arrOfLowest[i];
}
int sumHighest = 0;
for (int i = 0; i < arrOfHighest.Length; i++)
{
sumHighest += arrOfHighest[i];
}
sum -= (sumLoewst + sumHighest);
So the final touch based on the additional information. Since you want the min and max value to be added only once each inthe code above - sum -= (sumLoewst + sumHighest); right after this add:
sum -= (sumLoewst + sumHighest);
sum += (Highest + Lowest);
This way you will have all other values summed, no matter how times they appear in the array. And only one MAX and one MIN value added to the sum.