Beginner - C# Fractional Calculator simplification of negative fractions - c#

I've been having troubles trying to get my fractional calculator to work. I'm trying to get the simplifying to work, it works correctly simplifiyng positive fractions, but if I were to put a negative fraction it won't simplify it, I'm not sure what I'm doing wrong and I've read over it numerous times (the Gcd and Reduce functions).
Im new to all of this, any help appreciated.
My Reduce and GCD functions:
public int gcd()
{
// assigned x and y to the answer Numerator/Denominator, as well as an
// empty integer, this is to make code more simple and easier to read
int x = answerNumerator;
int y = answerDenominator;
int m;
// check if numerator is greater than the denominator,
// make m equal to denominator if so
if (x > y)
m = y;
else
// if not, make m equal to the numerator
m = x;
// assign i to equal to m, make sure if i is greater
// than or equal to 1, then take away from it
for (int i = m; i >= 1; i--)
{
if (x % i == 0 && y % i == 0)
{
//return the value of i
return i;
}
}
return 1;
}
public void Reduce()
{
try
{
//assign an integer to the gcd value
int gcdNum = gcd();
if (gcdNum != 0)
{
answerNumerator = answerNumerator / gcdNum;
answerDenominator = answerDenominator / gcdNum;
}
if (answerDenominator < 0)
{
answerDenominator = answerDenominator * -1;
answerNumerator = answerNumerator * -1;
}
}
catch (Exception exp)
{
// display the following error message
// if the fraction cannot be reduced
throw new InvalidOperationException(
"Cannot reduce Fraction: " + exp.Message);
}
}

I think the problem is that, when you determine the GCD, you are checking that the value is >= 1 in your for loop, even though it may be negative. In order to avoid this, you should capture the absolute values of the numerator and denominator when determining the GCD.
For example, this should fix it:
public int gcd()
{
// assigned x and y to the absolute values of the answer Numerator/Denominator,
// as well as an empty integer, this is to make code more simple and easier to read
int x = Math.Abs(answerNumerator);
int y = Math.Abs(answerDenominator);
int m;
// check if numerator is greater than the denominator,
// make m equal to denominator if so
if (x > y)
m = y;
else
// if not, make m equal to the numerator
m = x;
// assign i to equal to m, make sure if i is greater
// than or equal to 1, then take away from it
for (int i = m; i >= 1; i--)
{
if (x % i == 0 && y % i == 0)
{
//return the value of i
return i;
}
}
return 1;
}

Short Answer
You need:
int x = Math.Abs(answerNumerator);
int y = Math.Abs(answerDenominator);
Running Code
Here is a running Fiddle for you: https://dotnetfiddle.net/nBzr0i
Output:
Initial: 2/4
Reduced: 1/2
---
Initial: 2/-4
Reduced: -1/2
---
Running Code:
using System;
public class Program
{
public static void Main()
{
Calc.Reduce(2,4);
Calc.Reduce(2,-4);
}
}
public static class Calc
{
public static int gcd(int answerNumerator, int answerDenominator)
{
// assigned x and y to the answer Numerator/Denominator, as well as an
// empty integer, this is to make code more simple and easier to read
int x = Math.Abs(answerNumerator);
int y = Math.Abs(answerDenominator);
int m;
// check if numerator is greater than the denominator,
// make m equal to denominator if so
if (x > y)
m = y;
else
// if not, make m equal to the numerator
m = x;
// assign i to equal to m, make sure if i is greater
// than or equal to 1, then take away from it
for (int i = m; i >= 1; i--)
{
if (x % i == 0 && y % i == 0)
{
//return the value of i
return i;
}
}
return 1;
}
public static void Reduce(int answerNumerator, int answerDenominator)
{
Console.Write("Initial: ");
WriteFraction(answerNumerator, answerDenominator);
try
{
//assign an integer to the gcd value
int gcdNum = gcd(answerNumerator, answerDenominator);
if (gcdNum != 0)
{
answerNumerator = answerNumerator / gcdNum;
answerDenominator = answerDenominator / gcdNum;
}
if (answerDenominator < 0)
{
answerDenominator = answerDenominator * -1;
answerNumerator = answerNumerator * -1;
}
}
catch (Exception exp)
{
// display the following error message
// if the fraction cannot be reduced
throw new InvalidOperationException("Cannot reduce Fraction: " + exp.Message);
}
Console.Write("Reduced: ");
WriteFraction(answerNumerator, answerDenominator);
Console.WriteLine("---");
}
public static void WriteFraction(int answerNumerator, int answerDenominator)
{
Console.WriteLine(string.Format("{0}/{1}", answerNumerator, answerDenominator));
}
}

Related

Is there a dynamic way to split 100 into different values?

