GCD of three numbers (without using array) euclidean algorithm - c#

I have a task, that gives me a little headache here. The goal is to find Greatest Common Divisor with three integers, I succeded in doing it with two fairly easily, but with three it get's a little complicated when I can't use any arrays.
Here is the full code I used, finding gcd from two integers, tests all green:
public static int GetGcdByEuclidean(int a, int b)
{
if (a == 0 && b == 0)
{
throw new ArgumentException(null);
}
else if (a == int.MinValue)
{
throw new ArgumentOutOfRangeException(nameof(a));
}
else if (b == int.MinValue)
{
throw new ArgumentOutOfRangeException(nameof(b));
}
else
{
int abs1 = Math.Abs(a);
int abs2 = Math.Abs(b);
a = abs1;
b = abs2;
while (a != 0 && b != 0)
{
if (a > b)
{
a %= b;
}
else
{
b %= a;
}
}
return a | b;
}
}
And now I used the same principle for the GCD by three, but used something I found on web: gcd(a, b, c) = gcd(a, gcd(b, c)) = gcd(gcd(a, b), c) = gcd(gcd(a, c), b)..
public static int GetGcdByEuclidean(int a, int b, int c)
{
int result = 0;
if ((a == 0 && b == 0) && c == 0)
{
throw new ArgumentException(null);
}
else if (a == int.MinValue)
{
throw new ArgumentOutOfRangeException(nameof(a));
}
else if (b == int.MinValue)
{
throw new ArgumentOutOfRangeException(nameof(b));
}
else if (c == int.MinValue)
{
throw new ArgumentOutOfRangeException(nameof(c));
}
else
{
int abs1 = Math.Abs(a);
int abs2 = Math.Abs(b);
int abs3 = Math.Abs(c);
a = abs1;
b = abs2;
c = abs3;
while (a != 0 && b != 0 && c != 0)
{
if (a > b && a > c && b > c)
{
b %= c;
a %= b;
result = a;
}
else if (a > b && a > c && b < c)
{
c %= b;
a %= c;
result = a;
}
else if (b > a && b > c && a > c)
{
a %= c;
b %= a;
result = b;
}
else if (b > a && b > c && a < c)
{
c %= a;
b %= c;
result = b;
}
else if (c > a && c > b && a > b)
{
a %= b;
c %= a;
result = c;
}
else
{
b %= a;
c %= b;
result = c;
}
}
return result;
}
}

Just keep your solution for 2 numbers and call it from the one for three numbers by using this formula: gcd(a, b, c) = gcd(a, gcd(b, c))
public static int GetGcdByEuclidean(int a, int b)
{
// Your working solution for two numbers...
}
public static int GetGcdByEuclidean(int a, int b, int c)
{
return GetGcdByEuclidean(a, GetGcdByEuclidean(b, c));
}
Note, in C# you can have several methods with the same name, as long as the parameter lists are different. The names of the parameters do not matter, only the number or types of the parameters must be different. This is called overloading.
A solution with an arbitrary number of numbers (but at least two):
public static int GetGcdByEuclidean(int a, int b, params int[] other)
{
int gcd = GetGcdByEuclidean(a, b);
foreach (int x in other) {
gcd = GetGcdByEuclidean(gcd, x);
}
return gcd;
}

Related

How can I find the Least Common Multiple of two fractions?

