simple procedural maths program in C# - c#

so I am creating a very simple program in C# (my first one).
It should do an average of X numbers.. instead of writing it all out manually, it'll be much better done procedurally (I'm not sure if that's even a word). Basically as I've done with the 'amount' in the example below. I could just divide it by 2 (in this case). But instead I have a variable that increases with each new entry - so the program would work regardless of how many entries there are.
The same thing I'd need to do with the variables 'first', 'second' etc. I need some variable that would change dynamically, based on the number of entries. This should be a peace of cake algorithm-wise but this is my first day with C# and I can't manage to do it (namely because I am lacking the knowledge of syntax).
double first;
double second;
int amount = 0;
double result;
Console.Write("Write your first number");
first = int.Parse(Console.ReadLine());
++amount;
Console.Write("Write your second number");
second = int.Parse(Console.ReadLine());
++amount;
result = (first + second) / amount;
Console.Write("The average of your numbers is: " + result);
Thanks

Here's the gist of what I think you want. I'll use pseudocode to give you the opportunity to learn the C#:
create a list of numbers
output prompt
read input line
while the input line had a value
parse the input value
add the parsed value to the list of numbers
output prompt
read input line
calculate the sum of the values divided by the length of the list
output the calculated average

I think you're after the recusive average?
class Program
{
static void Main(string[] args)
{
//Compute Average Recursively:
int average_count = 0;
double average = 0;
average = RecursiveAverage(average, ref average_count, 1);
average = RecursiveAverage(average, ref average_count, 2);
average = RecursiveAverage(average, ref average_count, 3);
average = RecursiveAverage(average, ref average_count, 4);
Console.WriteLine(average); //2.5
}
private static double RecursiveAverage(double previous, ref int average_count, double next)
{
average_count += 1;
return ((average_count - 1.0) / (average_count)) * previous + (1.0 / (average_count)) * next;
}
}
See: http://people.revoledu.com/kardi/tutorial/RecursiveStatistic/Time-Average.htm
Update: Keep updating the average indefinitely (or until average_count gets too large to store without a BigInteger ) without having to remember all the numbers...
while (true)
{
var next = int.Parse(Console.ReadLine());
average = RecursiveAverage(average, ref average_count, next);
Console.WriteLine("Average is now: " + average);
}

Related

Assistance with temperature comparisons assignment in C#

I'm kinda new to C#, and I'm currently doing an assignment which is having me do three things:
1) Write a program named TemperaturesComparison that allows a user to input five daily Fahrenheit temperatures that must range from −30 to 130.
2) Display the temperatures in the order they were entered, and then display the average of the temperatures.
3) If a temperature is out of range, require the user to reenter it. If no temperature is lower than any previous one, display a message Getting warmer. If every temperature is lower than the previous one, display a message Getting cooler. If the temperatures are not entered in either ascending or descending order, display a message It’s a mixed bag.
The first two I've basically already got, but I'm not 100% sure how to address the third one in the most convenient way. Any advice on how to best handle this one would be greatly appreciated!
Here's a sample of the code I've written so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Console;
class TemperaturesComparison {
static void Main(string[] args) {
string userInput;
// Set Array Range
const int ARRAY_RANGE = 5;
const double AVG_RANGE = 5.0;
int[] dblArray = new int[ARRAY_RANGE];
int total = 0;
double average = 0;
WriteLine("This application calculates the average temperature of a provided dataset.\n");
for (int i = 0; i < ARRAY_RANGE; ++i) {
do {
Write("\nPlease provide temperature {0}: ", i + 1);
userInput = ReadLine();
} while (!int.TryParse(userInput, out dblArray[i]));
}
for (int i = 0; i < ARRAY_RANGE; ++i) {
total += dblArray[i];
}
foreach(var numListHolding in dblArray)
Write(numListHolding.ToString() + " ");
average = total / AVG_RANGE;
Write("\nAverage: {0}", average);
ReadKey();
}
}
You're making a few common beginner mistakes. First, arrays are better for collections that have a fixed size and never change, like the months of a year. If you want to have a changing number of entries, use something like a list:
var temperatures = new List<float>();
Second, integers are a poor type for real-world measurements like temperature. Prefer a floating-point type like float or double.
Next, variable names should tell you what the variables contain; names like userInput don't tell us that.
Next, your code doesn't “allow” a user to input five temperatures, it requires them to enter exactly five and will throw exceptions if they don't. Design your loops to work with any number of inputs:
while (true)
{
var nextTemperature = GetTemperatureFromSomewhere();
if (nextTemperature == null)
break;
if (nextTemperature is valid)
temperatures.Add(nextTemperature);
}
Look at the code above. If nextTemperature is not null but out of range you don't want to add it to temperatures.
When you have that working you want to store a maximumTemperature and compare it to each nextTemperature. If every nextTemperature exceeds maximumTemperature then your temperatures are getting warmer.

