Recursive functions multiply - c#

Can somebody please explain how this recursive function is doing? I'm struggling to understand how you can multiply numbers by using just +
static int Multiply(int x, int y)
{
if (y == 1)
{
return x;
}
else
{
return x + Multiply(x, y - 1);
}
}

Remember your basic arithmetic.
X * 2 = X + X
X * 3 = X + X + X
etc.
So I can factorise X * 3 as
X * 3 = X + (X * 2)
so in the function you have:
X * Y = X + (X * (Y-1))
Therefore
X * Y = Multiply(X, Y) = (X + Multiply(X, Y -1))
Which is essentially the recursion.

To explain with an Example...
Multiply(5, 4) will call
Multiply(5, 3) will call
Multiply(5, 2) will call
Multiply(5, 1)
For each call it will cumulatively add 5 like
5 + 5 + 5 + 5 = 20
Good Luck!

Simple. For e.g.
5 + 5 + 5 = 5 x 3
We can simply put this as Multiply(5, 3)

it is :
x + y(count)-1.
x+(x + (y count-1))
Example :
if x=3 y=4
x+((y-1))
3+(3)=> iteration1
3+(3+3) => iteration 2
3+(3+3+3) => iteration 3
Final => 3+(3+3+3)
Result => 12

Recursion is not the way to go for this requirement given stack limits. Also, evaluate your function with (1, 0) to observe the case where y is less than 1.
Here's a way to "multiply" using addition only with the aid of incrementing which is arguably +/- 1 addition:
static int Multiply(int x, int y)
{
int result = 0;
while (y > 0)
{
result += x;
y--;
}
while (y < 0)
{
result -= x;
y++;
}
return result;
}

That method is not correct because it crashes when you try to multiply by zero.
I wrote a correct method.
public static int Product(int a, int b)
{
if (a == 0 || b == 0) return 0;
else return a + Product(a,b - 1);
}

Related

Recursion stack overflow and I dont understand why

A 2 dimensional array with a size of NxN, composed of 1 and 0.
A neighbor is a 1 in the north / south / west / east of the index
Recursively find how many neighbors an index in the array has (neighbors that touch other neighbors are also included).
For the array I built I should get 6, but instead I get a stack overflow exception, and I don't get why.
Below is my 7x7 array, that for index 2, 5 should return the value of 6.
Example:
static void Main(string[] args)
{
int[,] arr = {
{ 0,0,0,1,0,0,0 },
{ 1,0,0,1,1,0,0 },
{ 0,0,0,0,1,1,0 },
{ 0,0,0,0,1,0,0 },
{ 0,0,0,0,0,0,0 },
{ 0,1,1,1,1,0,0 },
{ 1,0,0,1,0,0,0 },
};
Console.WriteLine(Recursive(arr,2,5));
Console.ReadLine();
}
Routine under test:
static public int Recursive(int[,] arr, int x, int y)
{
if (x < 0 || y < 0 || x > arr.GetLength(0) || y > arr.GetLength(1))
{
return 0;
}
// check if a 1 has neighbors
if (arr[x, y] == 1)
{
return 1 +
Recursive(arr, x - 1, y) +
Recursive(arr, x + 1, y) +
Recursive(arr, x, y - 1) +
Recursive(arr, x, y + 1);
}
else
{
return 0;
}
}
Please, note that when you compute Recursive(arr, x, y) you call both Recursive(arr, x - 1, y) and Recursive(arr, x + 1, y):
return 1 +
Recursive(arr, x - 1, y) + // <- both x - 1
Recursive(arr, x + 1, y) + // <- and x + 1
Recursive(arr, x, y - 1) +
Recursive(arr, x, y + 1);
On the next recursive call, when you try to compute Recursive(arr, x + 1, y) it calls Recursive(arr, x + 2, y) as well as Recursive(arr, x + 1 - 1, y) which is Recursive(arr, x, y). So you have a vicious circle: to compute Recursive(arr, x, y) you must compute Recursive(arr, x, y) and stack overflow as the the result.
The way out is to break the circle and don't let read the same cell again and again (we can just set it to 0 for this):
public static int Recursive(int[,] arr, int x, int y)
{
// out of the grid
if (x < 0 || y < 0 || x > arr.GetLength(0) || y > arr.GetLength(1))
return 0;
// empty cell
if (arr[x, y] == 0)
return 0;
// do not read the cell again! From now on treat it as an empty cell
arr[x, y] = 0;
int result = 1; // the cell itself
// let have a loop instead of four calls
for (int d = 0; d < 4; ++d)
result += Recursive(arr, x + (d - 2) % 2, y + (d - 1) % 2);
// Restore after the recursive call:
// let us do not damage arr with permanently setting cells to 0
// and return arr to its original state
arr[x, y] = 1;
return result;
}
Edit: non recursive solution, where we memorize in visited all the visited cells:
public static int Memoization(int[,] arr, int x, int y) {
if (x < 0 || y < 0 || x > arr.GetLength(0) || y > arr.GetLength(1))
return 0;
if (arr[x, y] == 0)
return 0;
int result = 0;
var agenda = new Queue<(int x, int y)>();
agenda.Enqueue((x, y));
var visited = new HashSet<(int x, int y)> { (x, y) };
while (agenda.Count > 0) {
result += 1;
var (oldX, oldY) = agenda.Dequeue();
for (int d = 0; d < 4; ++d) {
int newX = oldX + (d - 2) % 2;
int newY = oldY + (d - 1) % 2;
if (newX < 0 || newY < 0 || newX > arr.GetLength(0) || newY > arr.GetLength(1))
continue;
if (arr[newX, newY] == 0)
continue;
if (visited.Add((newX, newY)))
agenda.Enqueue((newX, newY));
}
}
return result;
}
Start by considering the simplest possible input. In this case it would be an array like
int[,] arr = { {1, 1 }}
I.e. an array consisting of only two items.
Start by the first left item, this is one, so next all neighbors recursed to.
All but the right neighbor is outside the array so will be ignored.
The right item is one, so all neighbors to this will be recursed to, including the left item.
Since you end up processing the left item again, you will continue the recursion until you run out of stack space.
The point here is that you need to keep track of all the points you have already visited. For example by using a HashSet<(int x, int y)>.

