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

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.

Related

C# SPOJ time optimalization

I'm trying to get the job done MOHIBPIZ - PIZZA (https://www.spoj.com/problems/MOHIBPIZ/).
I'm already sitting on it the second day, I've tried everything I can and found on the internet. The last chance before giving up is to ask you guys
For recudces time I'm using InputOutput class created by davidsekar (https://github.com/davidsekar/C-sharp-Programming-IO/blob/master/ConsoleInOut/InputOutput.cs)
but still I have time "time limit exceeded". :(
I tried with two loops, but the method with the function seems more optimal to me. Thanks in advance for all the hints, suggestions and answers.
This is code (link on ideone: https://ideone.com/):
using System;
using System.IO;
public class Test
{
public static void Main()
{
InputOutput reader = new InputOutput();
StreamWriter _output = new StreamWriter(Console.OpenStandardOutput());
int T = reader.ReadInt();
for (int i = 0; i < T; i++)
{
_output.WriteLine(Recursion(reader.ReadInt()));
}
_output.Flush();
}
private static int Recursion(int x)
{
if(x <= 1)
{
return 2;
}
else
{
return Recursion(x - 1) + x;
}
}
#region Input Output Helper
public class InputOutput : System.IDisposable
{
private System.IO.Stream _readStream, _writeStream;
private int _readIdx, _bytesRead, _writeIdx, _inBuffSize, _outBuffSize;
private readonly byte[] _inBuff, _outBuff;
private readonly bool _bThrowErrorOnEof;
public void SetBuffSize(int n)
{
_inBuffSize = _outBuffSize = n;
}
public InputOutput(bool throwEndOfInputsError = false)
{
_readStream = System.Console.OpenStandardInput();
_writeStream = System.Console.OpenStandardOutput();
_readIdx = _bytesRead = _writeIdx = 0;
_inBuffSize = _outBuffSize = 1 << 22;
_inBuff = new byte[_inBuffSize];
_outBuff = new byte[_outBuffSize];
_bThrowErrorOnEof = throwEndOfInputsError;
}
public void SetFilePath(string strPath)
{
strPath = System.IO.Path.GetFullPath(strPath);
_readStream = System.IO.File.Open(strPath, System.IO.FileMode.Open);
}
public T ReadNumber<T>()
{
byte rb;
while ((rb = GetByte()) < '-')
;
var neg = false;
if (rb == '-')
{
neg = true;
rb = GetByte();
}
dynamic m = (T)Convert.ChangeType(rb - '0', typeof(T));
while (true)
{
rb = GetByte();
if (rb < '0')
break;
m = m * 10 + (rb - '0');
}
return neg ? -m : m;
}
public int ReadInt()
{
byte readByte;
while ((readByte = GetByte()) < '-')
;
var neg = false;
if (readByte == '-')
{
neg = true;
readByte = GetByte();
}
var m = readByte - '0';
while (true)
{
readByte = GetByte();
if (readByte < '0')
break;
m = m * 10 + (readByte - '0');
}
return neg ? -m : m;
}
public string ReadString()
{
return ReadString(' ');
}
public string ReadString(string delimiter)
{
return ReadString(delimiter[0]);
}
public string ReadString(char delimiter)
{
byte readByte;
while ((readByte = GetByte()) <= delimiter)
;
System.Text.StringBuilder sb = new System.Text.StringBuilder();
do
{
sb.Append((char)readByte);
} while ((readByte = GetByte()) > delimiter);
return sb.ToString();
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
private byte GetByte()
{
if (_readIdx >= _bytesRead)
{
_readIdx = 0;
_bytesRead = _readStream.Read(_inBuff, 0, _inBuffSize);
if (_bytesRead >= 1)
return _inBuff[_readIdx++];
if (_bThrowErrorOnEof)
throw new System.Exception("End Of Input");
_inBuff[_bytesRead++] = 0;
}
return _inBuff[_readIdx++];
}
public void WriteToBuffer(string s)
{
foreach (var b in System.Text.Encoding.ASCII.GetBytes(s))
{
if (_writeIdx == _outBuffSize)
Flush();
_outBuff[_writeIdx++] = b;
}
}
public void WriteLineToBuffer(string s)
{
WriteToBuffer(s);
if (_writeIdx == _outBuffSize)
Flush();
_outBuff[_writeIdx++] = 10;
}
public void WriteToBuffer(int c)
{
byte[] temp = new byte[10];
int tempidx = 0;
if (c < 0)
{
if (_writeIdx == _outBuffSize)
Flush();
_outBuff[_writeIdx++] = (byte)'-';
c = -c;
}
do
{
temp[tempidx++] = (byte)((c % 10) + '0');
c /= 10;
} while (c > 0);
for (int i = tempidx - 1; i >= 0; i--)
{
if (_writeIdx == _outBuffSize)
Flush();
_outBuff[_writeIdx++] = temp[i];
}
}
public void WriteLineToBuffer(int c)
{
WriteToBuffer(c);
if (_writeIdx == _outBuffSize)
Flush();
_outBuff[_writeIdx++] = 10;
}
private void Flush()
{
_writeStream.Write(_outBuff, 0, _writeIdx);
_writeStream.Flush();
_writeIdx = 0;
}
public void Dispose()
{
Flush();
_writeStream.Close();
_readStream.Close();
}
}
#endregion Input Output Helper
}
As far as I can see, you have a well known Circle Division problem; see also A000124 sequence:
number of pieces after n cuts are (n * n + n + 2) / 2
That's why we can put O(1) time and space complexity
Code:
private static int Solution(int n) => (int)(((long)n * n + n + 2) / 2);
Here I've put (long) n in case n * n exceeds int.MaxValue, when (n * n + n + 2) / 2 doesn't.
Edit: I've implemented int Solution(int n) method which is based on current code int Recursion(int x) signature; but if there're tests for large n we are going to have integer overflow.
In this case
private static long Solution(long n) =>
1 + (n % 2 == 0 ? n / 2 * (n + 1) : (n + 1) / 2 * n);
In case of arbitrary n we have to use BigInteger:
using System.Numerics;
...
private static BigInteger Solution(BigInteger n) =>
1 + (n * n + n) / 2;

why a list<long[]> variable automatically changes with another variable?

I have two variables: long[] nextState and List<long[]> TabuList.
I use this code to add items to TabuList:
TabuList.add(nextState);
or this:
TabuList.insert(Index, nexState);
but the problem is that after either of these operations, all of TabuList’s items automatically convert to the current value of nextState.
my complete code is:
class TabuSearch
{
private long[] current { get; set; }
private double Delta;
private Random rnd = new Random();
int foundLists = 0;
public TabuSearch()
{
current = new long[Convert.ToInt32(num_list1)];
}
public long[] TabuMOSA3Objectives(long[] c)
{
assign(current, c);
long[] nextState = new long[Convert.ToInt32(num_list1)];
List<long[]> TabuList = new List<long[]>();
double proba;
double alpha = 0.969;
double temperature = 500.0;
double epsilon = 0.0001;
short domination_st;
int iter = 0;
while (temperature > epsilon)
{
iter++;
Delta = 1;
assign(nextState, GenerateNextState(primaryList, current));
domination_st = CheckDomination3Objective(nextState, current);
try { var tmp = TabuList.Find(x => x == nextState); if (tmp == null) foundLists = 0; else foundLists = tmp.Count(); }
catch { }
if (foundLists == 0)
{
if (domination_st > 0)
{
assign(current, nextState);
}
else // domination_st < 0
{
proba = rnd.NextDouble();
if (proba < 1 / (1 + Math.Exp(Delta * temperature)))
{
assign(current, nextState);
}
else
{
if (TabuList.Count == 10)
TabuList.RemoveAt(0);
assign(nextState, TabuList);
}
}
}
//cooling proces on every iteration
temperature *= alpha;
}
return current;
}
}
static void assign(long[] c, long[] n)
{
for (int i = 0; i < c.Length; i++)
c[i] = n[i];
}
static void assign(long[] item, List<long[]> list)
{
list.Add(item);
}

Fraction Calculator error

The problem is that the expression 1/4 + 2 1/2 displays the result of 2 3/8 instead of 2 3/4. The same thing goes to the expression 1/8 + 2 1/2, the result displays 2 3/8 as well. Please help me with this. Thanks!
class FractionDemo
{
static void Main(string[] args)
{
Fraction firstfraction = new Fraction();
Fraction secondfraction = new Fraction();
firstfraction.Numerator = 1;
firstfraction.Denominator = 4;
secondfraction.Numerator = 1;
secondfraction.Denominator = 8;
secondfraction.WholeNumber = 2;
Fraction add = new Fraction();
add = firstfraction + secondfraction;
Console.Write("\n {0}/{1}", firstfraction.Numerator, firstfraction.Denominator);
Console.WriteLine(" + {0}/{1} = {2}/{3}", secondfraction.Numerator, secondfraction.Denominator, add.Numerator, add.Denominator);
Console.Write("\n {0}/{1}", firstfraction.Numerator, firstfraction.Denominator);
Console.WriteLine(" + {0} {1}/{2} = {3} {4}/{5}", secondfraction.WholeNumber, secondfraction.Numerator,secondfraction.WholeNumber, add.WholeNumber, add.Numerator, add.Denominator);
Console.Write("\n {0}/{1}", firstfraction.Numerator, secondfraction.Denominator);
Console.WriteLine(" + {0} {1}/{2} = {3} {4}/{5}", secondfraction.WholeNumber, secondfraction.Numerator, secondfraction.WholeNumber, add.WholeNumber, add.Numerator, add.Denominator);
Console.ReadLine();
}
public class Fraction
{
private int wholenumber;
private int numerator;
private int denominator;
public int WholeNumber
{
get
{
return wholenumber;
}
set
{
wholenumber = value;
}
}
public int Numerator
{
get
{
return numerator;
}
set
{
numerator = value;
}
}
public int Denominator
{
get
{
return denominator;
}
set
{
denominator = value;
if (denominator > 0)
{
denominator = value;
}
else
{
denominator = 1;
}
}
}
public Fraction(int wholenumber, int numerator, int denominator)
: this(numerator, denominator)
{
WholeNumber = wholenumber;
}
public Fraction(int numerator, int denominator)
{
WholeNumber = 0;
Numerator = numerator;
Denominator = denominator;
}
public Fraction()
{
WholeNumber = 0;
Numerator = 0;
Denominator = 1;
}
public int gcd()
{
int x = Numerator;
int y = Denominator;
int m;
if (x > y)
m = y;
else
m = x;
for (int i = m; i >= 1; i--)
{
if (x % i == 0 && y % i == 0)
{
return i;
}
}
return 1;
}
public void Reduce()
{
int gcdNum = gcd();
if (gcdNum != 0)
{
Numerator = Numerator / gcdNum;
Denominator = Denominator / gcdNum;
}
if (Denominator < 0)
{
Denominator = Denominator * -1;
Numerator = Numerator * -1;
}
convertFraction();
}
public void convertFraction()
{
WholeNumber = Numerator / Denominator;
Numerator = Numerator % Denominator;
}
public static Fraction operator +(Fraction firstfraction, Fraction secondfraction)
{
int firstNum = (firstfraction.WholeNumber * firstfraction.Denominator) + firstfraction.Numerator;
int secondNum = (secondfraction.WholeNumber * secondfraction.Denominator) + secondfraction.Numerator;
Fraction Result = new Fraction();
Result.Numerator = firstNum * secondfraction.Denominator + firstfraction.Denominator * secondNum;
Result.Denominator = firstfraction.Denominator * secondfraction.Denominator;
Result.Reduce();
return Result;
}
}
}
Your Fraction is correct. For first example you should use:
firstfraction.Numerator = 1;
firstfraction.Denominator = 4;
secondfraction.Numerator = 1;
secondfraction.Denominator = 2;
secondfraction.WholeNumber = 2;
Then you'll get 2 3/4

Returning Nth Fibonacci number the sequence?

I have a question on my homework for class and I need to know how to return nth number of Fibonacci sequence using iteration (no recursion allowed).
I need some tips on how to do this so I can better understand what I am doing wrong. I output to the console in my program.cs, hence it being absent in the code below.
// Q1)
//
// Return the Nth Fibonacci number in the sequence
//
// Input: uint n (which number to get)
// Output: The nth fibonacci number
//
public static UInt64 GetNthFibonacciNumber(uint n)
{
// Return the nth fibonacci number based on n.
if (n == 0 || n == 1)
{
return 1;
}
// The basic Fibonacci sequence is
// 1, 1, 2, 3, 5, 8, 13, 21, 34...
// f(0) = 1
// f(1) = 1
// f(n) = f(n-1) + f(n-2)
///////////////
//my code is below this comment
uint a = 0;
uint b = 1;
for (uint i = 0; i < n; i++)
{
n = b + a;
a = b;
b = n;
}
return n;
:)
static ulong Fib(int n)
{
double sqrt5 = Math.Sqrt(5);
double p1 = (1 + sqrt5) / 2;
double p2 = -1 * (p1 - 1);
double n1 = Math.Pow(p1, n + 1);
double n2 = Math.Pow(p2, n + 1);
return (ulong)((n1 - n2) / sqrt5);
}
Just for a little fun you could do it with an infinite Fibonacci list and some IEnumerable extensions
public IEnumerable<int> Fibonacci(){
var current = 1;
var b = 0;
while(true){
var next = current + b;
yield return next;
b = current;
current = next;
}
}
public T Nth<T>(this IEnumerable<T> seq, int n){
return seq.Skip.(n-1).First();
}
Getting the nth number would then be
Fibonacci().Nth(n);
public static int GetNthFibonacci(int n)
{
var previous = -1;
var current = 1;
int index = 1;
int element = 0;
while (index++ <= n)
{
element = previous + current;
previous = current;
current = element;
}
return element;
}
I think this should do the trick:
uint a = 0;
uint b = 1;
uint c = 1;
for (uint i = 0; i < n; i++)
{
c = b + a;
a = b;
b = c;
}
return c;
public IEnumerable<BigInteger> FibonacciBig(int maxn)
{
BigInteger Fn=1;
BigInteger Fn_1=1;
BigInteger Fn_2=1;
yield return Fn;
yield return Fn;
for (int i = 3; i < maxn; i++)
{
Fn = Fn_1 + Fn_2;
yield return Fn;
Fn_2 = Fn_1;
Fn_1 = Fn;
}
}
you can get the n-th Number by
FibonacciBig(100000).Skip(n).First();
This is the solution for your homework, you should start from 3 because you already have numbers for f1 and f2 (first two numbers). Please note that there is no point in getting 0th Fibonacci number.
public static UInt64 GetNthFibonacciNumber(uint n)
{
// Return the nth fibonacci number based on n.
if (n == 1 || n == 2)
{
return 1;
}
uint a = 1;
uint b = 1;
uint c;
for (uint i = 3; i <= n; i++)
{
c = b + a;
a = b;
b = c;
}
return c;
}
public static UInt64 GetNthFibonacciNumber(uint n)
{
if (n == 0 || n == 1)
{
return 1;
}
UInt64 a = 1, b = 1;
uint i = 2;
while (i <= n)
{
if (a > b) b += a;
else a += b;
++i;
}
return (a > b) ? a : b;
}
public static List<int> PrintFibonacci(int number)
{
List<int> result = new List<int>();
if (number == 0)
{
result.Add(0);
return result;
}
else if (number == 1)
{
result.Add(0);
return result;
}
else if (number == 2)
{
result.AddRange(new List<int>() { 0, 1 });
return result;
}
else
{
//if we got thus far,we should have f1,f2 and f3 as fibonacci numbers
int f1 = 0,
f2 = 1;
result.AddRange(new List<int>() { f1, f2 });
for (int i = 2; i < number; i++)
{
result.Add(result[i - 1] + result[i - 2]);
}
}
return result;
}
Only 2 variables are needed (declaring one in a for loop counts too).
public int NthFib(int n)
{
int curFib = 0;
int nextFib = 1;
while (--n > 0)
{
nextFib += curFib;
curFib = nextFib - curFib;
}
return curFib;
}
If you want to see the sequence to n change it to:
public IEnumerable<int> NthFib(int n)
{
int curFib = 0;
int nextFib = 1;
while (n-- > 0)
{
yield return curFib;
nextFib += curFib;
curFib = nextFib - curFib;
}
}

permutation in c#

Is it possible to generate all permutations of a collection in c#?
char[] inputSet = { 'A','B','C' };
Permutations<char> permutations = new Permutations<char>(inputSet);
foreach (IList<char> p in permutations)
{
Console.WriteLine(String.Format("{{{0} {1} {2}}}", p[0], p[1], p[2]));
}
I've already faced the problem and I wrote these simple methods:
public static IList<T[]> GeneratePermutations<T>(T[] objs, long? limit)
{
var result = new List<T[]>();
long n = Factorial(objs.Length);
n = (!limit.HasValue || limit.Value > n) ? n : (limit.Value);
for (long k = 0; k < n; k++)
{
T[] kperm = GenerateKthPermutation<T>(k, objs);
result.Add(kperm);
}
return result;
}
public static T[] GenerateKthPermutation<T>(long k, T[] objs)
{
T[] permutedObjs = new T[objs.Length];
for (int i = 0; i < objs.Length; i++)
{
permutedObjs[i] = objs[i];
}
for (int j = 2; j < objs.Length + 1; j++)
{
k = k / (j - 1); // integer division cuts off the remainder
long i1 = (k % j);
long i2 = j - 1;
if (i1 != i2)
{
T tmpObj1 = permutedObjs[i1];
T tmpObj2 = permutedObjs[i2];
permutedObjs[i1] = tmpObj2;
permutedObjs[i2] = tmpObj1;
}
}
return permutedObjs;
}
public static long Factorial(int n)
{
if (n < 0) { throw new Exception("Unaccepted input for factorial"); } //error result - undefined
if (n > 256) { throw new Exception("Input too big for factorial"); } //error result - input is too big
if (n == 0) { return 1; }
// Calculate the factorial iteratively rather than recursively:
long tempResult = 1;
for (int i = 1; i <= n; i++)
{
tempResult *= i;
}
return tempResult;
}
Usage:
var perms = Utilities.GeneratePermutations<char>(new char[]{'A','B','C'}, null);
There's nothing built in.
I've found a a couple of Code Project articles here and here which might help you implement your own class.
public static void Recursion(char[] charList, int loBound, int upBound )
{
for (int i = loBound; i <= upBound; i++)
{
swap(ref charList[loBound], ref charList[i]);
if (loBound == upBound)
{
Console.Write(charList);
Console.WriteLine("");
}
Recursion(charList, loBound + 1, upBound);
swap(ref charList[loBound], ref charList[i]);
}
}
public static void swap(ref char a, ref char b)
{
if (a == b) return;
a ^= b;
b ^= a;
a ^= b;
}
public static void Main(string[] args)
{
string c = "123";
char[] c2 = c.ToCharArray();
Recursion(c2, 0, c2.Length-1);
Console.ReadKey();
}
I built these Extensions Methods for Enumerable<T>
The following Generics Methods can find Permutations as well as Combinations of an IEnumerable of any type.
Visit http://github.com/MathewSachin/Equamatics for more
using System;
using System.Collections.Generic;
using System.Linq;
namespace Equamatics
{
public static class Combinatorics
{
#region Permute
public static IEnumerable<IEnumerable<T>> Permute<T>(this IEnumerable<T> Input, int r = -1)
{
int n = Input.Count();
if (r == -1) foreach (var item in new Permutor<T>(Input).Recursion(0))
yield return item;
if (r > n) throw new ArgumentOutOfRangeException("r cannot be greater than no of elements");
foreach (var list in Input.Combinations(r))
foreach (var item in new Permutor<T>(list).Recursion(0))
yield return item;
}
class Permutor<T>
{
int ElementLevel = -1;
int[] PermutationValue;
T[] Elements;
public Permutor(IEnumerable<T> Input)
{
Elements = Input.ToArray();
PermutationValue = new int[Input.Count()];
}
public IEnumerable<IEnumerable<T>> Recursion(int k)
{
ElementLevel++;
PermutationValue[k] = ElementLevel;
if (ElementLevel == Elements.Length)
{
List<T> t = new List<T>();
foreach (int i in PermutationValue) t.Add(Elements[i - 1]);
yield return t;
}
else
for (int i = 0; i < Elements.Length; i++)
if (PermutationValue[i] == 0)
foreach (IEnumerable<T> e in Recursion(i))
yield return e;
ElementLevel--;
PermutationValue[k] = 0;
}
}
public static double P(int n, int r)
{
if (r < 0 | n < 0 | n < r) return Double.NaN;
else if (r == 0) return 1;
else if (n == r) return Factorial(n);
else
{
double Product = 1;
for (int i = n - r + 1; i <= n; ++i) Product *= i;
return Product;
}
}
#endregion
#region Combinations
public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<T> Input, int r = -1)
{
if (r == -1)
{
yield return Input;
yield break;
}
int n = Input.Count();
if (r > n) throw new ArgumentOutOfRangeException("r cannot be greater than no of elements");
int[] Indices = Enumerable.Range(0, r).ToArray();
yield return Indices.Select(k => Input.ElementAt(k));
while (true)
{
int i;
for (i = r - 1; i >= 0; --i)
if (Indices[i] != i + n - r)
break;
if (i < 0) break;
Indices[i] += 1;
for (int j = i + 1; j < r; ++j)
Indices[j] = Indices[j - 1] + 1;
yield return Indices.Select(k => Input.ElementAt(k));
}
}
public static double C(int n, int r)
{
if (r < 0 | n < 0 | n < r) return Double.NaN;
else if (n - r == 1 | r == 1) return n;
else if (n == r | r == 0) return 1;
else if (n - r > r) return (P(n, n - r) / Factorial(n - r));
else return (P(n, r) / Factorial(r));
}
#endregion
public static double Factorial(int n)
{
if (n < 0) return Double.NaN;
else if (n == 0) return 1;
else
{
double Product = 1;
for (int i = 1; i <= n; ++i) Product *= i;
return Product;
}
}
public static int Derangement(int n)
{
double x = 0;
for (int i = 2; i <= n; ++i)
{
if (i % 2 == 0) x += (1 / Factorial(i));
else x -= (1 / Factorial(i));
}
return (int)(Factorial(n) * x);
}
public static int Catalan(int n) { return (int)C(2 * n, n) / (n + 1); }
}
}
`
A simple implementation using recursion
static void Main(string[] args)
{
char[] inputSet = { 'A', 'B', 'C' };
var permutations = GetPermutations(new string(inputSet));
foreach (var p in permutations)
{
Console.WriteLine(String.Format("{{{0} {1} {2}}}", p[0], p[1], p[2]));
}
}
public static List<string> GetPermutations(string str)
{
List<string> result = new List<string>();
if (str == null)
return null;
if (str.Length == 0)
{
result.Add("");
return result;
}
char c = str.ElementAt(0);
var perms = GetPermutations(str.Substring(1));
foreach (var word in perms)
{
for (int i = 0; i <= word.Length; i++)
{
result.Add(word.Substring(0, i) + c + word.Substring(i));
}
}
return result;
}

Categories