Precondition: The fractions are expressed in simplest form and denom != 0.
Improper fractions are allowed.
Postcondition: Returns the LCM (as a fraction) of the two fractions.
Using System.Numerics.BigInteger for my numerator and denominator.
This is what I currently have, but I think this works only for BigInteger...not my custom made Fraction class:
public static Fraction LCM(Fraction a, Fraction b)
{
Fraction frac1, frac2;
if (a > b)
{
frac1 = a; frac2 = b;
}
else
{
frac1 = b; frac2= a;
}
for (Fraction i = new Fraction(); i < frac2; i = i.Add(new Fraction()))
{
if (frac1.Multiply(i).Divide(frac2).Simplify().num == 1)
{
return i.Multiply(frac1);
}
}
return frac1.Multiply(frac2);
}
new Fraction() returns 1/1
Fraction Class:
public class Fraction
{
public BigInteger num, denom;
public Fraction power, coef;
public Fraction()
{
num = denom = 1;
}
public Fraction(BigInteger n)
{
num = n;
denom = 1;
}
public Fraction(BigInteger num, BigInteger denom)
{
this.num = num;
this.denom = denom;
if (GCD(BigInteger.Abs(num), BigInteger.Abs(denom)) != 1 || (num > 0 && denom < 0)
|| (num < 0 && denom < 0))
{
BigInteger n = Simplify().num;
BigInteger d = Simplify().denom;
this.num = n;
this.denom = d;
}
}
public Fraction(BigInteger num, BigInteger denom, Fraction power)
{
Fraction n = new Fraction(num, denom);
coef = new Fraction();
this.num = n.num;
this.denom = n.denom;
this.power = power.Simplify();
if (power.num != 1)
{
Fraction n2 = n.Pow(power.num);
this.num = n2.num;
this.denom = n2.denom;
this.power = new Fraction(BigInteger.One, power.denom);
}
if (this.power.denom != 1)
{
Fraction n3 = SimplifyRadical();
this.num = n3.num;
this.denom = n3.denom;
if (n3.coef != null)
{
coef = new Fraction(n3.coef.num, n3.coef.denom);
}
if (n3.power != null)
{
this.power = n3.power.Simplify();
}
}
}
public Fraction(Fraction n, Fraction power)
{
BigInteger newNum = n.num;
BigInteger newDenom = n.denom;
Fraction n2 = new Fraction(newNum, newDenom, power);
num = n2.num;
denom = n2.denom;
this.power = n2.power;
if (n2.coef != null)
{
coef = n2.coef;
}
}
public Fraction Multiply(Fraction f)
{
Fraction product;
if (power != null || f.power != null)
{
if (power == null)
{
power = new Fraction(1);
}
if (f.power == null)
{
f.power = new Fraction(1);
}
Fraction LCMPower = LCM(power, f.power);
product = new Fraction(new Fraction(num, denom).Pow(power.Multiply(LCMPower.Reciprocate()).num).Multiply(new Fraction(f.num, f.denom).Pow(f.power.Multiply(LCMPower.Reciprocate()).num)), LCMPower);
}
else
{
product = new Fraction(BigInteger.Multiply(num, f.num), BigInteger.Multiply(denom, f.denom));
}
if(coef != null || f.coef != null)
{
if(coef != null && f.coef != null)
{
product.coef = coef.Multiply(f.coef);
}
else if(coef != null && f.coef == null)
{
product.coef = coef;
}
else if (coef == null && f.coef != null)
{
product.coef = f.coef;
}
}
return product;
}
public Fraction Divide(Fraction f)
{
return Multiply(f.Reciprocate());
}
public Fraction Reciprocate()
{
if (power != null)
{
return new Fraction(denom, num, power);
}
else
{
return new Fraction(denom, num);
}
}
public Fraction Raise(Fraction p)
{
Fraction newP = p;
if (p.num < 0)
{
Fraction n = Reciprocate();
num = n.num;
denom = n.denom;
newP = new Fraction(BigInteger.Abs(p.num), BigInteger.Abs(p.denom));
}
if (power != null)
{
return new Fraction(num, denom, power.Multiply(newP));
}
else
{
return new Fraction(num, denom, p);
}
}
public Fraction Pow(BigInteger p)
{
BigInteger newNum = num;
BigInteger newDenom = denom;
bool reverse = false;
if (p < 0)
{
p = -p;
reverse = true;
}
else if (p == 0)
{
return new Fraction();
}
if (power != null)
{
if (reverse)
{
return new Fraction(newDenom, newNum, power.Multiply(new Fraction(p)));
}
else
{
return new Fraction(newNum, newDenom, power.Multiply(new Fraction(p)));
}
}
else
{
for (int i = 1; i < p; i++)
{
newNum = BigInteger.Multiply(newNum, num);
newDenom = BigInteger.Multiply(newDenom, denom);
}
if (reverse)
{
return new Fraction(newDenom, newNum);
}
else
{
return new Fraction(newNum, newDenom);
}
}
}
public bool IsOne()
{
Fraction ONE = new Fraction();
return num == 1 && denom == 1;
}
public bool IsZero()
{
Fraction ZERO = new Fraction(0);
return num == 0;
}
public static List<BigInteger> PrimeFactorization(BigInteger Fraction)
{
BigInteger prime = new BigInteger(2);
List<BigInteger> primesArr = new List<BigInteger>();
while (Fraction >= prime * prime)
{
if (Fraction % prime == 0)
{
primesArr.Add(prime);
Fraction /= prime;
}
else
{
prime++;
}
}
primesArr.Add(Fraction);
return primesArr;
}
public static BigInteger GCD(BigInteger num1, BigInteger num2)
{
while (num1 != 0 && num2 != 0)
{
if (num1 > num2)
{
num1 %= num2;
}
else
{
num2 %= num1;
}
}
if (num1 == 0)
{
return num2;
}
else
{
return num1;
}
}
public static Fraction LCM(Fraction a, Fraction b)
{
a = a.Simplify();
b = b.Simplify();
Fraction num1, num2;
if (a > b)
{
num1 = a; num2 = b;
}
else
{
num1 = b; num2 = a;
}
for (Fraction i = new Fraction(); i < num2; i = i.Add(new Fraction()))
{
if (num1.Multiply(i).Divide(num2).Simplify().num == 1)
{
return i.Multiply(num1);
}
}
return num1.Multiply(num2);
}
public static bool operator >(Fraction num1, Fraction num2)
{
return Comparison(num1, num2) > 0;
}
public static bool operator <(Fraction num1, Fraction num2)
{
return Comparison(num1, num2) < 0;
}
public static bool operator >=(Fraction num1, Fraction num2)
{
return Comparison(num1, num2) >= 0;
}
public static bool operator <=(Fraction num1, Fraction num2)
{
return Comparison(num1, num2) <= 0;
}
public static int Comparison(Fraction num1, Fraction num2)
{
Fraction newNum1 = new Fraction();
Fraction newNum2 = new Fraction();
newNum1.num = num1.num * num2.denom;
newNum1.denom = num1.denom * num2.denom;
newNum2.num = num2.num * num1.denom;
newNum2.denom = num2.denom * num1.denom;
if (newNum1.num < newNum2.num)
{
return -1;
}
else if (newNum1.num == newNum2.num)
{
return 0;
}
else if (newNum1.num > newNum2.num)
{
return 1;
}
return 0;
}
public Fraction Simplify()
{
bool nnum = false, ndenom = false;
if (num < 0)
{
nnum = true;
num = -num;
}
if (denom < 0)
{
ndenom = true;
denom = -denom;
}
BigInteger divisor = GCD(num, denom);
BigInteger numNew = num / divisor;
BigInteger denomNew = denom / divisor;
if (nnum)
{
numNew = -numNew;
}
if (ndenom)
{
numNew = -numNew;
}
if (power != null)
{
numNew = SimplifyPower().num;
denomNew = SimplifyPower().denom;
Fraction powerNew = SimplifyPower().power;
return new Fraction(numNew, denomNew, powerNew);
}
return new Fraction(numNew, denomNew);
}
private Fraction SimplifyPower()
{
return new Fraction(Pow(power.num), new Fraction(BigInteger.One, power.denom));
}
private Fraction SimplifyRadical()
{
Fraction final = new Fraction();
final.coef = new Fraction();
List<BigInteger> pN = PrimeFactorization(num);
List<BigInteger> pD = PrimeFactorization(denom);
List<BigInteger> pNDupes = FractionOfDupes(pN);
List<BigInteger> pDDupes = FractionOfDupes(pD);
int index = 0;
int position = 0;
for (int i = 0; i < pNDupes.Count; i++)
{
if (pNDupes[i] >= power.denom)
{
BigInteger pow = pNDupes[i] / power.denom;
BigInteger powLeft = pNDupes[i] - power.denom * pow;
final.coef = final.coef.Multiply(new Fraction(pN[position]).Raise(new Fraction(pow)));
final.num *= new Fraction(pN[index], 1, new Fraction(powLeft, 1)).num;
position += (int)pNDupes[i];
}
else
{
final.num *= new Fraction(pN[index], 1, new Fraction(pNDupes[i], 1)).num;
}
index += 2;
}
index = 0;
position = 0;
for (int i = 0; i < pDDupes.Count; i++)
{
if (pDDupes[i] >= power.denom)
{
BigInteger pow = pDDupes[i] / power.denom;
BigInteger powLeft = pDDupes[i] - power.denom * pow;
final.coef = final.coef.Divide(new Fraction(pD[position]).Raise(new Fraction(pow)));
final.denom *= new Fraction(pD[index], 1, new Fraction(powLeft, 1)).num;
position += (int)pDDupes[i];
}
else
{
final.denom *= new Fraction(pD[index], 1, new Fraction(pDDupes[i], 1)).num;
}
index += 2;
}
final.power = power;
return final;
}
private List<BigInteger> NumberOfDupes(List<BigInteger> a)
{
List<BigInteger> l = new List<BigInteger>();
List<BigInteger> final = new List<BigInteger>();
foreach (BigInteger el in a)
{
l.Add(el);
}
int index = 0;
for (int i = 0; i < l.Count; i++)
{
BigInteger ele = l[i];
final.Add(1);
l.RemoveAt(i);
for (int j = 0; j < l.Count; j++)
{
if (ele == l[j])
{
final[index]++;
l.RemoveAt(j);
j--;
}
}
i--;
index++;
}
return final;
}
public void Print(bool printLn)
{
if (coef != null && !(coef.num == 1 && coef.denom == 1))
{
PrintHelper(coef);
if (!(num == 1 && denom == 1))
{
Console.Write("*");
}
}
if (!IsOne() || coef == null)
{
PrintHelper(this);
}
if (power != null && !power.IsOne() && !IsOne())
{
Console.ForegroundColor = ConsoleColor.Green;
Console.Write("^");
PrintHelper(power);
}
if (printLn)
{
Console.WriteLine();
}
Console.ForegroundColor = ConsoleColor.Gray;
}
private void PrintHelper(Fraction n)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.Write("[");
Console.ForegroundColor = ConsoleColor.Gray;
Console.Write(n.num);
Console.ForegroundColor = ConsoleColor.Green;
if (n.denom != 1)
{
Console.Write("/");
Console.ForegroundColor = ConsoleColor.Gray;
Console.Write(n.denom);
Console.ForegroundColor = ConsoleColor.Green;
Console.Write("]");
}
else
{
Console.Write("]");
}
}
public Fraction Add(Fraction a)
{
Fraction newNum1 = new Fraction(Multiply(new Fraction(a.denom, a.denom)).num, denom * a.denom);
Fraction newNum2 = new Fraction(a.Multiply(new Fraction(denom, denom)).num, denom * a.denom);
return new Fraction(newNum1.num + newNum2.num, denom * a.denom);
}
}
Your integer algorithm is right, but it's based on integer arithmetic, on the idea a division, sometimes results in a natural number, and sometimes in a natural number and a Rest. This is not possible with fraction. You can dived them as you want - you will always get a new fraction - there will never be a Rest.
So this algorithm is not applicable. I found a formula, that makes a conversion:
lcm(a/b, c/d) = lcm(a,b,c,d)/lcm(b,d).
lcm(a,b,c,d)=lcm(lcm(a,b),lcm(c,d)).
So all together is
lcm(lcm(a,b),lcm(c,d))/lcm(b,d)
So you got 4 calls to the integer version of lcm, to do one lcm for a fraction.
Do not Modify your int-version of LCM.
The Fraction version would be
public static BigInteger LCM(Fraction a, Fraction b)
{
return lcm(lcm(a.num, a.denom), lcm(b.num, b.denom))/lcm(a.denom, b.denom);
}
But this will only find least natural number common multiple.
The result of lcm(1/4, 1/8) will be 1, not 1/4 as one may assume.

