What I want to do is get the middle of each half of my number.
So what I have already created is a way to get the middle of the number (The median in math terms) here;
public static String Find_Median()
{
double Size = list.Count;
double Final_Number = 0;
if (Size % 2 == 0)
{
int HalfWay = list.Count / 2;
double Value1 = Convert.ToDouble(list[HalfWay - 1].ToString());
double Value2 = Convert.ToDouble(list[HalfWay - 1 + 1].ToString());
double Number = Value1 + Value2;
Final_Number = Number / 2;
}
else
{
int HalfWay = list.Count / 2;
double Value1 = Convert.ToDouble(list[HalfWay].ToString());
Final_Number = Value1;
}
return Convert.ToString(Final_Number);
}
That gets the exact middle number of all the numbers in the list, even if its got to middle it does that math also.
I want to do that on both sides; here's an example;
3 2 1 4 5 6
The middle (median) of that list is 3.5.
I want to use math to find 2, which is between the start and the middle of the equation. also known as Q1 in the IQR. I also want to know how I can find the middle number between the median (middle) and the end, which is 5.
I.E. So i can find 70,80 and 90 with code.
I just ran into the same issue, and checking the wikipedia entry for Quartile, it's a bit more complex than it first appears.
My approach was as follows: (which seems to work pretty well for all cases, N=1 on up)...
/// <summary>
/// Return the quartile values of an ordered set of doubles
/// assume the sorting has already been done.
///
/// This actually turns out to be a bit of a PITA, because there is no universal agreement
/// on choosing the quartile values. In the case of odd values, some count the median value
/// in finding the 1st and 3rd quartile and some discard the median value.
/// the two different methods result in two different answers.
/// The below method produces the arithmatic mean of the two methods, and insures the median
/// is given it's correct weight so that the median changes as smoothly as possible as
/// more data ppints are added.
///
/// This method uses the following logic:
///
/// ===If there are an even number of data points:
/// Use the median to divide the ordered data set into two halves.
/// The lower quartile value is the median of the lower half of the data.
/// The upper quartile value is the median of the upper half of the data.
///
/// ===If there are (4n+1) data points:
/// The lower quartile is 25% of the nth data value plus 75% of the (n+1)th data value.
/// The upper quartile is 75% of the (3n+1)th data point plus 25% of the (3n+2)th data point.
///
///===If there are (4n+3) data points:
/// The lower quartile is 75% of the (n+1)th data value plus 25% of the (n+2)th data value.
/// The upper quartile is 25% of the (3n+2)th data point plus 75% of the (3n+3)th data point.
///
/// </summary>
internal Tuple<double, double, double> Quartiles(double[] afVal)
{
int iSize = afVal.Length;
int iMid = iSize / 2; //this is the mid from a zero based index, eg mid of 7 = 3;
double fQ1 = 0;
double fQ2 = 0;
double fQ3 = 0;
if (iSize % 2 == 0)
{
//================ EVEN NUMBER OF POINTS: =====================
//even between low and high point
fQ2 = (afVal[iMid - 1] + afVal[iMid]) / 2;
int iMidMid = iMid / 2;
//easy split
if (iMid % 2 == 0)
{
fQ1 = (afVal[iMidMid - 1] + afVal[iMidMid]) / 2;
fQ3 = (afVal[iMid + iMidMid - 1] + afVal[iMid + iMidMid]) / 2;
}
else
{
fQ1 = afVal[iMidMid];
fQ3 = afVal[iMidMid + iMid];
}
}
else if (iSize == 1)
{
//================= special case, sorry ================
fQ1 = afVal[0];
fQ2 = afVal[0];
fQ3 = afVal[0];
}
else
{
//odd number so the median is just the midpoint in the array.
fQ2 = afVal[iMid];
if ((iSize - 1) % 4 == 0)
{
//======================(4n-1) POINTS =========================
int n = (iSize - 1) / 4;
fQ1 = (afVal[n - 1] * .25) + (afVal[n] * .75);
fQ3 = (afVal[3 * n] * .75) + (afVal[3 * n + 1] * .25);
}
else if ((iSize - 3) % 4 == 0)
{
//======================(4n-3) POINTS =========================
int n = (iSize - 3) / 4;
fQ1 = (afVal[n] * .75) + (afVal[n + 1] * .25);
fQ3 = (afVal[3 * n + 1] * .25) + (afVal[3 * n + 2] * .75);
}
}
return new Tuple<double, double, double>(fQ1, fQ2, fQ3);
}
THERE ARE MANY WAYS TO CALCULATE QUARTILES:
I did my best here to implement the version of Quartiles as described as type = 8 Quartile(array, type=8) in the R documentation: https://www.rdocumentation.org/packages/stats/versions/3.5.1/topics/quantile. This method, is preferred by the authors of the R function, described here, as it produces a smoother transition between values. However, R defaults to method 7, which is the same function used by S and Excel.
If you are just Googling for answers and not thinking about what the output means, or what result you are trying to achieve, this might give you a surprise.
I know this is an old question so I debated whether I should add below answer or not for a little while and since the most voted answer didn't match the numbers with Excel Quartile, I have decided to post below answer.
I also needed to find first and third quartile as I am trying to draw histogram and to create bin width and ranges I am using Freedman–Diaconis rule which requires to know First and Third quartile. I started with Mike's answer.
But during data verification I noticed that result didn't match with the way Quartile is calculated in Excel and histogram created using Ploltly so I dig further and stumbled upon following two links:
C# Descriptive Statistic Class
Statistics - check slide 12
Slide 12 in second link states "The position of the Pth percentile is given by (n + 1)P/100, where n is the number of observations in the set."
So equivalent C# code from C# Descriptive Statistic Class is:
/// <summary>
/// Calculate percentile of a sorted data set
/// </summary>
/// <param name="sortedData"></param>
/// <param name="p"></param>
/// <returns></returns>
internal static double Percentile(double[] sortedData, double p)
{
// algo derived from Aczel pg 15 bottom
if (p >= 100.0d) return sortedData[sortedData.Length - 1];
double position = (sortedData.Length + 1) * p / 100.0;
double leftNumber = 0.0d, rightNumber = 0.0d;
double n = p / 100.0d * (sortedData.Length - 1) + 1.0d;
if (position >= 1)
{
leftNumber = sortedData[(int)Math.Floor(n) - 1];
rightNumber = sortedData[(int)Math.Floor(n)];
}
else
{
leftNumber = sortedData[0]; // first data
rightNumber = sortedData[1]; // first data
}
//if (leftNumber == rightNumber)
if (Equals(leftNumber, rightNumber))
return leftNumber;
double part = n - Math.Floor(n);
return leftNumber + part * (rightNumber - leftNumber);
} // end of internal function percentile
Test case (written in Visual Studio 2017):
static void Main()
{
double[] x = { 18, 18, 18, 18, 19, 20, 20, 20, 21, 22, 22, 23, 24, 26, 27, 32, 33, 49, 52, 56 };
var q1 = Percentile(x, 25);
var q2 = Percentile(x, 50);
var q3 = Percentile(x, 75);
var iqr = q3 - q1;
var (q1_mike, q2_mike, q3_mike) = Quartiles(x); //Uses named tuples instead of regular Tuple
var iqr_mike = q3_mike - q1_mike;
}
Result comparison:
You will notice that result in excel matches to the theory mentioned Statistics in slide 12.
From code:
From excel (matches q1, q2 and q3 values)
Run the same metod on the following lists:
list1 = list.Where(x => x < Median)
list2 = list.Where(x => x > Median)
Find_Median(list1) will return first Quartile,
Find_Median(list2) will return third Quartile
a quick way that can be adjusted
var q3 = table.Skip(table.Length * 3 / 4).Take(1);
var q1 = table.Skip(table.Length * 1 / 4).Take(1);
Related
I have the code which prints all possible permutations of a given string. How to set the length of one permutation? For example if the lenght is 2 then output should contains 6 possible permutations from ABCD.
class GFG
{
/**
* permutation function
* #param str string to
calculate permutation for
* #param l starting index
* #param r end index
*/
private static void permute(String str,
int l, int r)
{
if (l == r)
Console.WriteLine(str);
else
{
for (int i = l; i <= r; i++)
{
str = swap(str, l, i);
permute(str, l + 1, r);
str = swap(str, l, i);
}
}
}
/**
* Swap Characters at position
* #param a string value
* #param i position 1
* #param j position 2
* #return swapped string
*/
public static String swap(String a,
int i, int j)
{
char temp;
char[] charArray = a.ToCharArray();
temp = charArray[i] ;
charArray[i] = charArray[j];
charArray[j] = temp;
string s = new string(charArray);
return s;
}
// Driver Code
public static void Main()
{
String str = "ABCD";
int n = str.Length;
permute(str, 0, n-1);
}
}
I originally missed that this was using a variable number of number arrangements (i.e. 5 source characters to all of the 2 character strings that could be generated). I've since revised this to show extra detail.
This is probably a mathematic rather than programming questions.
In order to calculate the number of permutations for source characters c with the maximum output length l, use the following:
result = c! / (c - l)!
In the case of your example of 4 characters and a maximum of 2-character output, this gives:
result = 4! / (4 - 2)!
= 4! / 2!
= 24 / 2
= 12
To calculate this in C# is not difficult - calculate the factorial (!) of c and the difference between c and l and divide the first by the second:
Using the handy function below:
/// <summary>
/// Gets the factorial of the specified number.
/// </summary>
/// <param name="n">An int indicating the number to get the factorial of.</param>
/// <returns>An int indicating the factorial.</returns>
private static int getFactorial(int n)
{
int returnValue = 1;
while (n > 1)
returnValue *= n--;
return returnValue;
}
This can be done using:
int result = getFactorial(4) / getFactorial(4 - 2);
Console.WriteLine(result);
Output:
12
This can also be placed into its own function:
/// <summary>
/// Gets the factorial of n to length l.
/// </summary>
/// <param name="n">An int indicating the number of items in the set.</param>
/// <param name="l">An int indicating the length of the output.</param>
/// <returns>An int indicating the result.</returns>
private static int getFactorial(int n, int l)
{
if (l > n) throw new ArgumentException("The legnth of the output may not be larger than the number of items", nameof(l));
return getFactorial(n) / getFactorial(n - l);
}
Used as such:
Console.WriteLine($"The factorial of 4 by 2 is {getFactorial(4, 2)}");
Console.WriteLine($"The factorial of 5 by 3 is {getFactorial(5, 3)}");
Console.WriteLine($"The factorial of 6 by 2 is {getFactorial(6, 2)}");
Outputs:
The factorial of 4 by 2 is 12
The factorial of 5 by 3 is 60
The factorial of 6 by 2 is 30
Note: Using an int may not be the best choice. At low numbers it works well but as soon as you have a 13-character string (13!) it will overflow and give an invalid result. 13! = 6,227,020,800 which is clearly bigger than an int32 in C#.
Update 01
Thanks to Caius, found the main problem, the logic on the "if" was wrong, now fixed and giving the correct results. The loop still create more positions than needed on the secondary List, an extra position for each number on the main List.
I've updated the code bellow for refence for the following question:
-001 I can figure out why it create positions that needed, the for loop should run only after the foreach finishes its loops correct?
-002 To kind of solving this issue, I've used a List.Remove() to remove all the 0's, so far no crashes, but, the fact that I'm creating the extra indexes, and than removing them, does means a big performance down if I have large list of numbers? Or is an acceptable solution?
Description
It supposed to read all numbers in a central List1 (numberList), and count how many numbers are inside a certain (0|-15 / 15|-20) range, for that I use another List, that each range is a position on the List2 (numberSubList), where each number on List2, tells how many numbers exists inside that range.
-The range changes as the numbers grows or decrease
Code:
void Frequency()
{
int minNumb = numberList.Min();
int maxNumb = numberList.Max();
int size = numberList.Count();
numberSubList.Clear();
dGrdVFrequency.Rows.Clear();
dGrdVFrequency.Refresh();
double k = (1 + 3.3 * Math.Log10(size));
double h = (maxNumb - minNumb) / k;
lblH.Text = $"H: {Math.Round(h, 2)} / Rounded = {Math.Round(h / 5) * 5}";
lblK.Text = $"K: {Math.Round(k, 4)}";
if (h <= 5) { h = 5; }
else { h = Math.Round(h / 5) * 5; }
int counter = 1;
for (int i = 0; i < size; i++)
{
numberSubList.Add(0); // 001 HERE, creating more positions than needed, each per number.
foreach (int number in numberList)
{
if (number >= (h * i) + minNumb && number < (h * (i + 1)) + minNumb)
{
numberSubList[i] = counter++;
}
}
numberSubList.Remove(0); // 002-This to remove all the extra 0's that are created.
counter = 1;
}
txtBoxSubNum.Clear();
foreach (int number in numberSubList)
{
txtBoxSubNum.AppendText($"{number.ToString()} , ");
}
lblSubTotalIndex.Text = $"Total in List: {numberSubList.Count()}";
lblSubSumIndex.Text = $"Sum of List: {numberSubList.Sum()}";
int inc = 0;
int sum = 0;
foreach (int number in numberSubList)
{
sum = sum + number;
int n = dGrdVFrequency.Rows.Add();
dGrdVFrequency.Rows[n].Cells[0].Value = $"{(h * inc) + minNumb} |- {(h * (1 + inc)) + minNumb}";
dGrdVFrequency.Rows[n].Cells[1].Value = $"{number}";
dGrdVFrequency.Rows[n].Cells[2].Value = $"{sum}";
dGrdVFrequency.Rows[n].Cells[3].Value = $"{(number * 100) / size} %";
dGrdVFrequency.Rows[n].Cells[4].Value = $"{(sum * 100) / size} %";
inc++;
}
}
Screen shot showing the updated version.
I think, if your aim is to only store eg 17 in the "15 to 25" slot, this is wonky:
if (number <= (h * i) + minNumb) // Check if number is smaller than the range limit
Because it's found inside a loop that will move on to the next range, "25 to 35" and it only asks if the number 17 is less than the upper limit (and 17 is less than 35) so 17 is accorded to the 25-35 range too
FWIW the range a number should be in can be derived from the number, with (number - min) / number_of_ranges - at the moment you create your eg 10 ranges and then you visit each number 10 times looking to put it in a range, so you do 9 times more operations than you really need to
I want to get a list of: Sides of Right Triangle
which are perfectly whole numbers.(where each sides less than 100)
Example:
//I want these combination to be printed
3, 4, 5
6, 8, 10 |'.
5, 12, 13 12 | '. 13 (Figure is just Example)
. | '.
. |______'.
. 5
// I don't want these
1, 1, 1.414.... |'.
. 1 | '. √ˉ2 = 1.414.... (Figure is just Example)
. | '.
|______'.
1
Update:
I do like this: But this is very heavy code(regarding optimization)
for(int i=1;i<100;i++)
{
for(int j=1;j<100;j++)
{
for(int k=1;k<100;k++)
{
if(i*i + j*j == k*k)
{
//print i, j, k
}
}
}
}
What you're looking for are the Pythagorean triples.
// Obvious min is 1, obvious max is 99.
for(int i = 1; i != 100; ++i)
{
// There's no point going beyond the lowest number that gives an answer higher than 100
int max = 100 * 100 - i * i;
// There's no point starting lower than our current first side, or we'll repeat results we already found.
for(int j = i; j * j <= max; ++j)
{
// Find the square of the hypotenuse
int sqr = i * i + j * j;
// We could have a double and do hyp == Math.Round(hyp), but lets avoid rounding error-based false positives.
int hyp = (int)Math.Sqrt(sqr);
if(hyp * hyp == sqr)
{
Console.WriteLine(i + ", " + j + ", " + hyp);
// If we want to e.g. have not just "3, 4, 5" but also "4, 3, 5", then
// we can also here do
// Console.WriteLine(j + ", " + i + ", " + hyp);
}
}
}
I've used this formula in C# for generating Pythagorean triples in the past. But there are many other options on that page.
You can improve your code by removing the innermost loop if you take advantage of the fact that for each pair of catheti, there is only one possible value for the hypotenuse. Instead of looping around to find that value, you can compute it using the Pythagorean theorem and test if it is an whole number.
Something like:
// compute the hypotenuse
var hypotenuse = Math.Sqrt(i*i + j*j);
// test if the hypotenuse is a whole number < 100
if(hypotenuse < 100 && hypotenuse == (int)hypotenuse)
{
// here's one!
}
Some other improvements you can do include:
Once you've checked a pair of catheti (x,y), don't check for (y,x) again;
Once you find a triangle (x,y,z), you can include all triangles with the same sides multiplied by a constant factor (k*x, k*y, k*z), i.e, if you find (3,4,5) you can include (6,8,10), (9,12,15), (12,16,20), etc (this one might be a too much effort for little gains);
A fairly good exhaustive search:
for(i=1;i<100;i++) {
k=i;
for(j=1;k<100;j++) {
while(i*i+j*j<k*k) {
k++;
}
if(i*i+j*j==k*k) {
printf("%d %d %d", i, j, k);
}
}
}
In a declarative language (Mathematica):
FindInstance[x^2 + y^2==z^2 &&1<=z<=100 && 1<=y<=x<=100, {x, y, z}, Integers,100]
I have to display ratings and for that, I need increments as follows:
Input
Rounded
1.0
1
1.1
1
1.2
1
1.3
1.5
1.4
1.5
1.5
1.5
1.6
1.5
1.7
1.5
1.8
2.0
1.9
2.0
2.0
2.0
2.1
2.0
and so on...
Is there a simple way to compute the required values?
Multiply your rating by 2, then round using Math.Round(rating, MidpointRounding.AwayFromZero), then divide that value by 2.
Math.Round(value * 2, MidpointRounding.AwayFromZero) / 2
Multiply by 2, round, then divide by 2
if you want nearest quarter, multiply by 4, divide by 4, etc
Here are a couple of methods I wrote that will always round up or down to any value.
public static Double RoundUpToNearest(Double passednumber, Double roundto)
{
// 105.5 up to nearest 1 = 106
// 105.5 up to nearest 10 = 110
// 105.5 up to nearest 7 = 112
// 105.5 up to nearest 100 = 200
// 105.5 up to nearest 0.2 = 105.6
// 105.5 up to nearest 0.3 = 105.6
//if no rounto then just pass original number back
if (roundto == 0)
{
return passednumber;
}
else
{
return Math.Ceiling(passednumber / roundto) * roundto;
}
}
public static Double RoundDownToNearest(Double passednumber, Double roundto)
{
// 105.5 down to nearest 1 = 105
// 105.5 down to nearest 10 = 100
// 105.5 down to nearest 7 = 105
// 105.5 down to nearest 100 = 100
// 105.5 down to nearest 0.2 = 105.4
// 105.5 down to nearest 0.3 = 105.3
//if no rounto then just pass original number back
if (roundto == 0)
{
return passednumber;
}
else
{
return Math.Floor(passednumber / roundto) * roundto;
}
}
There are several options. If performance is a concern, test them to see which works fastest in a large loop.
double Adjust(double input)
{
double whole = Math.Truncate(input);
double remainder = input - whole;
if (remainder < 0.3)
{
remainder = 0;
}
else if (remainder < 0.8)
{
remainder = 0.5;
}
else
{
remainder = 1;
}
return whole + remainder;
}
decimal d = // your number..
decimal t = d - Math.Floor(d);
if(t >= 0.3d && t <= 0.7d)
{
return Math.Floor(d) + 0.5d;
}
else if(t>0.7d)
return Math.Ceil(d);
return Math.Floor(d);
Sounds like you need to round to the nearest 0.5. I see no version of round in the C# API that does this (one version takes a number of decimal digits to round to, which isn't the same thing).
Assuming you only have to deal with integer numbers of tenths, it's sufficient to calculate round (num * 2) / 2. If you're using arbitrarily precise decimals, it gets trickier. Let's hope you don't.
These lines of code snap a float dx to nearest snap:
if (snap <= 1f)
dx = Mathf.Floor(dx) + (Mathf.Round((dx - Mathf.Floor(dx)) * (1f / snap)) * snap);
else
dx = Mathf.Round(dx / snap) * snap;
So if snap is 0.5, value gets rounded to nearest 0.5 value (1.37 goes to 1.5), if it is 0.02, value is rounded to nearest 0.02 ((1.37 goes to 1.38)). If snap is 3, value is rounded to nearest 3 (7.4 goes to 6, 7.6 goes to 9) etc... I use it to quickly snap objects on scene in unity because unity default snapping doesn't seem to work well for me.
Public Function Round(ByVal text As TextBox) As Integer
Dim r As String = Nothing
If text.TextLength > 3 Then
Dim Last3 As String = (text.Text.Substring(text.Text.Length - 3))
If Last3.Substring(0, 1) = "." Then
Dim dimcalvalue As String = Last3.Substring(Last3.Length - 2)
If Val(dimcalvalue) >= 50 Then
text.Text = Val(text.Text) - Val(Last3)
text.Text = Val(text.Text) + 1
ElseIf Val(dimcalvalue) < 50 Then
text.Text = Val(text.Text) - Val(Last3)
End If
End If
End If
Return r
End Function
This answer is taken from Rosdi Kasim's comment in the answer that John Rasch provided.
John's answer works but does have an overflow possibility.
Here is my version of Rosdi's code:
I also put it in an extension to make it easy to use. The extension is not necessary and could be used as a function without issue.
<Extension>
Public Function ToHalf(value As Decimal) As Decimal
Dim integerPart = Decimal.Truncate(value)
Dim fractionPart = value - Decimal.Truncate(integerPart)
Dim roundedFractionPart = Math.Round(fractionPart * 2, MidpointRounding.AwayFromZero) / 2
Dim newValue = integerPart + roundedFractionPart
Return newValue
End Function
The usage would then be:
Dim newValue = CDec(1.26).ToHalf
This would return 1.5
I had difficulty with this problem as well.
I code mainly in Actionscript 3.0 which is base coding for the Adobe Flash Platform, but there are simularities in the Languages:
The solution I came up with is the following:
//Code for Rounding to the nearest 0.05
var r:Number = Math.random() * 10; // NUMBER - Input Your Number here
var n:int = r * 10; // INTEGER - Shift Decimal 2 places to right
var f:int = Math.round(r * 10 - n) * 5;// INTEGER - Test 1 or 0 then convert to 5
var d:Number = (n + (f / 10)) / 10; // NUMBER - Re-assemble the number
trace("ORG No: " + r);
trace("NEW No: " + d);
Thats pretty much it.
Note the use of 'Numbers' and 'Integers' and the way they are processed.
Good Luck!
I'm looking for a formula that can spread out numbers in a linear format based on a minimum number, max number and amount of numbers (or dots) between. The catch is, the closer you get to the max, the more numbers should be there.
An example (number will vary and will be about 100 times larger)
Min = 0
Max = 16
AmountOfNumbersToSpread = 6
0 1 2 3 4 5 6 7 8 9 A B C D E F
1 2 3 4 5 6
Thanks for the help in advance.
Based on the answer of Tal Pressman, you can write a distribution function like this:
IEnumerable<double> Spread(int min, int max, int count, Func<double, double> distribution)
{
double start = min;
double scale = max - min;
foreach (double offset in Redistribute(count, distribution))
yield return start + offset * scale;
}
IEnumerable<double> Redistribute(int count, Func<double, double> distribution)
{
double step = 1.0 / (count - 1);
for (int i = 0; i < count; i++)
yield return distribution(i * step);
}
You can use any kind of distribution function which maps [0;1] to [0;1] this way. Examples:
quadratic
Spread(0, 16, 6, x => 1-(1-x)*(1-x))
Output: 0 5.76 10.24 13.44 15.36 16
sine
Spread(0, 16, 6, x => Math.Sin(x * Math.PI / 2))
Output: 0 4.94427190999916 9.40456403667957 12.9442719099992 15.2169042607225 16
Basically, you should have something that looks like:
Generate a random number between 0 and 1.
Implement your desired distribution function (a 1:1 function from [0,1]->[0,1]).
Scale the result of the distribution function to match your desired range.
The exact function used for the second point is determined according to how exactly you want the numbers to be distributed, but according to your requirement, you'll want a function that has more values close to 1 than 0. For example, a sin or cos function.
Tried this on paper and it worked:
given MIN, MAX, AMOUNT:
Length = MAX - MIN
"mark" MIN and MAX
Length--, AMOUNT--
Current = MIN
While AMOUNT > 1
Space = Ceil(Length * Amount / (MAX - MIN))
Current += Space
"mark" Current
By "mark" I mean select that number, or whatever you need to do with it.
Close answer, not quite though, needs to work for larger numbers.
List<int> lstMin = new List<int>();
int Min = 1;
int Max = 1500;
int Length = Max - Min;
int Current = Min;
int ConnectedClient = 7;
double Space;
while(ConnectedClient > 0)
{
Space = Math.Ceiling((double)(Length * ConnectedClient / (Max - Min)));
Current += (int)Space;
ConnectedClient--;
Length--;
lstMin.Add(Current);
}