.NET Stops on sorting and Icompare() - c#

I'm having a problem with sorting and IComparer(). My program stops on it. I'm a beginner with C#.
Here is the part of the code where it stops:
public ArrayList ModelSort()
{
IComparer sorter = new R2SortHelper();
InnerList.Sort(sorter);
return InnerList;
}
private class R2SortHelper : System.Collections.IComparer
{
public int Compare(object x, object y)
{
double m1 = ((Model)x).R2() + ((Model)x).Valid().GetHashCode();
double m2 = ((Model)y).R2() + ((Model)y).Valid().GetHashCode();
if (m1 > m2)
return -1;
else if (m1 < m2)
return 1;
else
return 0;
}
}
Here is an error from console:
Unable to sort because the IComparer.Compare() method returns inconsistent results. Either a value does not compare equal to itself, or one value repeatedly compared to another value yields different results. IComparer: 'AMO.EnPI.AddIn.Utilities.ModelCollection+R2SortHelper'.
List of exceptions:
Exception Text
System.ArgumentException: Unable to sort because the IComparer.Compare() method returns inconsistent results. Either a value does not compare equal to itself, or one value repeatedly compared to another value yields different results. IComparer: 'AMO.EnPI.AddIn.Utilities.ModelCollection+R2SortHelper'.
at System.Array.SorterObjectArray.DepthLimitedQuickSort(Int32 left, Int32 right, Int32 depthLimit)
at System.Array.SorterObjectArray.DepthLimitedQuickSort(Int32 left, Int32 right, Int32 depthLimit)
at System.Array.Sort(Array keys, Array items, Int32 index, Int32 length, IComparer comparer)
at System.Collections.ArrayList.Sort(Int32 index, Int32 count, IComparer comparer)
at System.Collections.ArrayList.Sort(IComparer comparer)
at AMO.EnPI.AddIn.Utilities.ModelCollection.ModelSort() in C:\ENPI\EnPI\AMO.EnPI-5.0\AMO.EnPI.Utilities\Analytics.cs:line 961
at AMO.EnPI.AddIn.ModelSheet.WriteResultsTable(Int32 n, Boolean top) in C:\ENPI\EnPI\AMO.EnPI-5.0\AMO.EnPI.AddIn\ModelSheet.cs:line 146
at AMO.EnPI.AddIn.ModelSheet.Populate() in C:\ENPI\EnPI\AMO.EnPI-5.0\AMO.EnPI.AddIn\ModelSheet.cs:line 60
at AMO.EnPI.AddIn.ThisAddIn.plotEnPI(ListObject LO) in C:\ENPI\EnPI\AMO.EnPI-5.0\AMO.EnPI.AddIn\ThisAddIn.cs:line 318
at AMO.EnPI.AddIn.RegressionControl.runFunction(Object sender, EventArgs e) in C:\ENPI\EnPI\AMO.EnPI-5.0\AMO.EnPI.AddIn\RegressionControl.cs:line 817
at AMO.EnPI.AddIn.CO2EmissionControl.btnCalculate_Click(Object sender, EventArgs e) in C:\ENPI\EnPI\AMO.EnPI-5.0\AMO.EnPI.AddIn\CO2EmissionControl.cs:line 148
My model class:
public class Model
{
public int ModelNumber { get; set; }
public double[] Ys { get; set; }
public double[,] Xs { get; set; }
public string[] VariableNames { get; set; }
public double RMSError { get; set; }
public double[] Coefficients { get; set; }
public Model()
{
ModelNumber = 0;
Ys = null;
Xs = null;
VariableNames = null;
RMSError = 0;
Coefficients = null;
}
public Model(int ModelNumber, double[] Ys, double[,] Xs, string[] VariableNames)
{
RMSError = 0;
Coefficients = null;
// run LLS
int info;
double[] c;
alglib.lsfitreport rep;
try
{
alglib.lsfitlinear(Ys, Xsplusone(), out info, out c, out rep);
}
catch
{
throw;
}
Coefficients = c;
RMSError = rep.rmserror;
}
public void Run() //double[] Ys, double[,] Xs, string[] VariableNames)
{
RMSError = 0;
Coefficients = null;
if (Ys != null && Xs != null)
{
// run LLS
int info;
double[] c;
alglib.lsfitreport rep;
try
{
alglib.lsfitlinear(Ys, Xsplusone(), out info, out c, out rep);
}
catch
{
throw;
}
Coefficients = c;
RMSError = rep.rmserror;
}
}
public int N()
{
return Ys.Count();
}
public int df()
{
return N() - k() - 1;
}
public int k()
{
return VariableNames.Count();
}
public double TotalSS()
{
// compute total sum of squares
double ybar = Ys.Average();
double sst = 0;
for (int i = Ys.GetLowerBound(0); i <= Ys.GetUpperBound(0); i++)
{
sst += Math.Pow(Ys[i] - ybar, 2);
}
return sst;
}
public double ResidualSS ()
{
return ( N() * Math.Pow( RMSError, 2));
}
public double R2()
{
return (1 - (ResidualSS() / TotalSS()));
}
public double AdjustedR2()
{
return (1 - (((1 - R2()) * (N() - 1)) / (N() - k() - 1)));
}
public double F()
{
return ( (R2() / k()) / ((1 - R2()) / (N() - k() - 1)));
}
public double ModelPValue()
{
double modelP = 0;
double modelF = F();
if (modelF < 0) modelF = 0;
try
{
modelP = alglib.fcdistribution(N() - df() - 1, df(), modelF);
}
catch (alglib.alglibexception e)
{
}
return modelP;
}
public bool Valid()
{
// Model validity criteria, from the SEP M&V protocol:
// The model p-value must be less than 0.1
// All variables must have p-values less than 0.2
// At least one variable must have a p-value of less than 0.1
// The R2 value must be greater than 0.5
double[] ps = PValues();
bool varsvalid = true;
bool varlowexists = false;
for (int i = 0; i < ps.Count(); i++)
{
if (ps[i] <= Constants.PVALUE_THRESHOLD)
varlowexists = true;
if (ps[i] > Constants.PVALUE_HIGH)
varsvalid = false;
}
if (!varlowexists)
return false;
if (!varsvalid)
return false;
if (ModelPValue() > Constants.PVALUE_THRESHOLD)
return false;
if (R2() < Constants.R2VALUE_MIN)
return false;
return true;
}
public string Formula()
{
string formula = "";
int offset = Coefficients.GetLowerBound(0) - VariableNames.GetLowerBound(0);
for (int i = Coefficients.GetLowerBound(0); i < Coefficients.GetUpperBound(0); i++)
{
formula += "(" + Coefficients[i].ToString("0.0000") + " * " + ExcelHelpers.CreateValidFormulaName(VariableNames[i - offset]) + ") + ";
// formula += "(" + Coefficients[i].ToString() + " * " + ExcelHelpers.CreateValidFormulaName(VariableNames[i - offset]) + ") + ";
}
formula += Coefficients[Coefficients.GetUpperBound(0)].ToString("0.00");
return formula;
}
public double[,] Xsplusone()
{
return DataHelper.arrayAddIdentity(Xs, 0, 1); // add on a column of ones for the intercept
}
public double[] PredictedYs()
{ // compute the predicted ys
double[] yhat = new double[N()];
double[,] xs = Xsplusone();
double[] c = Coefficients;
for (int i = 0; i < N(); i++)
{
yhat[i] = 0;
for (int j = 0; j < k() + 1; j++)
{
yhat[i] += xs[i, j] * c[j];
}
}
return yhat;
}
public double[,] CovarianceMatrix()
{
// compute the coefficient covariance matrix
double[,] twodYs = DataHelper.dbl2DArray(Ys);
double[,] XYs = DataHelper.dblarrayUnion(Xs, twodYs);
double[,] cov;
int info;
alglib.linearmodel lm;
alglib.lrreport rpt;
try
{
alglib.lrbuild(XYs, N(), k(), out info, out lm, out rpt);
cov = rpt.c;
}
catch
{
throw;
}
return cov;
}
public double[] StandardErrors()
{
// compute the x std errors and p-values
double[,] cov = CovarianceMatrix();
double[] se = new double[k()];
if (cov.GetLength(0) > 0 && cov.GetLength(1) > 0)
{
for (int j = 0; j < k(); j++)
{
se[j] = Math.Sqrt(cov[j, j]);
}
}
return se;
}
public double[] PValues()
{
double[] c = Coefficients;
double[,] cov = CovarianceMatrix();
double[] se = StandardErrors();
double[] pv = new double[k()];
if (cov.GetLength(0) > 0 && cov.GetLength(1) > 0)
{
for (int j = 0; j < k(); j++)
{
se[j] = Math.Sqrt(cov[j, j]);
try
{
pv[j] = 2 * (1 - alglib.studenttdistribution(df(), Math.Abs(c[j] / se[j])));
}
catch
{
}
}
}
return pv;
}
public string AICFormula()
{
return "";
}
//Added By Suman for SEP Validation changes
public string[] SEPValidationCheck()
{
string[] sepChk = new string[k()];
for (int cnt = 0; cnt < sepChk.Length; cnt++)
{
if (Valid() == true)
{
sepChk[cnt] = "Pass";
}
else
{
sepChk[cnt] = "Fail";
}
}
return sepChk;
}
}
Here is GetHashCode():
public override int GetHashCode()
{
return x.GetHashCode() ^ y.GetHashCode();
}
My R2():
public double R2()
{
return (1 - (ResidualSS() / TotalSS()));
}