finding middle position in C# [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
Hello I have tried to follow learning on codeasy.net, I have reached chapter 4 where it asks this:
Write a program that reads from the console three numbers each from the new line and then outputs the middle by the value of these three numbers.
Example:
>54
>4456
>2
54
I have tried all the code I know as a beginner and it is still wrong. My current code is this:
using System;
namespace ConsoleInput
{
public class TheMiddle
{
public static void Main(string[] args)
{
int a = int.Parse(Console.ReadLine());
int b = int.Parse(Console.ReadLine());
int c = int.Parse(Console.ReadLine());
if (a < b && c < b)
Console.WriteLine(a);
if (a < b && b < c)
Console.WriteLine(b);
if (c < b && a < c)
Console.WriteLine(c);
if (a < b && c > b )
Console.WriteLine(a);
else
if (a > b && c > a)
Console.WriteLine(a);
if (a > b && b > c)
Console.WriteLine(b);
if (c > b && b > a)
Console.WriteLine(a);
if (b > a && c > a)
Console.WriteLine(c);
}
}
}
You need to make more comparisons. There are 3 cases.
if((a <= b && b <= c) || (c <= b && b <= a))
Console.WriteLine(b);
if((b <= a && a <= c) || (c <= a && a <= b))
Console.WriteLine(a);
if((a <= c && c <= b) || (b <= c && c <= a))
Console.WriteLine(c);
Basically the number is in the middle of the other two and you have to check the case where the the other two numbers are on either side. So for example b is in the middle if it's between a and c in that order, or between c and a in that order.
using System;
namespace ConsoleInput
{
public class TheMiddle
{
public static void Main(string[] args)
{
int a = int.Parse(Console.ReadLine());
int b = int.Parse(Console.ReadLine());
int c = int.Parse(Console.ReadLine());
int result;
if (a < b)
{
if (c < a)
result = a;
else if (c > b)
result = b;
else
result = c;
}
else
{
if (c < b)
result = b;
else if (c > a)
result = a;
else
result = c;
}
Console.WriteLine(result);
}
}
}
this is the answer.
You can do this just by sorting your values and taking middle:
var list = new List<int>();
list.Add(a);
list.Add(b);
list.Add(c);
list.Sort();
var middleValue = list[list.Count/2];

