Adding and subtracting vulgar fractions - c#

I'm trying to add two vulgar fractions together by finding the lowest common denominator and then adding. However, my code isn't behaving as expected, and is outputting two very high negative numbers. When I change the second fraction to 3/15 it outputs 0/0.
Here is my main program code:
class Program
{
static void Main(string[] args)
{
Fraction n = new Fraction(2, 4);
Fraction z = new Fraction(3, 12);
Fraction sum = n.Add(z, n);
int num = sum.Numerator;
int den = sum.Denominator;
Console.WriteLine("{0}/{1}", num, den);
Console.ReadKey(true);
}
}
Here is my Fraction class code:
internal class Fraction
{
public Fraction(int numerator, int denominator)
{
Numerator = numerator;
Denominator = denominator;
}
public int Numerator { get; private set; }
public int Denominator { get; private set; }
public Fraction Add(Fraction fraction2, Fraction fraction8)
{
int lcd = GetLCD(fraction8, fraction2);
int x = lcd/fraction8.Denominator;
int n = lcd/fraction2.Denominator;
int f2num = fraction2.Numerator*n;
int f8num = fraction8.Numerator*x;
int t = fraction2.Numerator;
Fraction Fraction3 = new Fraction(f2num+f8num,lcd);
return Fraction3;
}
public int GetLCD(Fraction b, Fraction c)
{
int i = b.Denominator;
int j = c.Denominator;
while (true)
{
if (i == j)
{
return i;
}
j = j + j;
i = i + i;
}
}
}

It didn't make sense to have GetLCD, Add & Subtract methods in the class. So, I moved it out of the class and made them static methods.
Your GetLCD function doesn't get LCD correctly. This will give you the required result.(I didn't bother to make the Subtract method working, you can follow the below code & make it work yourself)
PS: I didn't change all of your variable names & I would recommend you to make them as meaningful as possible. n,z,x,y,b,c are not good variable names
static void Main(string[] args)
{
Fraction n = new Fraction(2, 4);
Fraction z = new Fraction(3, 12);
Fraction sum = Add(z, n);
int x = sum.Numerator;
int y = sum.Denominator;
Console.WriteLine("{0}/{1}", x, y);
Console.ReadKey(true);
}
public static Fraction Add(Fraction fraction2, Fraction fraction8)
{
int lcd = GetLCD(fraction8, fraction2);
int multiplier = 0;
if (fraction2.Denominator < lcd)
{
multiplier = lcd / fraction2.Denominator;
fraction2.Numerator = multiplier * (fraction2.Numerator);
fraction2.Denominator = multiplier * (fraction2.Denominator);
}
else
{
multiplier = lcd / fraction8.Denominator;
fraction8.Numerator = multiplier * (fraction8.Numerator);
fraction8.Denominator = multiplier * (fraction8.Denominator);
}
Fraction Fraction3 = new Fraction(fraction2.Numerator + fraction8.Numerator, lcd);
return Fraction3;
}
public static int GetLCD(Fraction b, Fraction c)
{
int i = b.Denominator;
int j = c.Denominator;
int greater = 0;
int lesser = 0;
if (i > j)
{
greater = i; lesser = j;
}
else if (i < j)
{
greater = j; lesser = i;
}
else
{
return i;
}
for (int iterator = 1; iterator <= lesser; iterator++)
{
if ((greater * iterator) % lesser == 0)
{
return iterator * greater;
}
}
return 0;
}
internal class Fraction
{
public Fraction(int numerator, int denominator)
{
Numerator = numerator;
Denominator = denominator;
}
public int Numerator { get; set; }
public int Denominator { get; set; }
}

Personally, I think your first mistake is trying to calculate the Lowest Common Denominator instead of just finding the simplest common denominator. Finding the LCD is a great stratgety for humans working this out on paper because of pattern recognition: we can recognize LCDs quickly; but calculating the LCD, and then converting the fractions to it is significantly more steps for a computer that must perform every step every time (and is not able to recognize patterns). Plus, once you add the two fractions after transforming them to their LCD it isn't even guaranteed to be a reduced result. I'm assuming that the reduced result is required, as is usually expected with fractional arithmetic. And because it seems useful, I put the reduction directly into the constructor code:
internal class Fraction
{
public Fraction(int numerator, int denominator, bool reduce = false)
{
if (!reduce)
{
Numerator = numerator;
Denominator = denominator;
}
else
{
var GCD = GreatestCommonDivisor(numerator, denominator);
Numerator = numerator / GCD;
Denominator = denominator / GCD;
}
}
public int Numerator { get; private set; }
public int Denominator { get; private set; }
public static Fraction Add(Fraction first, Fraction second)
{
return Combine(first, second, false);
}
public static Fraction Subtract(Fraction first, Fraction second)
{
return Combine(first, second, true);
}
private static Fraction Combine(Fraction first, Fraction second, bool isSubtract)
{
var newDenominator = first.Denominator * second.Denominator;
var newFirst = first.Numerator * second.Denominator;
var newSecond = first.Denominator * second.Denominator;
if (isSubtract)
{
newSecond = newSecond * -1;
}
return new Fraction(newFirst + newSecond, newDenominator, true);
}
private static int GreatestCommonDivisor(int a, int b)
{
return b == 0 ? a : GreatestCommonDivisor(b, a % b);
}
}
Edit: stole Greatest Common Divisor code from this answer