Probability of getting a particular sum from n m-sided dice c#

I am trying to generate a probability of getting a specific number from n dice, with no guarantee of them having the same number of sides. (eg, 1d6 + 2d10)
I know there is a really expensive way of doing it (With recursion), but if there is a mathematical way of determining the chance of an event happening, that would be way better.
One way to do this:
Create an output array count with length sum(sides all dice)+1, i.e. so that the max that can possibly be rolled works as an index.
This represents the number of ways that the index can be rolled. Initialise this with [0] = 1.
For each dice of N sides, enumerate the results of each possible rolled value.
Copy the existing count array into prev, say, and create a new empty count array
for roll = 1 to N, for total = 0 to count.length-1-roll, count[total+roll]+=prev[total]
Now the probability of rolling value = count[value] / sum(count)
Notes:
This isn't, as you feared, either really expensive or needs recursion. This will be O(N^2) where N as the total faces on all dice.
This will compute the probability of all outputs not just the one output that you're interested in, which may be an issue if the total faces is extremely large and the value you're interested in small. You could cap the count array at length (value you're interested in) + 1, if necessary, and compute the total number of rolls as the product of each die face as you process it rather than from sum(count) as I've suggested above.
#Rup already gave one standard solution, the bottom up dynamic programming method.
The top down approach is to write your recursive function..and then memoize it. That is when your function is called you first check whether you have seen this before (ie you look into a dictionary to see if you have a "memo" to yourself about the answer), and if you haven't you calculate the answer and save it. Then you return the memoized answer.
The usual tradeoffs apply:
Top down is easier to figure out and write.
Bottom up lets you see that you don't need to store 2 dice answers when you have the 3 dice ones, and therefore reduces working memory requirements.
Therefore it is good to know both approaches, but I always reach for a top down approach first.
Here I generated from 2 dice rolling
1 Randon() will be generated from n faces
2 here n times is rolled on
3 sum is displayed for n rolled
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Dicerolling
{
class Program
{
static void Main(string[] args)
{
Random x = new Random();
int throw_times = 1;
int sum = 0;
int[] dice = new int[2];
dice[0] = x.Next(1, 7);
dice[1] = x.Next(1, 7);
Console.WriteLine("enter the no of rollings :");
var n = int.Parse(Console.ReadLine());
for (int i = 1; i <= n; i++)
{
dice[0] = x.Next(1, 7);
dice[1] = x.Next(1, 7);
int total_var = dice[0] + dice[1];
sum += dice[0] + dice[1] ;//total in array
Console.Write("Throw " + throw_times + ": " + dice[0] + " d " + dice[1] + " = ");
Console.WriteLine(total_var);
throw_times++;
Array.Sort(dice);
for (int a = dice.Length - 1; a >= 0; a--)
{
int s = dice[a];
Console.WriteLine("#" + s);
}
}
Console.WriteLine("Total sum: " + sum);//only returns sum of last 2 rolls
Console.ReadLine();
}
}
}

What wrong with this implement of this arcsine approximate in C#

This is a formula to approximate arcsine(x) using Taylor series from this blog
This is my implementation in C#, I don't know where is the wrong place, the code give wrong result when running:
When i = 0, the division will be 1/x. So I assign temp = 1/x at startup. For each iteration, I change "temp" after "i".
I use a continual loop until the two next value is very "near" together. When the delta of two next number is very small, I will return the value.
My test case:
Input is x =1, so excected arcsin(X) will be arcsin (1) = PI/2 = 1.57079633 rad.
class Arc{
static double abs(double x)
{
return x >= 0 ? x : -x;
}
static double pow(double mu, long n)
{
double kq = mu;
for(long i = 2; i<= n; i++)
{
kq *= mu;
}
return kq;
}
static long fact(long n)
{
long gt = 1;
for (long i = 2; i <= n; i++) {
gt *= i;
}
return gt;
}
#region arcsin
static double arcsinX(double x) {
int i = 0;
double temp = 0;
while (true)
{
//i++;
var iFactSquare = fact(i) * fact(i);
var tempNew = (double)fact(2 * i) / (pow(4, i) * iFactSquare * (2*i+1)) * pow(x, 2 * i + 1) ;
if (abs(tempNew - temp) < 0.00000001)
{
return tempNew;
}
temp = tempNew;
i++;
}
}
public static void Main(){
Console.WriteLine(arcsin());
Console.ReadLine();
}
}
In many series evaluations, it is often convenient to use the quotient between terms to update the term. The quotient here is
(2n)!*x^(2n+1) 4^(n-1)*((n-1)!)^2*(2n-1)
a[n]/a[n-1] = ------------------- * --------------------- -------
(4^n*(n!)^2*(2n+1)) (2n-2)!*x^(2n-1)
=(2n(2n-1)²x²)/(4n²(2n+1))
= ((2n-1)²x²)/(2n(2n+1))
Thus a loop to compute the series value is
sum = 1;
term = 1;
n=1;
while(1 != 1+term) {
term *= (n-0.5)*(n-0.5)*x*x/(n*(n+0.5));
sum += term;
n += 1;
}
return x*sum;
The convergence is only guaranteed for abs(x)<1, for the evaluation at x=1 you have to employ angle halving, which in general is a good idea to speed up convergence.
You are saving two different temp values (temp and tempNew) to check whether or not continuing computation is irrelevant. This is good, except that you are not saving the sum of these two values.
This is a summation. You need to add every new calculated value to the total. You are only keeping track of the most recently calculated value. You can only ever return the last calculated value of the series. So you will always get an extremely small number as your result. Turn this into a summation and the problem should go away.
NOTE: I've made this a community wiki answer because I was hardly the first person to think of this (just the first to put it down in a comment). If you feel that more needs to be added to make the answer complete, just edit it in!
The general suspicion is that this is down to Integer Overflow, namely one of your values (probably the return of fact() or iFactSquare()) is getting too big for the type you have chosen. It's going to negative because you are using signed types — when it gets to too large a positive number, it loops back into the negative.
Try tracking how large n gets during your calculation, and figure out how big a number it would give you if you ran that number through your fact, pow and iFactSquare functions. If it's bigger than the Maximum long value in 64-bit like we think (assuming you're using 64-bit, it'll be a lot smaller for 32-bit), then try using a double instead.

SPOJ small factorials problem

Here is the exact question
You are asked to calculate factorials of some small positive integers.
Input:
An integer t, 1<=t<=100, denoting the number of testcases, followed by t lines, each containing a single integer n, 1<=n<=100.
Output:
For each integer n given at input, display a line with the value of n!
Example
Sample input:
4
1
2
5
3
Sample output:
1
2
120
6
I have coded the SPOJ small factorials problem no 24, but the judge is saying as wrong answer. Please have a look at my code and help me.
class Program
{
static void Main(string[] args)
{
long numOfTestCases=0;
string factForAll = "";
numOfTestCases = Convert.ToInt32(Console.ReadLine());
long[] numArray = new long[numOfTestCases];
for (long i = 0; i < numArray.Length; i++)
{
numArray[i]= Convert.ToInt64(Console.ReadLine());
}
foreach (var item in numArray)
{
long factResult = findFact(item);
factForAll += factResult+"\n";
}
Console.WriteLine();
Console.WriteLine(factForAll);
}
public static long findFact(long number)
{
long factorial = 1;
if (number<=1)
{
factorial = 1;
}
for (long i = 1; i <=number; i++)
{
factorial *= i;
}
return factorial;
}
}
After looking at the first comment you need to write each answer on a single line, in c3 that is "\r\n", not "\n".
The problem specifies that the numbers are in the range 1 <= n <= 100. You are calculating the factorial of these in long variables. The range of a long is –9223372036854775808 to 9223372036854775807. The result will easily overflow this range.
For example,
100! = 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
You will need to use something like BigInteger to manipulate numbers this large.
C# is not an optimal language choice on SPOJ.com because everything runs on Unix/Linux servers, and the version of C# used is actually Mono 2.. that is why a lot of stuff is not supported, and will not run as expected.
So i would recommend switching to C++ or Java :)