Beginner - C# Fractional Calculator simplification of negative fractions

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));
}
}

Create a double value from two separate variables C#

I have two seperate variables x and y of Integer types
Lets say x = 123 and y = 456. I want to create a double using these two variables such that
result = 123.456.
How do i get this?
public static double Combine(int x, int y)
{
if (x < 0 || y < 0) throw new NotSupportedException(); // need to specify
// how it should behave when x or y is below 0
if (y == 0) return x;
var fractionMultipler = (int)Math.Floor(Math.Log10(y)) + 1;
var divider = Math.Pow(10, fractionMultipler);
return x + (y / divider);
}
Sample:
var z = Combine(30, 11123); // result 30.11123

C# return multiples of a number in a number and the remainder?

I want to find all multiples of 3 given a certain number, and also find the remainder.
So for example:
Given the number 10 : multiples of 3 = {3;6;9} + remainder = 1
Given the number 11 : multiples of 3 = {3;6;9} + remainder = 2
The algorithm I have so far (but not code) goes like this:
Check if X is a multiple of 3 - Yes - return multiples (no remainder);
No? is x-1 a multiple of 3 - Yes - return multiples (1 remainder);
No? is x-2 a multiple of 3 - Yes - return multples (2 remainder);
Is there a better way to do this, using less code?
Edit: 2 more things, I'm only looking for 3 - so this could be a const. Also any number smaller than 3: 2, 1 and 0 - I don't mind having additional logic for that.
IEnumerable<int> Foo(int n, int k)
{
int m = k;
while (m <= n)
{
yield return m;
m += k;
}
yield return m - n;
}
Integer division (/) and modulus (%) are your friends here:
var multiples = num / 3;
var remainder = num % 3;
x = given number
y = loop number
have y loop from 0 to x while increasing it by 3 every time.
if y > x then the remender is (x-(y-3))
You can use the divider / and the modulus %
http://msdn.microsoft.com/en-us/library/3b1ff23f.aspx
10 / 3 = 3
http://msdn.microsoft.com/en-us/library/0w4e0fzs.aspx
10 % 3 = 1
int number = 10;
int divisor = 3;
List<int> numbers;
// Find all the numbers by incrementing i by the divisor.
for(int i = 0; i < number; i += divisor)
{
numbers.Add(i);
}
// Find the remainder using modulus operator.
int remainder = number % divisor;
You can simply enumerate the output values
public static IEnumerable<int> GetMultiples(int value, int divisor) {
// Be care of negative and zero values...
if ((value <= 0) || (divisor <= 0))
yield break;
// Multiplications
for (int i = 1; i <= value / divisor; ++i)
yield return i * divisor;
// Finally, let's return remainder if it's non-zero
if ((value % divisor) != 0)
yield return value % divisor;
}
...
foreach(int item in GetMultiples(10, 3)) { // item will be 3, 6, 9, 1
...
}
Here's your exact output
private static void Main(string[] args)
{
int num = 10;
int divisor = 3;
if(num<divisor)
Console.Write(num + " is less than " + divisor);
Console.Write("Given the number " + num + " : multiples of " + divisor + " = {");
for (int i = divisor; i < num; i+=divisor)
Console.Write((i!=3) ? ";"+i : i.ToString());
Console.Write("} + remainder = " + num%divisor);
}
Output
Given the number 10 : multiples of 3 = {3;6;9} + remainder = 1
and checks if input is less than divisor
You can use operator modulo
%
But is very slowly if you use a lot...
This will give you the output you want:
int num;
Console.WriteLine("give me a number equal or above 3!");
int.TryParse(Console.ReadLine(),out num);
int i = 0;
List<int> nums = new List<int>();
i += 3;
while (i <= num)
{
nums.Add(i);
i += 3;
}
Console.Write("Numbers are: ");
foreach (int y in nums)
{
Console.Write(y + " , ");
}
Console.WriteLine("The remainder is " + (num - nums[nums.Count - 1]));
Wasn't LINQ built for EXACTLY for this?
IEnumerable<int> GetMultiples(int max)
{
return Enumerable.Range(1, max / 3)
.Select(p => p * 3)
.Concat((max %= 3) == 0 ? new int[0] : new int[] { max });
}