I am stuck in a scenario which is complex for me to implement. Scenario is : I have rows in excel sheet which is dynamic . sometimes it could be 2, sometimes 5, sometimes 12 means any number of rows could be there. i need to assign different unique values to each available row in such a way that their sum should be equal to 100. Example : if i have 2 rows i can assign values 65 and 35 but not 50 to both as the value needs to be unique. similarly if i have 4 rows i need to assign values like 20,30, 27, 23 .Need a c# code for this.
How can i do this?
There are many ways you could generate different random numbers for each row. The way I generated the numbers was with DateTime.Now.Second and DateTime.Now.Minute. To ensure that the numbers never go over 100, you can subtract from the maximum number in the row. This is the general idea:
`
public static ulong CapAtNumber(ulong num, ulong cap) {
while(num>cap)
{
num = (num / 2) - 2;
if (num < 3)
{
num += (Convert.ToUInt64(DateTime.Now.Minute) + Convert.ToUInt64(DateTime.Now.Second) / 2);
}
}
return num;
}
This is an example of how you would find the maximum. I used the Math group to check for maximums among twoulong` numbers. The numbers are A B C D E F, and so on, and I group them into AB CD EF to find the maximum between the groups. The array size gets cut in half each time until the array size is 1. When the array size is 1, the number in the array is the maximum.
public static ulong[] FindTheMaxOfArray(ulong[] arg)
{
bool repeat = true;
ulong checknumber = 100;
while(repeat == true)
{
if (arg.Length % 2 == 0)
{
var halflist = new ulong[arg.Length / 2];
for (int z = 0; z < arg.Length / 2; z += 2)
{
halflist[z] = Math.Max(arg[z], arg[z + 1]);
if (
halflist.Length == 1)
{
repeat = true;
arg = new ulong[halflist.Length];
arg = halflist;
}
else { repeat = false;
checknumber = halflist[0]; }
}
}
else
{
var halflist = new ulong[arg.Length + 1 / 2];
for (int z = 0; z < halflist.Length; z++)
{
if (z % 2 != 0)
{
if (z != halflist.Length - 2)
{
halflist[z] = Convert.ToUInt64(Math.Max(Math.Max(arg[z], arg[z + 1]), arg[z + 2]));
}
else { halflist[z] = Convert.ToUInt64(Math.Max(arg[z], arg[z + 1])); }
}
}
if (halflist.Length == 1)
{
repeat = true;
arg = new ulong[halflist.Length];
arg = halflist;
}
else { checknumber = halflist[0];
repeat = false;
}
}
}
for(int z=0; z<arg.Length; z++)
{
if (arg[z] == checknumber)
{
arg[z] = CapAtNumber(arg[z], arg[z] - 20);
}
}
return arg;
}
if you want to ensure that there are no repeats, you can create a method to check for that. Each number in the foreach loop is checking with the numbers in the for loop. Since these are the same arrays, there has to be at least one repeat that happens naturally. Everything except this part seems to run smoothly. Here is an example
public static ulong[] Checkforrepeats(ulong[] args)
{
ulong repeatednumber = 1000;
int repeat = -1;
foreach( ulong num in args)
{
for(int z = 0; z<args.Length; z++)
{
if(z == 0)
{ repeat = -1; }
if(num ==args[z])
{
repeat += 1; //repeat was set to -1 to counter act the guaranteed repeat that will happen
}
if (repeat == 2)
{
args[z] += 2;
args[z - 1] -= 2;
}
}
}
return args;
}

Use of unassigned local variable result - different scenario [duplicate]

This question already has answers here:
Unassigned local variable mystery
(3 answers)
Closed 2 years ago.
Good Day guys! I'm trying to make solve a programming challenge named NextPrime. Its just basically will return the next number that is prime. for example the input is 8, the return value is 11 since 11 is a prime number. I made my code below and got this Use of unassigned local variable result. The code below is my source code:
public static int NextPrime(int num)
{
int half = num / 2;
int outer = num * 2;
int x, y, result;
for (x = num; x <= outer; x++)
{
for (y = 2; y <= half; y++)
{
if (x % y == 0)
{
break;
}
else if (y == half)
{
result = x;
x = outer + 1;
break;
}
}
}
return result;
}
Well, result can well appear uninitialized; the easiest example is
var demo = NextPrime(-1);
Note, that outer loop for (x = num; x <= outer; x++) is not entered and that's why result is not assigned.
What can you do? Direct approach is to implement IsPrime method:
public static bool IsPrime(int x) {
if (x <= 1)
return false;
else if (x % 2 == 0) // we have only one even prime, that is 2
return x == 2;
int n = (int)(Math.Sqrt(x) + 0.5);
for (int divisor = 3; divisor <= n; divisor += 2)
if (x % divisor == 0)
return false;
return true;
}
And then use it in NextPrime:
public static int NextPrime(int num) {
if (num <= 1)
return 2;
for (int x = num + 1 + num % 2; ; start += 2)
if (IsPrime(x))
return x;
}
Compiler Error CS0165
Use of unassigned local variable 'name'
The C# compiler doesn't allow the use of uninitialized variables. If
the compiler detects the use of a variable that might not have been
initialized, it generates compiler error CS0165. For more information,
see Fields. This error is generated when the compiler encounters a
construct that might result in the use of an unassigned variable, even
if your particular code does not. This avoids the necessity of overly
complex rules for definite assignment.
You need to be explicit about what is returned if the loops don't run. The compiler only goes so far with static analysis and doesn't probe whether loops are meaningfully setting values within
public static int NextPrime(int num)
{
int half = num / 2;
int outer = num * 2;
int result = 0; // Explicit
for (var x = num; x <= outer; x++)
for (var y = 2; y <= half; y++)
if (x % y == 0)
break;
else if (y == half)
{
result = x;
x = outer + 1;
break;
}
return result;
}