Return value only of last iteration

I am trying to calculate the Greatest Common Divisor using a while loop. I am therefore looking for the greatest number (i.e. the last value of the loop). How do I get rid of the preceding numbers?
Example:
The greatest common divisor of 84 and 18 is 6. However, my code gives me the numbers 2, 3, and 6. What do I need to change to get only the last number?
using System;
namespace CalculateGCD
{
class Program
{
static void Main(string[] args)
{
int a = int.Parse(Console.ReadLine());
int b = int.Parse(Console.ReadLine());
int i = 1;
while (i <= Math.Min(a, b))
{
i++;
if (a % i == 0 && b % i == 0)
{
Console.WriteLine("GCD:{0}", i);
}
}
}
}
}
Define a variable called max then print the max out of the while loop like this:
int max = 0;
while (i <= Math.Min(a, b))
{
i++;
if (a % i == 0 && b % i == 0)
{
max = i;
}
}
Console.WriteLine("GCD:{0}", max);
Also if you are using C# 6 you could simplify your Console.WriteLine by using string interpolation like this:
Console.WriteLine($"GCD:{max}");
There is a simple solution which will calculate GCD
static int GCD(int a, int b) {
return b == 0 ? a : GCD(b, a % b);
}
and you can use it like below
using System;
namespace CalculateGCD
{
public class Program
{
public static void Main(string[] args)
{
int a = int.Parse(Console.ReadLine());
int b = int.Parse(Console.ReadLine());
Console.WriteLine(GCD(a,b));
}
static int GCD(int a, int b)
{
return b == 0 ? a : GCD(b, a % b);
}
}
}
You can invert the loop, insted of going from 1 to the Min between a and b, search from the Min to 1.
int i = Math.Min(a, b);
while (i > 0)
{
i--;
if (a % i == 0 && b % i == 0)
{
Console.WriteLine("GCD:{0}", i);
break;
}
}
simply reverse the enumeration sequence will do
int a = int.Parse(Console.ReadLine());
int b = int.Parse(Console.ReadLine());
int i = Math.Min(a ,b);
while (i > 1)
{
if (a % i == 0 && b % i == 0)
{
Console.WriteLine("GCD:{0}", i);
break;//greatest will be the first
}
i--;
}
int gcd;
while (i <= Math.Min(a, b))
{
i++;
if (a % i == 0 && b % i == 0)
{
gcd=i;
}
}
Console.WriteLine("GCD:{0}",gcd);
Save greatest common divisor in a variable.