Related

C# Object method in separate is not picking up in Main

class Rational
{
private int Denominator, Numerator;
public Rational(int numerator = 0, int denominator = 1)
{
Numerator = numerator;
Denominator = denominator;
}
public override string ToString()
{
return string.Format("Fraction: {0} / {1}", Numerator, Denominator);
}
public void IncreaseBy(Rational other)
{
Numerator = other.Numerator + Numerator;
Denominator = other.Denominator + Denominator;
}
public void DecreaseBy(Rational other)
{
Numerator = Numerator - other.Numerator;
Denominator = Denominator - other.Denominator;
}
}
This class is a simple one. It is suppose to add or substract a denominator and numerator in my main.
This is in the main, bother under the same namespace
It is suppose to ask the user for the denominator and numerator 4 times. and add them both by 3
class Program
{
static void Main(string[] args)
{
int i = 0;
Console.WriteLine("Print 4 rational numbers.\n");
do
{
Console.Write("Choose a numberator: ");
int myNumerator = Convert.ToInt32(Console.ReadLine());
Console.Write("Choose a denominator: ");
int myDenominator = Convert.ToInt32(Console.ReadLine());
Rational original = new Rational(myNumerator, myDenominator);
original.IncreaseBy(3, 3);
Console.WriteLine(original);
i++;
} while (i < 4);
}
The IncreaseBy method takes one argument, you are giving it two. You need to give it one Rational, so...
original.IncreaseBy(new Rational(3, 3));

How to shift all the whole numbers in a double to the right of the point

How to shift all the whole numbers in a double to the right of the point ?
Example i have 5342, i want the function to return 0.5342. I do not know the number of digits in the double, it's randomly generated. Should be fairly easy but i can't find any answers.
private static void Main(string[] args)
{
Console.WriteLine(MyFunction(5127));
Console.WriteLine(MyFunction(1));
Console.WriteLine(MyFunction(51283271));
Console.WriteLine(MyFunction(-512));
Console.WriteLine(MyFunction(0));
}
public static double MyFunction(double myNumber)
{
return Math.Floor(myNumber) / Math.Pow(10, Math.Abs(myNumber).ToString().Length);
}
This sounds like a pretty bizarre task, to be honest, but you could use:
while (Math.Abs(value) >= 1)
{
value = value / 10;
}
That will go into an infinite loop if the input is infinity though - and you may well lose information as you keep dividing. The latter point is important - if what you're really interested in is the decimal representation, you should consider using decimal instead of double.
You could potentially use a mixture of Math.Log and Math.Pow to do it, but the above is probably what I'd start with.
This will get you most of the way there
public static string test()
{
double dub = 5432;
string dubTxt = dub.ToString();
string text = "0.";
string test = string.Concat(text + dubTxt);
if (1 == 1)
{
MessageBox.Show(test);
return test;
}
}
You will have to develop more if statements to handle the negative numbers.
public static string test()
{
double dub = 5432;
string dubTxt = dub.ToString();
string text = "0.";
string test = string.Concat(text + dubTxt);
if (dub < 0)
{
//Do this code instead
}
}
Good Luck. Please bump me if you choose it!! I need the cred so I can do other junk. :-D
Just divide by 10 until the number is less than 1.
public static double SomeMethod(double n)
{
double d = n;
bool isNegative = (d < 0);
if(isNegative)
d = d * -1;
while(d >= 1)
d = d/10;
if(isNegative)
d = d * -1;
return d;
}
Alternative (and more precise) option:
public static double SomeMethod2(double n)
{
double d = n;
bool isNegative = (d < 0);
if(isNegative)
d = d * -1;
int numberOfDigits = ((int)d).ToString().Length;
int divisor = 1;
for(int i = 0; i < numberOfDigits; i++)
divisor = divisor * 10;
d = d/divisor;
if(isNegative)
d = d * -1;
return d;
}

Interview practice on array size i.e. I can't use arraylist, linked list, or any standard list class

I've become rusty at the brain teaser questions since I have been using fancy IDEs and C#. I have a solution for this question, but my real question is How should I deal with the array size? Assuming I can't use a list. This is written in C#.
The array size could be too small, or just be a waste of memory in its current state. I left out checks for negative coins, etc. so we could just focus on the algorithm. So I want to get rid of this line: double [] minList = new double[1000];
Here's the interview question, return the minimum number of coins that sum to a value (-1 if impossible:
public static Main(string [] args) {
double[] coins = {0.01, 0.05, 0.10, 0.25};
Console.WriteLine(MinNumberOfCoinsToSum(0.24, coins));
}
public static int MinNumberOfCoinsToSum(double sum, double [] coins)
{
double [] minList = new double[1000];
minList[0] = sum;
for (int i = 1; i < minList.Length; i++)
{
double buffer = minList[i-1];
for (int j = 0; j < coins.Length; j++)
{
if(minList[i-1] - coins[j] >= 0.0)
{
buffer = Math.Min(buffer, minList[i-1] - coins[j]);
}
}
minList[i] = Math.Min(minList[i-1], Math.Round(buffer, 2));
if (minList[i] == 0.0)
{
return i;
}
}
return -1;
}
Well Here's an answer taking in what you guys said (though it doesn't return -1 if not found):
private static int MinNumberOfCoinsToSumRecursiveDecimalVersion(decimal sum, decimal [] coins)
{
decimal buffer = sum;
for(int i = 0; i < coins.Length; i++)
{
if(sum - coins[i] >= 0)
{
buffer = Math.Min(buffer, sum - coins[i]);
}
}
if (buffer == sum && sum == 0m)
return 0;
if(buffer == sum && sum != 0m)
{
return Int32.MinValue;
}
int result = 1 + MinNumberOfCoinsToSumRecursiveDecimalVersion(Math.Min(buffer, sum), coins);
return result;
}
However my real is question is how do I deal with an array size when I do not know the size beforehand. Thanks btw for the decimal note... that would have been embarrassing at an interview.
public int MinNumberForCoinSum(int sum, decimal [] coins) {
// I assume there is a custom Util class, but it would be checking null, empty, or any other business requirement
foreach(var verification in VerificationUtil.GetArrayVerifications()) {
verification.Verify(coins);
}
if(sum < 0 ) { Throw new InvalidArgumentException()); }
return MinNumberOfCoinsToSumRecursiveDecimalVersion(sum, coins);
}
The classic solution to deal with unknown array sizes is to use an initial capacity and then start resizing when it gets full. The growth factor is typically 2. This is what most of the growing data structures in the .NET framework do (list, stack, queue etc.)
Forgive if I sound obnoxious: you are way off. The question has nothing to do with resizing arrays. Here is a solution.
public static int numberOfCoins(double[] coins, double sum){
int total = 0;
Arrays.sort(coins);
int amount = (int)(sum*100);//convert to int for precision
for(int i=coins.length-1; i>=0 && amount > 0; i--){
int coin = (int)(100*coins[i]);//convert to int for precision
total+=amount/coin;
amount%=coin;
}
if(amount>0)
return -1;
return total;
}//numberOfCoins
Test the code with
public static void main(String... args){
double[] den = {0.01,.10,.05,.25};
System.out.println(numberOfCoins(den,1.65));
}
EDIT TO HANDLE INT CASE:
In that case I recommend overloading the function. by adding below as well
public static int numberOfCoins(int[] coins, int sum){
int total = 0;
Arrays.sort(coins);
int amount = sum;
for(int i=coins.length-1; i>=0 && amount > 0; i--){
total+=amount/coins[i];
amount%=coins[i];
}
if(amount>0)
return -1;
return total;
}//numberOfCoins

