C#: finding the sum in a for loop - c#

the question asks:
Write a program that reads from the screen two integer numbers min and max and outputs the sum of all squares of integers between min(including) and max(not including). If min is bigger than max, the program should output "min should be smaller than max!". Example:
>4
>9
190 (= 4² + 5² + 6² + 7² + 8²)
>14
>3
min should be smaller than max!
my code:
using System;
namespace ForLoops
{
class SumOfSquares
{
static void Main(string[] args)
{
int sum = 0;
int min = int.Parse(Console.ReadLine());
int max = int.Parse(Console.ReadLine());
for (int i = min; i < max; i = i++)
{
sum = i * i;
}
Console.WriteLine(sum);
}
}
}
I keep getting 68 when i should get 190.

So the answer is you make it to For Loop statement so you can have the 2 examples. Answers at the same time.
int min = int.Parse(Console.ReadLine());
int max = int.Parse(Console.ReadLine());
if(min > max)
{
Console.WriteLine("min should be smaller than max!");
}
else
{
int sum = 0;
for(int i = min; i < max; i++)
{
sum = sum + i*i;
}
Console.WriteLine(sum);
}

There are two flaws in your code:
The post-increment operator i++ increments i, but returns the previous value. So by i = i++ you never increase i because you always reassign the value as it was before the increment. This leads to an infinite loop.
You didn't sum up the products, but only assigned individual productes with sum = i * i;. You need to add them with sum += i*i;.
So your final loop could look like that:
int sum = 0;
for (int i = min; i < max; i++)
sum += i * i;

Linq is altertative to get rid of explicit loops (and let .net do the work for you):
using System.Linq;
...
int min = 4;
int max = 9;
int sum = Enumerable
.Range(min, max - min) // from min to max (not included)
.Sum(x => x * x); // sum up squares

Related

How do i get the lowest sum of input numbers?