How to get integers to an array (from integer i to integer j). c#

I want to store integers(in an array or anything) that in range of int "i" and int "j".
eg:-Think, "int i = 1" and "int j = 10".I want to store integers from 1 and 10.
So that (1,2,3,4,5,6,7,8,9,10)
Because I want to answer to HackerRank "Beautiful Days at the Movies".
link below.
https://www.hackerrank.com/challenges/beautiful-days-at-the-movies/problem?isFullScreen=false
here is my code and it a garbage.
static int beautifulDays(int i, int j, int k) {
var total = 0;
for(var a = i; a <= j; a++ )
{
if (a != 0)
{
int ri = Reverse(i);
int rj = Reverse(j);
var ra = Reverse(a);
if((ra/k) % 1 == 0)
{
total++;
}
if((rj/k) % 1 == 0)
{
total++;
}
if((ri/k) % 1 == 0)
{
total++;
}
}
return total;
}
return total;
}
public static int Reverse(int inval)
{
int result = 0;
do
{
result = (result * 10) + (inval % 10);
inval = inval / 10;
}
while(inval > 0);
return result;
}
simply, can you give me the answer of HackerRank "Beautiful Days at the Movies".
link below.
https://www.hackerrank.com/challenges/beautiful-days-at-the-movies/problem?isFullScreen=false
Using Java you can easily stream a range of numbers with IntStream, then map the reverse function for each value, then filter those that fulfils the condition and count. With streams you don't need to store, you can get straight to the answer.
IntUnaryOperator reverse = (opperand) -> {
int reversed = 0;
int num = opperand;
while (num != 0) {
int digit = num % 10;
reversed = reversed * 10 + digit;
num /= 10;
}
return Math.abs(opperand - reversed);
};
return (int) IntStream.rangeClosed(i, j).map(reverse)
.filter(v -> v % k == 0).count();

Negative exponent of a number