For the majority of types, you can't sort by GetHashCode() since the hash code calculations aren't necessarily going to sort in the same order as the value. You can only sort on GetHashCode() reliably when it is the value itself (such as int), but at that point there isn't any point in getting the hash code since you already have the value. Also you didn't show what R2() and Valid() methods do, so who knows what kind of unholyness is going on in there.
EDIT (OP updated code):
Your GetHashCode() usage is definitely not sortable. Nor is adding a boolean to a double. 5 + 0 vs. 2 + 1 is not going to sort correctly (assuming you want the falses up front?)
Just use ((Model)x).R2() vs ((Model)y).R2() as the comparison, if you want the falses or trues up front, you can add something like:
if (x.Valid && !y.Valid)
return 1;
if (!x.Valid && y.Valid)
return -1;
//then do your R2 comparisons here.
That preamble will cause the non valids to always come first and then sort by R2s. You can reverse if you want to go the other way.

Your .Valid() method is returning boolean, and then you go to find hash code. Is this expected from your code?
Basically, you are doing some double value + boolean.GetHashCode(). Solution would be to not use .Valid() in your right side expression. Check that separately.
private class R2SortHelper : System.Collections.IComparer
{
public int Compare(object x, object y)
{
Model xModel = (Model)x;
Model yModel = (Model)y;
if((Model.Valid()==true) && (yModel.Valid()==true))
{
double m1 = xModel.R2() + xModel.GetHashCode();
double m2 = yModel.R2() + yModel.GetHashCode();
return (m1 > m2) ? -1 : ((m1 < m2) ? 1 :0);
}
return 0;
}
}