How to simplify fractions?

How to simplify a fraction in C#? For example, given 1 11/6, I need it simplified to 2 5/6.
If all you want is to turn your fraction into a mixed number whose fractional part is a proper fraction like the previous answers assumed, you only need to add numerator / denominator to the whole part of the number and set the numerator to numerator % denominator. Using loops for this is completely unnecessary.
However the term "simplify" usually refers to reducing a fraction to its lowest terms. Your example does not make clear whether you want that as well, as the example is in its lowest terms either way.
Here's a C# class that normalizes a mixed number, such that each number has exactly one representation: The fractional part is always proper and always in its lowest terms, the denominator is always positive and the sign of the whole part is always the same as the sign of the numerator.
using System;
public class MixedNumber {
public MixedNumber(int wholePart, int num, int denom)
{
WholePart = wholePart;
Numerator = num;
Denominator = denom;
Normalize();
}
public int WholePart { get; private set; }
public int Numerator { get; private set; }
public int Denominator { get; private set; }
private int GCD(int a, int b)
{
while(b != 0)
{
int t = b;
b = a % b;
a = t;
}
return a;
}
private void Reduce(int x) {
Numerator /= x;
Denominator /= x;
}
private void Normalize() {
// Add the whole part to the fraction so that we don't have to check its sign later
Numerator += WholePart * Denominator;
// Reduce the fraction to be in lowest terms
Reduce(GCD(Numerator, Denominator));
// Make it so that the denominator is always positive
Reduce(Math.Sign(Denominator));
// Turn num/denom into a proper fraction and add to wholePart appropriately
WholePart = Numerator / Denominator;
Numerator %= Denominator;
}
override public String ToString() {
return String.Format("{0} {1}/{2}", WholePart, Numerator, Denominator);
}
}
Sample usage:
csharp> new MixedNumber(1,11,6);
2 5/6
csharp> new MixedNumber(1,10,6);
2 2/3
csharp> new MixedNumber(-2,10,6);
0 -1/3
csharp> new MixedNumber(-1,-10,6);
-2 -2/3
int unit = 1;
int numerator = 11;
int denominator = 6;
while(numerator >= denominator)
{
numerator -= denominator;
if(unit < 0)
unit--;
else
unit++;
}
Then do whatever you like with the variables.
Note that this isn't particularly general.... in particular I doubt it's going to play well with negative numbers (edit: might be better now)
int num = 11;
int denom = 6;
int unit = 1;
while (num >= denom)
{
num -= denom;
unit++;
}
Sorry I didn't fully understand that part about keeping track of the unit values.
to simplify the fraction 6/11 you would see if you could get both to line up by the same number greater than 1 and divide.
So
2,4,6,8,10,12 no
1,3,6,9,12 no
4,8 no
5,10 no
6,12 no
7 no
8 no
9 no.
No will be the answer for all so it is already in simplest. There is no more to be done.