I made this program to find the power of any number using recursion and it works, but also I need to find negative power of the number, for example, I have the base = 2 and the exponent = -3 so the result = 0.125,
what should I do?
public static int power(int x, int n )
{
if (n < 0)
{
Console.WriteLine("invalid");
return 0;
}
else if (n == 1)
{
return x;
}
else if (n == 0)
{
return 1;
}
else
{
return x * power(x, n - 1);
}
}
static void Main(string[] args)
{
Console.Write("enter the base: ");
int x = int.Parse(Console.ReadLine());
Console.Write("enter the power:");
int n = int.Parse(Console.ReadLine());
int z = power(x, n);
Console.WriteLine(z);
}
Since the result of raising a number to a negative power is just 1 divided by the number raised to the non-negative power, you can change you method like so (note that we also need to return a double type, since we're dealing with fractional values):
public static double power(int x, int n)
{
if (n < 0) return 1 / power(x, -n); // recursive call with '-n' for negative powers
if (n == 0) return 1;
if (n == 1) return x;
return x * power(x, n - 1);
}
Now it works with negative numbers:
public static void Main(string[] args)
{
Console.WriteLine(power(2, -3));
GetKeyFromUser("\nDone! Press any key to exit...");
}
Output

Smallest Multiple

I have a code here written in C# that finds the smallest multiple by all numbers from 1 to 20. However, I find it very inefficient since the execution took awhile before producing the correct answer. I would like to know what are the different ways that I can do to improve the code. Thank You.
public static void SmallestMultiple()
{
const ushort ARRAY_SIZE = 21;
ushort[] array = new ushort[ARRAY_SIZE];
ushort check = 0;
for (uint value = 1; value < uint.MaxValue; value++)
{
for (ushort j = 1; j < ARRAY_SIZE; j++)
{
array[j] = j;
if (value % array[j] == 0)
{
check++;
}
}
if (check == 20)
{
Console.WriteLine("The value is {0}", value);
}
else
{
check = 0;
}
}
}
static void Main(string[] args)
{
int[] nums = Enumerable.Range(1, 20).ToArray();
int lcm = 1;
for (int i = 0; i < nums.Length; i++)
{
lcm = LCM(lcm, nums[i]);
}
Console.WriteLine("LCM = {0}", lcm);
}
public static int LCM(int value1, int value2)
{
int a = Math.Abs(value1);
int b = Math.Abs(value2);
// perform division first to avoid potential overflow
a = checked((a / GCD(a, b)));
return checked((a * b));
}
public static int GCD(int value1, int value2)
{
int gcd = 1; // Greates Common Divisor
// throw exception if any value=0
if (value1 == 0 || value2 == 0)
{
throw new ArgumentOutOfRangeException();
}
// assign absolute values to local vars
int a = Math.Abs(value1); // local var1
int b = Math.Abs(value2); // local var2
// if numbers are equal return the first
if (a == b) { return a; }
// if var "b" is GCD return "b"
if (a > b && a % b == 0) { return b; }
// if var "a" is GCD return "a"
if (b > a && b % a == 0) { return a; }
// Euclid algorithm to find GCD (a,b):
// estimated maximum iterations:
// 5* (number of dec digits in smallest number)
while (b != 0)
{
gcd = b;
b = a % b;
a = gcd;
}
return gcd;
}
}
Source : Fast Integer Algorithms: Greatest Common Divisor and Least Common Multiple, .NET solution
Since the result must also be divisible by 19 (which is the greatest prime number) up to 20, you might only cycle through multiples of 19.
This should get to to the result about 19 times faster.
Here's the code that does this:
public static void SmallestMultiple()
{
const ushort ARRAY_SIZE = 21;
ushort[] array = new ushort[ARRAY_SIZE];
ushort check = 0;
for (uint value = 19; value < uint.MaxValue; value += 19)
{
for (ushort j = 1; j < ARRAY_SIZE; j++)
{
array[j] = j;
if (value % array[j] == 0)
{
check++;
}
}
if (check == 20)
{
Console.WriteLine("The value is {0}", value);
return;
}
else
{
check = 0;
}
}
}
On my machine, this finds the result 232792560 in a little over 2 seconds.
Update
Also, please note that the initial program did not stop when reaching a solution; I have added a return statement to make it stop.
You're just looking for the LCM of the numbers from 1 to 20:
Where the GCD can be efficiently calculated with the Euclidean algorithm.
I don't know C#, but this Python solution shouldn't be hard to translate:
def gcd(a, b):
while b != 0:
a, b = b, a % b
return a
def lcm(a, b):
return (a * b) / gcd(a, b)
numbers = range(1, 20 + 1)
print reduce(numbers, lcm)
It's pretty fast too:
>>> %timeit reduce(lcm, range(1, 20000))
1 loops, best of 3: 258 ms per loop
EDIT: v2.0 - Major speed improvement
Building on w0lf's solution. A faster solution:
public static void SmallestMultiple()
{
// this is a bit quick and dirty
// (not too difficult to change to generate primeProduct dynamically for any range)
int primeProduct = 2*3*5*7*11*13*17*19;
for (int value = primeProduct; ; value += primeProduct)
{
bool success = true;
for (int j = 11; j < 21; j++)
{
if (value % j != 0)
{
success = false;
break;
}
}
if (success)
{
Console.WriteLine("The value is {0}", value);
break;
}
}
}
You needn't check 1-10 since if something is divisible by x (e.g. 12), it is divisible by x/n (e.g. 12/2 = 6). The smallest multiple will always be a multiple of a product of all the primes involved.
Didn't benchmark C# solution, but equivalent Java solution runs in about 0.0000006 seconds.
Well I'm not sure what exactly you are trying to accomplish here but your out side for loop will run approximately 4,294,967,295 time (uint.MaxValue). So that will take some time...
If you have a way to keep from going to uint.MaxValue - like breaking your loop when you have accomplished what you need to - that will speed it up.
Also, since you are setting array[j] equal to j and then apparently never using the array again why not just do:
value % j
instead of
value % array[j]
Using also code written by W0lf (sorry but i cannot comment on your post) I would improve it (only a little) deleting the array that I think is useless..
public static void SmallestMultiple()
{
const ushort ARRAY_SIZE = 21;
ushort check = 0;
for (uint value = 1; value < uint.MaxValue; value++)
{
for (ushort j = 1; j < ARRAY_SIZE; j++)
{
if (value % j == 0)
{
check++;
}
}
if (check == 20)
{
Console.WriteLine("The value is {0}", value);
}
else
{
check = 0;
}
}
}

Categories