Version of Improved Noise keeps returning 0

I'm trying to implement Improved Noise in my XNA game, but my Improved Noise function keeps returning 0.0f. It's the exact same code as Ken Perlin's (http://mrl.nyu.edu/~perlin/noise/), just ported to C#.
I've tried rewriting the class and even copy and pasting directly from the site (and then porting to C#, of course), but it just won't output any value but 0.
Here's the code that I'm using:
public class PerlinNoise
{
private int[] permutations = new int[512];
private Random random;
public PerlinNoise()
: this(Environment.TickCount)
{ }
public PerlinNoise(int seed)
{
random = new Random(seed);
for (int i = 0; i < 256; i++)
{
permutations[i] = i;
}
for (int i = 0; i < 256; i++)
{
int k = random.Next(256 - i) + i;
int l = permutations[i];
permutations[i] = permutations[k];
permutations[k] = l;
permutations[i + 256] = permutations[i];
}
}
private int fastfloor(float x)
{
return x > 0 ? (int)x : (int)x - 1;
}
private float fade(float t)
{
return t * t * t * (t * (t * 6 - 15) + 10);
}
private float lerp(float t, float a, float b)
{
return a + t * (b - a);
}
public float grad(int hash, float x, float y, float z)
{
int h = hash & 15;
float u = h < 8 ? x : y,
v = h < 4 ? y : h == 12 || h == 14 ? x : z;
return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
}
public float noise3d(float x, float y, float z)
{
int X = fastfloor(x) & 0xff,
Y = fastfloor(y) & 0xff,
Z = fastfloor(z) & 0xff;
x -= fastfloor(x);
y -= fastfloor(y);
z -= fastfloor(z);
float u = fade(x);
float v = fade(y);
float w = fade(z);
int A = permutations[X] + Y, AA = permutations[A] + Z, AB = permutations[A + 1] + Z,
B = permutations[X + 1] + Y, BA = permutations[B] + Z, BB = permutations[B + 1] + Z;
return lerp(w, lerp(v, lerp(u, grad(permutations[AA], x, y, z),
grad(permutations[BA], x - 1, y, z)),
lerp(u, grad(permutations[AB], x, y - 1, z),
grad(permutations[BB], x - 1, y - 1, z))),
lerp(v, lerp(u, grad(permutations[AA + 1], x, y, z - 1),
grad(permutations[BA + 1], x - 1, y, z - 1)),
lerp(u, grad(permutations[AB + 1], x, y - 1, z - 1),
grad(permutations[BB + 1], x - 1, y - 1, z - 1))));
}
public float noise2d(float x, float y)
{
return noise3d(x, y, 0f);
}
} `
To test it, I simply did:
string[] args = Console.ReadLine().Split(' ');
PerlinNoise noise = new PerlinNoise();
int x = args[0];
int y = args[1];
int z = args[2];
Console.WriteLine(noise.noise3d(x, y, z));
And as I said above, it'll always output 0.
It seems to output 0.0f if all arguments are integral numbers. Change your testing code to
var input = Console.ReadLine()
.Split(' ')
.Select(s => float.Parse(s,
System.Globalization.CultureInfo.InvariantCulture))
.ToArray();
and try to enter, for example, 4234.2123 3123.12312 423.2434.
I'm not quite sure if it is desired behavior, but
x -= Math.Floor(x); // FIND RELATIVE X,Y,Z
y -= Math.Floor(y); // OF POINT IN CUBE.
z -= Math.Floor(z);
will always make x, y & z = 0 if they are integral numbers; fade(0.0f) is also always zero.
Multiply your inputs by (1 / MAX_VALUE) in your input case, just multiply by 1 / 256 or so, and never give it anything larger than that. When used in your game, multiply the input by (1 / MAXIMUM_CHOORD_VALUE).

Categories