round up given number in c#

I want round up given numbers in c#
Ex:
round(25)=50
round(250) = 500
round(725) = 1000
round(1200) = 1500
round(7125) = 7500
round(8550) = 9000
Most of your data suggests that you want to round up to the nearest multiple of 500. This would be done by
int round(int input)
{
return (int)(500 * Math.Ceiling(input / 500.0));
}
The rounding of 25 to 50 will not work, though.
Another guess would be that you want your rounding to depend on the size of the number being rounded. The following function would round 25 to 50, 250 to 500, 0.025 to 0.05, and 2500 to 5000. Maybe you can work from there.
double round(double input)
{
double scale = Math.Floor(Math.Log10(input));
double step = 5 * Math.Pow(10, scale);
return step * Math.Ceiling(input/step);
}
Depending on what you need, this could be a nice, reusable solution.
static int RoundUpWeird(int rawNr)
{
if (rawNr < 100 && rawNr > -100)
return RoundUpToNext50(rawNr);
else
return RoundUpToNext500(rawNr);
}
static int RoundUpToNext50(int rawNr)
{
return RoundUpToNext(rawNr, 50);
}
static int RoundUpToNext500(int rawNr)
{
return RoundUpToNext(rawNr, 500);
}
static int RoundUpToNext(int rawNr, int next)
{
int result;
int remainder;
if ((remainder = rawNr % next) != 0)
{
if (rawNr >= 0)
result = RoundPositiveToNext(rawNr, next, remainder);
else
result = RoundNegativeToNext(rawNr, remainder);
if (result < rawNr)
throw new OverflowException("round(Number) > Int.MaxValue!");
return result;
}
return rawNr;
}
private static int RoundNegativeToNext(int rawNr, int remainder)
{
return rawNr - remainder;
}
private static int RoundPositiveToNext(int rawNr, int next, int remainder)
{
return rawNr + next - remainder;
}
This code should work according to the rules I can gather:
public static double Round(double val)
{
int baseNum = val <= 100 ? 100 : 1000;
double factor = 0.5;
double v = val / baseNum;
var res = Math.Ceiling(v / factor) / (1 / factor) * baseNum;
return res;
}
This should work. And also for numbers greater than those you wrote:
int round(int value)
{
int i = 1;
while (value > i)
{
i *= 10;
}
return (int)(0.05 * i * Math.Ceiling(value / (0.05 * i)));
}

Categories

Resources