Related

how to fix IComparable<T> while creating a priority queue

this is a priority queue that I found at GitHub
public class PriorityQueue<T> where T : IComparable<T>
{
private List<T> data;
public PriorityQueue()
{
this.data = new List<T>();
}
public void Enqueue(T item)
{
data.Add(item);
int ci = data.Count - 1; // child index; start at end
while (ci > 0)
{
int pi = (ci - 1) / 2; // parent index
if (data[ci].CompareTo(data[pi]) >= 0) break; // child item is larger than (or equal) parent so we're done
T tmp = data[ci]; data[ci] = data[pi]; data[pi] = tmp;
ci = pi;
}
}
public T Dequeue()
{
// assumes pq is not empty; up to calling code
int li = data.Count - 1; // last index (before removal)
T frontItem = data[0]; // fetch the front
data[0] = data[li];
data.RemoveAt(li);
--li; // last index (after removal)
int pi = 0; // parent index. start at front of pq
while (true)
{
int ci = pi * 2 + 1; // left child index of parent
if (ci > li) break; // no children so done
int rc = ci + 1; // right child
if (rc <= li && data[rc].CompareTo(data[ci]) < 0) // if there is a rc (ci + 1), and it is smaller than left child, use the rc instead
ci = rc;
if (data[pi].CompareTo(data[ci]) <= 0) break; // parent is smaller than (or equal to) smallest child so done
T tmp = data[pi]; data[pi] = data[ci]; data[ci] = tmp; // swap parent and child
pi = ci;
}
return frontItem;
}
public T Peek()
{
T frontItem = data[0];
return frontItem;
}
public int Count()
{
return data.Count;
}
public override string ToString()
{
string s = "";
for (int i = 0; i < data.Count; ++i)
s += data[i].ToString() + " ";
s += "count = " + data.Count;
return s;
}
public bool IsConsistent()
{
// is the heap property true for all data?
if (data.Count == 0) return true;
int li = data.Count - 1; // last index
for (int pi = 0; pi < data.Count; ++pi) // each parent index
{
int lci = 2 * pi + 1; // left child index
int rci = 2 * pi + 2; // right child index
if (lci <= li && data[pi].CompareTo(data[lci]) > 0) return false; // if lc exists and it's greater than parent then bad.
if (rci <= li && data[pi].CompareTo(data[rci]) > 0) return false; // check the right child too.
}
return true; // passed all checks
} // IsConsistent
I have create an adge class like this:
public class Node
{
long x;
long y;
public long parent;
public long rank;
public Node(long a, long b, long c)
{
x = a;
y = b;
parent = c;
rank = 0;
}
}
public class Edge : IComparable<Edge>
{
public long u;
public long v;
public double weight;
public Edge(long a, long b, double c)
{
u = a;
v = b;
weight = c;
}
public int CompareTo(Edge e1, Edge e2)
{
return e1.weight < e2.weight ? -1 : 1;
}
public int CompareTo(Edge other)
{
throw new NotImplementedException();
}
}
when I try to create an instance form priority queue class with edges I have an error like this:
PriorityQueue<Edge> edges = new PriorityQueue<Edge>();
The type 'A4.Edge' cannot be used as type parameter 'T' in the generic type or method 'PriorityQueue'. There is no implicit reference conversion from 'A4.Edge' to 'System.IComparable
how can I fix this?
As of the defintion of your PriorityQueue-class T must implement IComparable<T>. Your Edge-class does not implement that interface, so you get the compiler-error-
Your Edge-class has to provide some way in order to compare an instance of it with another instance. That's done by implementing the IComparable<T>-interface:
public class Edge : IComparable<Edge>
{
public long u;
public long v;
public double weight;
public Edge(long a, long b, double c)
{
u = a;
v = b;
weight = c;
}
public int CompareTo(Edge other)
{
// your comparison here
}
}
Now as your class already provide some mechanism to make it comparable you won´t need to provide a Comparer to your PriorityQueue-class at all. In fact you don´t even use it in your code, so omit the parameter from the constructor:
PriorityQueue<Edge> edges = new PriorityQueue<Edge>();

My single layer perceptrone is not working

Here is code.
public class Adaline
{
private int _layer;
public int Layer { get { return _layer; } }
private int _epoch;
public int Epoch { get { return _epoch; } }
private double _error;
public double Error { get { return _error; } }
private double[] _weights;
public Adaline(int layer)
{
_layer = layer;
_weights = new double[layer];
Reset();
}
public void Reset()
{
Random r = new Random();
for (int i = 0; i < _layer; i++)
_weights[i] = r.NextDouble() - 0.5;
_error = 1;
}
public void Train(BasicTrainSet<double> trainset, double learnRate)
{
double ers = 0;
for(int p = 0; p < trainset.DataCount; p++)
{
double result = Compute(trainset.Input[p], true);
double error = trainset.Output[p] - result;
for (int i = 0; i < _weights.Length; i++)
{
_weights[i] += error * trainset.Input[p][i] * learnRate;
}
ers += Math.Abs(error);
}
_epoch++;
_error = ers;
}
public double Compute(double[] input, bool quan)
{
double result = 0;
for (int i = 0; i < _layer; i++)
result += Math.Tanh(_weights[i] * input[i]);
//double result = _weights.Zip(input, (a, b) => Math.Tanh(a * b)).Sum();
return quan ? (result >= 0 ? 1 : 0) : result;
}
}
When I tried to train and gate like this, it works like this.
Up four results are from this code
This is pretty weird, because there is not any problem with algorithm.
Weights are getting bigger and bigger. Where did i mistake?
In your code to compute the output of each neuron, you aren't applying the activation function correctly. You need to find the dot product between the weights and the inputs into each neuron then apply the activation function after. You are applying the activation function after each weighted accumulation, which is not correct.
Accumulate, then apply the activation function:
public double Compute(double[] input, bool quan)
{
double result = 0;
for (int i = 0; i < _layer; i++)
result += _weights[i] * input[i]; // Change - accumulate first
result = Math.Tanh(result); // Change - now apply activation function
return quan ? (result >= 0 ? 1 : 0) : result;
}

Find ascending duplicate pairs in an array

Given an array A with zero index and N integers find equal elements with different positions in the array. Pair of indexes (P,Q) such that 0 <= P < Q < N such that A[P] = A[Q]. My algorithm is below but I am looking for a O(N*logN) solution.
public int solution(int[] A)
{
int N = A.Length;
int count = 0;
for (int j = 0; j < N; j++)
{
count += FindPairs(A[j], j, A);
}
return count;
}
public int FindPairs(int item, int ci, int[] A)
{
int len = A.Length;
int counter=0;
int k = ci+1;
while (k < len)
{
if (item == A[k])
counter++;
k++;
}
return counter;
}
From your code, it looks like the goal is to return the count of ascending duplicate pairs in A.
We observe that if there are m occurrences of the number x in A, then the number of ascending duplicate pairs of the value x is m choose 2, or m (m - 1) / 2.
So, we sum up m (m - 1) / 2 for each unique x, giving us the answer.
In pseudocode, this looks like:
count = new Dictionary();
foreach a in A {
count[a]++;
}
total = 0;
foreach key, value in count {
total += value * (value - 1) / 2;
}
return total;
This algorithm is O(N).
Recent interview question … here is what I did:
using System;
using System.Collections.Generic;
using System.Linq;
namespace Codility
{
internal class Program
{
public struct Indice
{
public Indice(int p, int q)
{
P = p;
Q = q;
}
public int P;
public int Q;
public override string ToString()
{
return string.Format("({0}, {1})", P, Q);
}
}
private static void Main(string[] args)
{
// 0 1 2 3 4 5
int[] list = new int[] {3,3,3,3,3,3};
int answer = GetPairCount(list);
Console.WriteLine("answer = " + answer);
Console.ReadLine();
}
private static int GetPairCount(int[] A)
{
if (A.Length < 2) return 0;
Dictionary<int, Dictionary<Indice, Indice>> tracker = new Dictionary<int, Dictionary<Indice, Indice>>();
for (int i = 0; i < A.Length; i++)
{
int val = A[i];
if (!tracker.ContainsKey(val))
{
Dictionary<Indice, Indice> list = new Dictionary<Indice, Indice>();
Indice seed = new Indice(i, -1);
list.Add(seed, seed);
tracker.Add(val, list);
}
else
{
Dictionary<Indice, Indice> list = tracker[val];
foreach (KeyValuePair<Indice,Indice> item in list.ToList())
{
Indice left = new Indice(item.Value.P, i);
Indice right = new Indice(i, item.Value.Q);
if (!list.ContainsKey(left))
{
list.Add(left, left);
Console.WriteLine("left= " + left);
}
if (!list.ContainsKey(right))
{
list.Add(right, right);
Console.WriteLine("\t\tright= " + right);
}
}
}
}
return tracker.SelectMany(kvp => kvp.Value).Count(num => num.Value.Q > num.Value.P);
}
}
}
I think this is best version I got in c#.
static void Main(string[] args)
{
var a = new int[6] { 3, 5, 6, 3, 3, 5 };
//Push the indices into an array:
int[] indices = new int[a.Count()];
for (int p = 0; p < a.Count(); ++p) indices[p] = p;
//Sort the indices according to the value of the corresponding element in a:
Array.Sort(indices, (k, l) =>Compare(a[k], a[l]));
//Then just pull out blocks of indices with equal corresponding elements from indices:
int count = 0;
int i = 0;
while (i < indices.Count())
{
int start = i;
while (i < indices.Count() && a[indices[i]] == a[indices[start]])
{
++i;
}
int thisCount = i - start;
int numPairs = thisCount * (thisCount - 1) / 2;
count += numPairs;
}
Console.WriteLine(count);
Console.ReadKey();
}
//Compare function to return interger
private static int Compare(int v1, int v2)
{
if (v2 > v1)
return 1;
if (v1 == v2)
return 0;
else
return -1;
}
This approach has O(n log n) complexity overall, because of the sorting. The counting of the groups is linear.
Try this:
private static int GetIdenticalPairCount(int[] input)
{
int identicalPairCount = 0;
Dictionary<int, int> identicalCountMap = new Dictionary<int, int>();
foreach (int i in input)
{
if (identicalCountMap.ContainsKey(i))
{
identicalCountMap[i] = identicalCountMap[i] + 1;
if (identicalCountMap[i] > 1)
{
identicalPairCount += identicalCountMap[i];
}
else
{
identicalPairCount++;
}
}
else
{
identicalCountMap.Add(i, 0);
}
}
return identicalPairCount;
}
Test my version:
public int solution(int[] A)
{
int N = A.Length;
int count = 0;
for (int j = 0; j < N - 1; j++)
for (int i = j + 1; i < N; i++)
if (A[i] == A[j])
count++;
return count;
}

C# find the greatest common divisor

"The greatest common divisor of two integers is the largest integer that evenly divides each of the two numbers. Write method Gcd that returns the greatest common divisor of two integers. Incorporate the method into an app that reads two values from the user and displays the result."
(this is not homework, just an exercise in the book I'm using)
can you help me solve this? Here's what I've got so far.
(edit - I can submit the two numbers but it won't calculate the Gcd for me)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Greatest_Common_Divisor
{
class Program
{
static int GetNum(string text)
{
bool IsItANumber = false;
int x = 0;
Console.WriteLine(text);
do
{
IsItANumber = int.TryParse(Console.ReadLine(), out x);
} while (!IsItANumber);
return x;
}
static void Main(string[] args)
{
string text = "enter a number";
int x = GetNum(text);
text = "enter a second number";
int y = GetNum(text);
int z = GCD(x, y);
Console.WriteLine(z);
}
private static int GCD(int x, int y)
{
int v = 0;
int n = 0;
v = GetGreatestDivisor(x, y);
return v;
}
static int GetGreatestDivisor(int m, int h)
{
do
{
for (int i = m; i <= 1; i--)
if (m%i == 0 && h%i == 0)
{
int x = 0;
x = i;
return x;
}
} while (true);
return m;
}
}
}
Here's an implementation of the Euclidean algorithm that returns the greatest common divisor without performing any heap allocation.
You can substitute ulong for uint if needed. An unsigned type is used, as the technique does not work for signed values. If you know your a and b values are not negative, you can use long or int instead.
private static ulong GCD(ulong a, ulong b)
{
while (a != 0 && b != 0)
{
if (a > b)
a %= b;
else
b %= a;
}
return a | b;
}
This method is used in my metadata-extractor library, where it has associated unit tests.
Using LINQ's Aggregate method:
static int GCD(int[] numbers)
{
return numbers.Aggregate(GCD);
}
static int GCD(int a, int b)
{
return b == 0 ? a : GCD(b, a % b);
}
Note: answer above borrowed from accepted answer to Greatest Common Divisor from a set of more than 2 integers.
You can try using this:
static int GreatestCommonDivisor(int[] numbers)
{
return numbers.Aggregate(GCD);
}
static int GreatestCommonDivisor(int x, int y)
{
return y == 0 ? x : GreatestCommonDivisor(y, x % y);
}
Try this:
public static int GCD(int p, int q)
{
if(q == 0)
{
return p;
}
int r = p % q;
return GCD(q, r);
}
public class GCD
{
public int generalizedGCD(int num, int[] arr)
{
int gcd = arr[0];
for (int i = 1; i < num; i++) {
gcd = getGcd(arr[i], gcd);
}
return gcd;
}
public int getGcd(int x, int y)
{
if (x == 0)
return y;
return getGcd(y % x, x);
}
}
Here is a simple solution.
You can use BigInteger to get the greatest common divisor. Just do not forget to add using System.Numerics; to the top of your code.
using System.Numerics;
public class Program{
public static void Main(String[] args){
int n1 = 1;
int n2 = 2;
BigInteger gcd = BigInteger.GreatestCommonDivisor(n1,n2);
Console.WriteLine(gcd);
}
}
Offical Documentation
By using this, you can pass multiple values as well in the form of array:-
// pass all the values in array and call findGCD function
int findGCD(int arr[], int n)
{
int gcd = arr[0];
for (int i = 1; i < n; i++) {
gcd = getGcd(arr[i], gcd);
}
return gcd;
}
// check for gcd
int getGcd(int x, int y)
{
if (x == 0)
return y;
return gcd(y % x, x);
}
List<int> gcd = new List<int>();
int n1, n2;
bool com = false;
Console.WriteLine("Enter first number: ");
n1 = int.Parse(Console.ReadLine());
Console.WriteLine("Enter second number: ");
n2 = int.Parse(Console.ReadLine());
for(int i = 1; i <= n1; i++)
{
if(n1 % i == 0 && n2% i == 0)
{
gcd.Add(i);
}
if(i == n1)
{
com = true;
}
}
if(com == true)
{
Console.WriteLine("GCD of {0} and {1} is {2}.", n1, n2, gcd[gcd.Count - 1]);
}
Console.ReadLine();
If efficiency is not a big concern this will do the job.
// gets greatest common divisor of A and B.
var GCD=Enumerable.Range(1,Math.Min(A,B)).Last(n=>(A%n | B%n)==0);
int[] nums = new int[] {6,12,24,48};
int GCD(int a, int b) => b == 0 ? a : GCD(b, a % b);
int FindGCD(int[] numbers) => numbers.Aggregate(GCD);
Console.WriteLine($"List of numbers ({String.Join(',',nums)})");
Console.WriteLine($"Smallest number: {nums.Min()}");
Console.WriteLine($"Largest number: {nums.Max()}");
Console.WriteLine($"Greatest common devisor of {nums.Min()} and {nums.Max()}: {GCD(nums.Min(),nums.Max())}");
Console.WriteLine($"Aggregate common devisor of array ({String.Join(',',nums)}): {FindGCD(nums)}");
List of numbers (6,12,24,48)
Smallest number: 6
Largest number: 48
Greatest common devisor of 6 and 48: 6
Aggregate common devisor of array (6,12,24,48): 6
using System;
//Write a function that returns the greatest common divisor (GCD) of two integers
namespace GCD_of_Two_Numbers
{
class Program
{
public static void Gcd(int num1, int num2)
{
int[] temp1 = new int[num1];
int[] temp2 = new int[num2];
int[] common = new int[10];
for(int i=2;i<num1/2;i++)
{
if(num1 % i ==0)
{
temp1[i] = i;
}
}
for (int i = 2; i < num2/2; i++)
{
if (num2 % i == 0)
{
temp2[i] = i;
}
}
int len = temp1.Length + temp2.Length;
for(int i=0;i<len;i++)
{
if(temp1[i]==temp2[i])
{
common[i] = temp1[i];
}
}
int max_number = common[0];
for(int i=0;i<common.Length;i++)
{
if(max_number < common[i])
{
max_number = common[i];
}
}
Console.WriteLine($"The Greatest Common Diviser is {max_number}");
}
static void Main(string[] args)
{
Gcd(32, 8);
}
}
}
int a=789456;
int b=97845645;
if(a>b)
{
}
else
{
int temp=0;
temp=a;
a=b;
b=temp;
}
int x=1;
int y=0 ;
for (int i =1 ; i < (b/2)+1 ; i++ )
{
if(a%i==0)
{
x=i;
}
if(b%i==0)
{
y=i;
}
if ((x==y)& x==i & y==i & i < a)
{
Console.WriteLine(i);
}
}

Fractions in a NumericUpDown/DomainUpDown

Is it possible to display fractions in a NumericUpDown or a DomainUpDown?
I know there are some fonts that have various fraction characters, but I would like to keep my form using Microsoft Sans Serif uniformly.
What do you mean by upto one-tenth.
I have a sample code for you, try if it works for you
nupdwn.Minimum = -10;
nupdwn.Maximum = 10;
nupdwn.Increment = 0.25;
nupdwn.DecimalPlaces = 2;
Microsoft Sans Serif does support fractional characters:
I will try to program a derived NumericUpDown to show fractional values. If it succeeds, i will share the code here...
Here is my Sample-Code for a FractionalUpDown.
Be sure to set DecimalPlaces to your needs.
With Mode, you can choose the formatting of the value:
EMode.Decimal => 2,500.
EMode.Fractional => ⁵⁄₂
EMode.FractionalMixed => 2 ¹⁄₂
EMode.FractionalASCII => 5/2
EMode.FractionalMixedASCII => 2 1/2
Code:
public class FractionalUpDown: NumericUpDown {
//Hide Hexadecimal
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
[Bindable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new bool Hexadecimal {
get { return false; }
set { base.Hexadecimal = false; }
}
private EMode mode;
[DefaultValue(EMode.Fractional)]
public EMode Mode {
get { return mode; }
set {
if (value != mode) {
mode = value;
UpdateEditText();
}
}
}
public enum EMode {
Fractional,
FractionalMixed,
FractionalASCII,
FractionalMixedASCII,
Decimal
}
public FractionalUpDown() {
}
protected override void UpdateEditText() {
if (Mode == EMode.Decimal) {
base.UpdateEditText();
return;
}
double accuracy = Math.Pow(10.0, -(DecimalPlaces + 1));
if (accuracy > 0.1) accuracy = 0.1;
this.Text = FractionToString(DoubleToFraction((double)Value, accuracy), Mode);
}
public struct Fraction {
public Fraction(int n, int d) {
N = n;
D = d;
}
public int N { get; private set; }
public int D { get; private set; }
}
private static readonly char[] numbers = new char[10] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
private static readonly char[] numerators = new char[10] { '⁰', '¹', '²', '³', '⁴', '⁵', '⁶', '⁷', '⁸', '⁹' };
private static readonly char[] denumerators = new char[10] { '₀', '₁', '₂', '₃', '₄', '₅', '₆', '₇', '₈', '₉' };
protected string FractionToString(Fraction frac, EMode mode) {
int full = 0;
int n = frac.N;
string result = string.Empty;
bool mixed = mode == EMode.FractionalMixed ||
mode == EMode.FractionalMixedASCII;
bool useFractionalChars = mode == EMode.Fractional ||
mode == EMode.FractionalMixed;
if (mixed && Math.Abs(frac.N) >= frac.D) {
full = frac.N / frac.D;
n = Math.Abs(frac.N % frac.D);
if (full != 0) result = full.ToString();
else if (n == 0) return "0";
}
if (n != 0) {
string fracNtext = n.ToString();
string fracDtext = frac.D.ToString();
if (useFractionalChars) {
for (int i = 0; i < 10; i++) fracNtext = fracNtext.Replace(numbers[i], numerators[i]);
for (int i = 0; i < 10; i++) fracDtext = fracDtext.Replace(numbers[i], denumerators[i]);
} else {
if (full != 0) result += " ";
}
result += fracNtext + '⁄' + fracDtext;
} else {
//Fractional Part == 0/?
if (full == 0) {
if (mixed == true) {
return "0";
} else {
if (useFractionalChars) {
return numerators[0].ToString() + '⁄' + denumerators[1].ToString();
} else {
return numbers[0].ToString() + '⁄' + numbers[1].ToString();
}
}
}
}
return result;
}
//Source: https://stackoverflow.com/questions/5124743/algorithm-for-simplifying-decimal-to-fractions/32903747#32903747
protected Fraction DoubleToFraction(double value, double accuracy) {
if (accuracy <= 0.0 || accuracy >= 1.0) {
throw new ArgumentOutOfRangeException("accuracy", "Must be > 0 and < 1.");
}
int sign = Math.Sign(value);
if (sign == -1) {
value = Math.Abs(value);
}
// Accuracy is the maximum relative error; convert to absolute maxError
double maxError = sign == 0 ? accuracy : value * accuracy;
int n = (int)Math.Floor(value);
value -= n;
if (value < maxError) {
return new Fraction(sign * n, 1);
}
if (1 - maxError < value) {
return new Fraction(sign * (n + 1), 1);
}
// The lower fraction is 0/1
int lower_n = 0;
int lower_d = 1;
// The upper fraction is 1/1
int upper_n = 1;
int upper_d = 1;
while (true) {
// The middle fraction is (lower_n + upper_n) / (lower_d + upper_d)
int middle_n = lower_n + upper_n;
int middle_d = lower_d + upper_d;
if (middle_d * (value + maxError) < middle_n) {
// real + error < middle : middle is our new upper
Seek(ref upper_n, ref upper_d, lower_n, lower_d, (un, ud) => (lower_d + ud) * (value + maxError) < (lower_n + un));
upper_n = middle_n;
upper_d = middle_d;
} else if (middle_n < (value - maxError) * middle_d) {
// middle < real - error : middle is our new lower
Seek(ref lower_n, ref lower_d, upper_n, upper_d, (ln, ld) => (ln + upper_n) < (value - maxError) * (ld + upper_d));
lower_n = middle_n;
lower_d = middle_d;
} else {
// Middle is our best fraction
return new Fraction((n * middle_d + middle_n) * sign, middle_d);
}
}
}
/// <summary>
/// Binary seek for the value where f() becomes false.
/// Source: https://stackoverflow.com/questions/5124743/algorithm-for-simplifying-decimal-to-fractions/32903747#32903747
/// </summary>
protected void Seek(ref int a, ref int b, int ainc, int binc, Func<int, int, bool> f) {
a += ainc;
b += binc;
if (f(a, b)) {
int weight = 1;
do {
weight *= 2;
a += ainc * weight;
b += binc * weight;
}
while (f(a, b));
do {
weight /= 2;
int adec = ainc * weight;
int bdec = binc * weight;
if (!f(a - adec, b - bdec)) {
a -= adec;
b -= bdec;
}
}
while (weight > 1);
}
}
}

Categories

Resources