I've got a task for printing the highest sum of numbers, lowest sum of numbers and the average of numbers which were printed. i managed to get the higest sum of numbers but with the lowest somehow didn't work for me at all.
for example:
7 3 -2 6 -10 8 -5 3 -2 1
their Interim amount:
7 10 8 14 4 12 7 10 8 9
the output will be:
Higest Interim amount: 14
Lowest Interim amount: 4
Avg of numbers: 0.9
my code:
static void Main(string[] args)
{
int num = 0, i, sum = 0, c = 0, max, min;
max = min = num;
for (i = 0; i <= 10; i++)
{
Console.WriteLine("Enter a number:");
num = int.Parse(Console.ReadLine());
sum = sum + num;
if (sum >= max)
max = sum;
else if (sum <= min)
min = sum;
c++;
Console.WriteLine("sum:{0}", sum);
}
Console.WriteLine("count={0} avg={1}", c, sum / (float)c);
Console.WriteLine("Max:{0} Min:{1}", max, min);
}
You make both min and max start at 0, so the min will only update if you get a negative value for the cumulative sum (which does not happen in your example). (Would be the same for the max value if all your sums remained negative).
You need to start with the numeric equivalent of min = +Infinity and max = -Infinity.
i.e.
static void Main(string[] args)
{
int num = 0, i, sum = 0, c = 0;
int max = int.MinValue;
int min = int.MaxValue;
(Thanks #Caius Jard for the syntax, I know nothing about C#)
It's because you set the initial min to 0, and then only set the minimum to the sum if it drops below that. If you set initial minimum and maximum to the first number input you won't have this problem:
static void Main(string[] args)
{
int num = 0, i, sum = 0, c = 0, max, min;
for (i = 0; i <= 9; i++)
{
Console.WriteLine("Enter a number:");
num = int.Parse(Console.ReadLine());
if(i == 0)
{
min = num;
max = num;
}
sum = sum + num;
if (sum >= max)
max = sum;
else if (sum <= min)
min = sum;
c++;
Console.WriteLine("sum:{0}", sum);
}
Console.WriteLine("count={0} avg={1}", c, sum / (float)c);
Console.WriteLine("Max:{0} Min:{1}", max, min);
}

Calculate average grades, excluding the entered values that are the lowest and greatest

The task is to allow the user to enter values between 0 and 100. If the user enters -99 the program should stop. Once the program has exited, the average must be computed. However, the average should include all the entered values, except the lowest value entered (minimum) and the greatest value entered (maximum). I have written a fairly good-looking code, but it throws an IndexOutOfRangeException.
Here is that code:
class Program
{
static void Main(string[] args)
{
DisplayApp();
Calculate();
}
static void DisplayApp()
{
Console.WriteLine("Grade Calculator: ");
Console.WriteLine();
}
static double Calculate()
{
Console.WriteLine("Enter grades (-99 to exit): ");
string input = Console.ReadLine();
int[] array1 = new int[] { };
int iInput = int.Parse(input);
int min = 100;
int max = 0;
int i = 0;
int sum = 0;
double average = 0;
while(iInput != 99)
{
if(iInput < min)
{
array1[i] = min;
}
else if(iInput > max)
{
array1[i] = max;
}
sum += iInput - (min + max);
i++;
}
average = (double)sum / i;
return average;
}
}
What do you think could be improved in order for the program to work?
As I mentioned in the comments, you create an array of size zero. I don't see why you need an array at all, since you are only summing the values:
static double Calculate()
{
Console.WriteLine("Enter grades (-99 to exit): ");
int min = Int32.MaxValue;
int max = Int32.MinValue;
int sum = 0;
int i = 0;
while (true)
{
// TODO: Change to TryParse and handle input errors.
int iInput = int.Parse(Console.ReadLine());
if (iInput == -99) break;
if (iInput > 0 && iInput < 100) {
if (iInput < min)
{
min = iInput;
}
if (iInput > max)
{
max = iInput;
}
sum += iInput;
i += 1;
}
}
// TODO: Ensure no division by zero
return (double)(sum - max - min) / (i - 2);
}

Using specific array count

My array max size is 20. If I were to enter data that would be less than 20,how do I get it where my program only counts the used arrays?
for (int i = 0; i < Score.Length; i++)
{
sum = sum + Score[i];
}
average = sum / Score.Length;
If I use this for loop above, it always divides by 20 for the average. I need it to only count the ones I entered, not 20. I would prefer solutions using arrays
If you insist in using arrays, then you must keep track of how many items you added to the array, like:
int[] Score = new int[20];
Random rdn = new Random();
int size=0;
for(int i=0;i<rdn.Next(0,20);i++)
{
Score[i] = rdn.Next();
size++;
}
int sum = 0;
for (int i = 0; i < size; i++)
{
sum = sum + Score[i];
}
double average = sum / size;
A better option is to use the List class that keep track for you of the number of items you add
List<int> Score = new List<int>();
Random rdn = new Random();
for(int i=0;i<rdn.Next(0,20);i++)
{
Score.Add(rdn.Next());
}
int sum = 0;
for (int i = 0; i < Score.Count; i++)
{
sum = sum + Score[i];
}
double average = sum / Score.Count;
And of course, as you didn't say the type of your data you could use other data types, like double, float, long, decimal for both solutions.
That is probably an overkill, but another approach would be to use a SparseVector class of the Math.Numerics package:
Sparse Vector uses two arrays which are usually much shorter than the vector. One array stores all values that are not zero, the other stores their indices.
PM > Install-Package MathNet.Numerics
var vector = SparseVector.Build.SparseOfArray(Score);
var sum = vector.Sum();
Sum() will only go through non-empty elements.
You need to keep track of the record that are != 0, so
int count = 0;
for(int i = 0; i < array.Length; i++)
{
if ( array[i] != 0 )
{
count++;
sum += array[i];
}
}
average = sum / count;
And beware of division by 0 ;)

Display sum of 10 input numbers but take out highest and lowest number

I want to input 10 numbers and get the total sum of them if you take out the highest and lowest number that was input. So basically it'll be 8 numbers that i get the sum of when i take out the highest and lowest number that was input out of the 10. So far i can only count the total sum out of the 10 numbers, but not sure how to take out the highest and lowest. What approach could i take?
static void Main(string[] args)
{
int number, sum = 0, n;
for (number = 1; number < 11; number++)
{
Console.WriteLine("Enter a number");
n = Convert.ToInt32(Console.ReadLine());
sum += n;
}
Points(sum);
Console.ReadLine();
}
static void Points(int sum)
{
Console.WriteLine("Totalpoint is " + sum);
}
Addition is additive, so you can simply remove them on the end:
int sum = 0;
int min = int.MaxValue;
int max = int.MinValue;
for (int i = 0; i < 10; ++i)
{
Console.WriteLine("Enter a number");
int n = Convert.ToInt32(Console.ReadLine());
sum += n;
min = Math.Min(min, n);
max = Math.Max(max, n);
}
sum -= min;
sum -= max;
Points(sum);
Console.ReadLine();
An easy implementation to explain my thought process, could be the following:
static void Main(string[] args)
{
int number, sum = 0, n;
List<int> inputNumbers = new List<int>();
for(number = 0; number < 10; number++)
{
inputNumbers.Add(Convert.ToInt32(Console.ReadLine()));
}
// Obtain maximum and minimum values
var maximum = inputNumbers.Max();
var mimimum = inputNumbers.Min();
foreach (var item in inputNumbers)
{
if(item == maximum)
{
inputNumbers.Remove(item);
break;
}
}
foreach(var item in inputNumbers)
{
if(item == mimimum)
{
inputNumbers.Remove(item);
break;
}
}
Console.WriteLine("Sum: "+inputNumbers.Sum());
Console.ReadKey();
}
The solution is rather simple, since after populating the List with the specified 10 values, you query it to obtain the minimum and maximum values.
When you know them, you can simply loop through the list and remove both the maximum and minimum (break is completely necessary after those operations).
Downside? In this simple implementation, you would be iterating through the List two times, which should definitely be optimized, even if for clean code sake.
But it might the best first step to you!
Just have two more variables to track max and min values as you read them:
min = Math.Min(min, n);
max = Math.Max(max, n);
Then, as you exit the loop, you can simply subtract those from the total sum before printing.
sum -= min + max;
You can try this:
List<int> testNum = new List<int>();
int num = 0;
int sum = 0;
try
{
// This will loop until you have 10 inputs
while(testNum.Count < 10)
{
Console.WriteLine("Enter a number:");
num = Convert.ToInt32(Console.ReadLine()); // Need to have the Try/Catch in case user doesn't input a number
testNum.Add(num);
}
// Get the min and max values (you will need System.Linq for this)
int minVal = testNum.Min();
int maxVal = testNum.Max();
// Remove the min and max values from the List
testNum.Remove(testNum.IndexOf(minVal));
testNum.Remove(testNum.IndexOf(maxVal));
// Sum the remaining values up
foreach(int n in testNum)
{
sum = sum + n;
}
return sum;
}
catch
{
throw;
}
Add the input numbers in the List and sum their values excluding min and max values
public static void Main(string[] args)
{
var list = new List<int>();
for (int i = 0; i < 10; i++)
{
Console.WriteLine("Enter number " + i);
int num = Convert.ToInt32(Console.ReadLine());
list.Add(num); //adding the input number in list
}
Sum(list);
}
private static void Sum(List<int> list)
{
int max = list.Max();
int min = list.Min();
int sum = list.Where(x => x != max && x != min).Sum(); //taking the sum of all values exlcuding min and max
Console.WriteLine("Sum is " + sum);
}

Project Euler #23 in C#

Project Euler challenge 23 states this:
A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number.
A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n.
As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers. However, this upper limit cannot be reduced any further by analysis even though it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than this limit.
Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.
So I've been trying to get this working, however I keep getting back an incorrect result, I'm not sure where this is going wrong in the code though I have:
static void Main(string[] args)
{
List<int> abundantNums = Enumerable.Range(12, 1000000).Where(i => isAbundant(i)).ToList();
abundantNums = abundantNums.Distinct().ToList();
var boolArr = new bool[28124];
for (int i = 0; i < abundantNums.Count; ++i)
{
for (int j = i; j < abundantNums.Count; ++j)
{
var sum = abundantNums[i] + abundantNums[j];
if (sum < 28124) boolArr[sum] = true;
else break;
}
}
var total = 0;
for (int i = 0; i < boolArr.Length; i++)
{
if (boolArr[i] == false)
{
total += i;
}
}
Console.WriteLine(total);
Console.ReadKey();
}
static bool isAbundant(int num)
{
if (getFactors(num).Sum() > num)
{
return true;
}
else
{
return false;
}
}
And then to find the factors of a number I have:
static List<int> getFactors(int num)
{
List<int> factors = new List<int>();
Stopwatch watch = Stopwatch.StartNew();
for (int i=1; i < Math.Sqrt(num) + 1; i++)
{
if (num % i == 0)
{
factors.Add(i);
if (num / i != i)
{
factors.Add(num / i);
}
}
}
watch.Stop();
factors.Remove(num);
return factors;
}
Now I've been at this for a day or two and as far as I can tell this should be doing the trick, anyone wiser than I able to point out my failings?
The problem is your getFactors loop. Change:
for (int i=1; i < Math.Sqrt(num) + 1; i++)
to
for (int i=1; i <= Math.Sqrt(num); i++)
And it should work. I'll let you try and understand why :-)

Categories

Resources