C# Calculation of moving median of time series SortedList<DateTime, double> - improve performance?

I have a method that calculates the moving median value of a time series. Like a moving average, it use a fixed window or period (sometimes referred to as the look back period).
If the period is 10, it will created an array of the first 10 values (0-9), then find the median value of them. It will repeat this, incrementing the window by 1 step (values 1-10 now) and so on... hence the moving part of this. This is process is exactly the same as a moving average.
The median value is found by:
Sorting the values of an array
If there is an odd number of values in the array, take the mid value. The median of a sorted array of 5 values would be the 3rd value.
If there is an even number of values in the array, take the two values on each side of the mid and average them. The median of a sorted array of 6 values would be the (2nd + 3rd) / 2.
I have created a function that calculates this by populating a List<double>, calling List<>.Sort(), and then finding the appropriate values.
Computational it is correct, but I was wonder if there ws a way to improve the performance of this calculation. Perhaps by hand-rolling a sort on an double[] rather than using a list.
My implementation is as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Moving_Median_TimeSeries
{
class Program
{
static void Main(string[] args)
{
// created a a sample test time series of 10 days
DateTime Today = DateTime.Now;
var TimeSeries = new SortedList<DateTime, double>();
for (int i = 0; i < 10; i++)
TimeSeries.Add(Today.AddDays(i), i * 10);
// write out the time series
Console.WriteLine("Our time series contains...");
foreach (var item in TimeSeries)
Console.WriteLine(" {0}, {1}", item.Key.ToShortDateString(), item.Value);
// calculate an even period moving median
int period = 6;
var TimeSeries_MovingMedian = MovingMedian(TimeSeries, period);
// write out the result of the calculation
Console.WriteLine("\nThe moving median time series of {0} periods contains...", period);
foreach (var item in TimeSeries_MovingMedian)
Console.WriteLine(" {0}, {1}", item.Key.ToShortDateString(), item.Value);
// calculate an odd period moving median
int period2 = 5;
var TimeSeries_MovingMedian2 = MovingMedian(TimeSeries, period);
// write out the result of the calculation
Console.WriteLine("\nThe moving median time series of {0} periods contains...", period2);
foreach (var item in TimeSeries_MovingMedian2)
Console.WriteLine(" {0}, {1}", item.Key.ToShortDateString(), item.Value);
}
public static SortedList<DateTime, double> MovingMedian(SortedList<DateTime, double> TimeSeries, int period)
{
var result = new SortedList<DateTime, double>();
for (int i = 0; i < TimeSeries.Count(); i++)
{
if (i >= period - 1)
{
// add all of the values used in the calc to a list...
var values = new List<double>();
for (int x = i; x > i - period; x--)
values.Add(TimeSeries.Values[x]);
// ... and then sort the list <- there might be a better way than this
values.Sort();
// If there is an even number of values in the array (example 10 values), take the two mid values
// and average them. i.e. 10 values = (5th value + 6th value) / 2.
double median;
if (period % 2 == 0) // is any even number
median = (values[(int)(period / 2)] + values[(int)(period / 2 - 1)]) / 2;
else // is an odd period
// Median equals the middle value of the sorted array, if there is an odd number of values in the array
median = values[(int)(period / 2 + 0.5)];
result.Add(TimeSeries.Keys[i], median);
}
}
return result;
}
}
}
there might be a better way than this
You are right about this - you don't need to sort the whole list if all you want is the median. Follow links from this wikipedia page for more.
For a list of N items and a period P, your algorithm which re-sorts the list for every item is O(N * P lgP). There is an O(N * lg P) algorithm, which uses 2 heaps.
It uses a min-heap which contains P/2 items above the median, and a max-heap with the P-P/2 items less than or equal to it. Whenever you get a new data item, replace the oldest item with the new one, then do a sift-up or sift-down to move it to the correct place. If the new item reaches the root of either heap, compare it to the root of the other and swap and sift-down when needed. For odd P, the median is at the root of the max-heap. For even P, it is the average of both roots.
There is a c implementation in this question. One tricky part in implementing it is
tracking the oldest item efficiently. The overhead in that part may make the speed gains insignificant for small P.

Categories

Resources