Find the nth element in a tribonacci series

I found this as a Microsoft interview question (see Round 4). I am trying to solve it using C#. My attempt:
private static int NTerm_Tribonacci(int term)
{
int a = 0;
int b = 1;
int c = 1;
int result = 0;
if (term == 1) return a;
if (term == 2) return b;
if (term == 3) return c;
for (int i = 4; i <= term; i++)
{
a = a + b + c; if ((1 + 3 * i) % term == 0) { result = a; break; }
b = a + b + c; if ((2 * i + i - 1) % term == 0) { result = b; break; }
c = a + b + c; if ((3 * i) % term == 0) { result = c; break; }
}
return result;
}
But it is somehow not working var res = NTerm_Tribonacci(5);//should be 4 but getting 44
How can I solve this?
Tribonacci Number
Try this:
private static int NTerm_Tribonacci(int term)
{
int a = 0;
int b = 1;
int c = 1;
int result = 0;
if (term == 0) result = a;
if (term == 1) result = b;
if (term == 2) result = c;
while(term > 2)
{
result = a + b + c;
a = b;
b = c;
c = result;
term--;
}
return result;
}
Note that as per the definition in your link, I have assumed the first term to be T0, not T1.
Demo
I like the "LINQ way" of solving such things:
public IEnumerable<long> InfiniteTribonacciSequence()
{
long a = 0, b = 1, c = 1;
long nextTerm;
yield return a;
yield return b;
yield return c;
while (true)
{
nextTerm = a + b + c;
yield return nextTerm;
a = b;
b = c;
c = nextTerm;
}
}
But this has to be used carefully, because Methods like Min() will go crazy with this. But you can use e.g. InfiniteTribonacciSequence.Take(5).Last() to get the 5th element of the sequence.
I think the recursive way is too suitable for such cases:
example:
using System.IO;
using System;
class Program
{
static void Main()
{
int a=4, b;
b=tribo(a);
Console.WriteLine(b);
}
static public int tribo(int n)
{
if(n==0) return 0;
if(n==1) return 1;
if(n==2) return 1;
return(tribo(n-1)+tribo(n-2)+tribo(n-3));
}
}
this gives the series 0 1 1 2 4 7 13 24 ...

Converting C# code to Java code

I have to convert this little piece of C# code to Java:
const int AM = 65521;
int GetCCSufix(string a)
{
int c = 1, b = 0, d, e;
var chars = a.ToCharArray();
for(e =0; e< chars.Length; e ++)
{
d = chars[e];
c = (c + d) % AM;
b = (b + c) % AM;
}
return b << 16 | c;
}
And I made it this:
private int getSuffix(String a) {
int constant = 65521;
int c = 1;
int b = 0;
int d = 0;
int e = 0;
for(e = 0; e < a.length(); e++){
d = a.charAt(e);
c = (c + d) % constant;
b = (b + c) % constant;
}
return b << 16 | c;
}
However, this doesn't seem to give me the same output as the C# code. What am i doing wrong?
I did a verbatim translation of the original code, see if this gives the correct result. What values are you using for testing, that give different results?
private static final int AM = 65521;
int getCCSuffix(String a) {
int c = 1, b = 0, d = 0, e;
char[] chars = a.toCharArray();
for (e = 0; e < chars.length; e++) {
d = chars[e];
c = (c + d) % AM;
b = (b + c) % AM;
}
return b << 16 | c;
}

Categories