Since C# doesn't support the optimization of recursive call very well (e.g tail recursion). It seems I have to switch my code style from functional programming to something I am not familiar with.
I know sometimes iterative method alternative exists to a recursion method, but usually it is quite hard to find an efficient one.
Now, in generally, I believe all recursive methods can be rewritten by using stack<T> data structure somehow.
Where can I find the tutorial or introduction or general rule to this?
e.g., what if I wanna rewrite greatest common divisor method? given m>n
int gcd(int m, int n)
{
if (n==0)
return m;
else
return gcd(n,m%n);
}
Update
Probably it is a bad example as it indeed is tail recursive. Plz just ignore the fact and consider it is a normal recursive method.
Since your example method is tail-recursive, translating it to iterative style is easy and does not even require an explicit stack.
Here are some steps that can be applied to any recursive function:
Step 1: Rewrite the method so it calls itself exactly once (your method already does this), has exactly one return statement, and uses if and goto instead of else, while, for and foreach:
int gcd(int m, int n)
{
int result;
if (n == 0)
{
result = m;
goto done;
}
result = gcd(n, m % n);
done:
return result;
}
Step 2: Replace the recursive call with the assignment of the new arguments to the parameters and a goto to the start of the method:
int gcd(int m, int n)
{
int result;
start:
if (n == 0)
{
result = m;
goto done;
}
int old_m = m;
m = n;
n = old_m % n;
goto start;
done:
return result;
}
If the method was not tail-recursive, the method would need to save its state before the goto and restore it later again.
Step 3: Remove the gotos again:
int gcd(int m, int n)
{
int result;
while (true)
{
if (n == 0)
{
result = m;
break;
}
int old_m = m;
m = n;
n = old_m % n;
}
return result;
}
Step 4: Make the method look nicer:
int gcd(int m, int n)
{
while (n != 0)
{
int old_m = m;
m = n;
n = old_m % n;
}
return m;
}
Here's an example that is not tail-recursive:
int fac(int x)
{
if (x == 0)
{
return 1;
}
return x * fac(x - 1);
}
Step 1:
int fac(int x)
{
int result;
if (x == 0)
{
result = 1;
goto end;
}
result = x * fac(x - 1);
end:
return result;
}
Step 2:
int fac(int x)
{
Stack<int> stack = new Stack<int>();
int result;
start:
if (x == 0)
{
result = 1;
goto end;
}
stack.Push(x);
x = x - 1;
goto start;
end:
if (stack.Count != 0)
{
x = stack.Pop();
result = x * result;
goto end;
}
return result;
}
Step 3:
int fac(int x)
{
Stack<int> stack = new Stack<int>();
int result;
while (true)
{
if (x == 0)
{
result = 1;
break;
}
stack.Push(x);
x = x - 1;
}
while (stack.Count != 0)
{
x = stack.Pop();
result = x * result;
}
return result;
}
Step 4:
int fac(int x)
{
Stack<int> stack = new Stack<int>();
while (x != 0)
{
stack.Push(x);
x = x - 1;
}
int result = 1;
while (stack.Count != 0)
{
x = stack.Pop();
result = x * result;
}
return result;
}
In this case you don't even need a stack:
int gcd(int m, int n) {
while(n != 0) {
int aux = m;
m = n;
n = aux % n;
}
return m;
}
In general, for every tail recursive algorithm, you don't need a stack, this is way some compiler can optimize it; but the optimization is archieved WITHOUT the use of the call stack! Tail recursion can then be archieved through a simple cycle
If we look at the simplest case, it shouldn't be too hard to generalize from there.
Suppose we have a method that looks like this:
public void CountToTenInReverse(int curNum)
{
if (curNum >= 11)
return;
CountToTen(curNum + 1);
Console.WriteLine(curNum);
}
Let's look at the call stack for CountToTenInReverse(1) to see what's actually happening. After ten calls, we have this:
[ CountToTenInReverse(10) ] <---- Top of stack
[ CountToTenInReverse(9) ]
[ CountToTenInReverse(8) ]
[ CountToTenInReverse(7) ]
[ CountToTenInReverse(6) ]
[ CountToTenInReverse(5) ]
[ CountToTenInReverse(4) ]
[ CountToTenInReverse(3) ]
[ CountToTenInReverse(2) ]
[ CountToTenInReverse(1) ] <---- Bottom of stack
After the tenth call, we'll hit the base case, and start unwinding the stack, printing numbers as we go. In words, then, our algorithm is "Push numbers onto the stack, stop when we hit 10 numbers, and then pop and print each number." So let's write that with our own stack:
public void PrintToTenInReverseNoRecursion()
{
Stack<int> myStack = new Stack<int>();
for (int i = 0; i < 10; i++)
{
myStack.Push(i);
}
for (int i = 0; i < 10; i++)
Console.WriteLine(myStack.Pop());
}
And now we've successfully converted it over. (Of course this can be done iteratively without a stack, but it was just an example.)
The same approach can be taken for other, more complicated algorithms: look at the call stack, and then imitate what it's doing with your own stack.
I know this doesn't really answer your question on how to program a recursive call with a Stack, but .NET does support optimization of tail calls. It's not as simple or straight-forward as a compiled language because of the presence of a JIT compiler and the translation of IL between different CLR language compilers.
That said, why worry about it? If it is a performance problem, rewrite the method and eliminate the recursive call altogether. Also, be aware that .NET 4.0 has made vast improvements in this area. Here is some more information on Tail Call Improvements in .NET Framework 4. You might be worrying about a non-issue.
Related
this is my first post here, I'm new to C# and I have some problems with my code.
class Program
{
static void Main(string[] args)
{
#region FindAllNumbersDivisibleBy3
Console.Write("Enter a string of numbers: ");
string Nums = Console.ReadLine();
List<long> arr = new List<long>();
for (int i = 0; i < Nums.Length; i++)
{
for(int j = Nums.Length - 1; j >= i; j--)
{
try
{
string substring = Nums.Substring(i, j);
if (Convert.ToInt64(substring) % 3 == 0)
{
arr.Add(Convert.ToInt64(substring));
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
Console.WriteLine("The following numbers are divisble by 3: ");
for (int i = 0; i < arr.Count; i++)
{
Console.WriteLine(arr[i]);
}
Console.ReadLine();
#endregion
}
}
The problem is the following: I'm given a series of numbers, probably too big and inefficient to be stored as an integer, so it's recommended to use a string, and you have to find every single number divisible by three. That could be the entire string, or some sub-strings, or just single digit numbers, etc. I get some conversion errors from the catch exception, as well as something else regarding some length parameter and I don't really understand what's the problem. It's also possible that the for loops' arguments have some errors too, but as far as I'm concerned the problems start in the try block.
Sorry if this is a very dumb question, I'm still in high school so I'm not very good at programming yet. Thank you for your help in advance.
This is still vulnerable to overflows, but it would take a very long string indeed to reach that point:
class Program
{
static void Main(string[] args)
{
Console.Write("Enter a string of numbers: ");
string Nums = Console.ReadLine();
Console.WriteLine("The following numbers are divisble by 3: ");
foreach(var result in DivisibleByThree(Nums))
{
Console.WriteLine(result);
}
Console.ReadKey(true);
}
public static IEnumerable<string> DivisibleByThree(string input)
{
for (int i = 0; i < input.Length; i++)
{
for(int j = input.Length; j > i; j--)
{
string segment = input.Substring(i, j-i);
if (SumOfDigits(segment) % 3 == 0)
{
yield return segment;
}
}
}
}
public static int SumOfDigits(string digits)
{
return digits.Where(c => char.IsDigit(c)).Select(c => c-'0').Sum();
}
}
See it work here:
https://dotnetfiddle.net/KacyAD
And since someone suggested recursion, I thought that'd be fun to try. I didn't quite get as far as I wanted (removing both loops and using recursion as the only repetition mechanism), but this does work:
public static IEnumerable<string> DivisibleByThree(string input)
{
if (input.Length > 1)
{
foreach(var item in DivisibleByThree(input.Substring(0, input.Length-1)))
{
yield return item;
}
}
while(input.Length > 0)
{
if ( SumOfDigits(input) % 3 == 0) yield return input;
input = input.Substring(1);
}
}
But that's the boring recursion. From a pure performance standpoint, it still spends a lot of time summing the same sequences of digits. There's a probably a way to use recursion to preserve prior work on each recursive call, and in that way make this run significantly faster.
That is, rather than start with a big string and check progressively smaller segments, start with the small string and with each check add the sum for the just the additional digit:
public static IEnumerable<string> DivisibleByThree(string input)
{
for(int i = input.Length - 1; i>=0; i--)
{
foreach(var item in DivisibleByThreeR(input.Substring(i, input.Length - i), 0, 0, 0)) yield return item;
}
}
public static IEnumerable<string> DivisibleByThreeR(string input, int startPos, int nextPos, int sum)
{
sum += input[nextPos] - '0';
if (sum % 3 == 0) yield return input.Substring(startPos, nextPos - startPos + 1);
if (++nextPos < input.Length)
{
foreach (var item in DivisibleByThreeR(input, startPos, nextPos, sum)) yield return item;
}
}
I'm not sure this is really any faster. I didn't benchmark or test at all beyond getting the right result. In fact, I suspect the iterators will eat up any improvements over the pure-loop version.
There's also probably a way to move the loop in the outer method also into the recursive function thereby optimize even further. But it was a nice exercise.
Here's my final fiddle if anyone else wants to play:
https://dotnetfiddle.net/dGFWNx
Here's a solution close to your code that uses BigInteger (you need .NET5+). This shall eliminate the risk of running into OverflowException. Please note that there can be duplicates in the output (you didn't say if you want to see them).
using System.Numerics;
class Program
{
static void Main(string[] args)
{
#region FindAllNumbersDivisibleBy3
Console.Write("Enter a string of numbers: ");
string Nums = Console.ReadLine();
List<BigInteger> results = new();
for (int i = 0; i < Nums.Length; i++)
{
for (int j = Nums.Length; j >= i; j--)
{
try
{
string substring = Nums.Substring(i, j - i);
if (BigInteger.TryParse(substring, out var bi) && BigInteger.ModPow(bi, 1, 3).IsZero)
{
results.Add(bi);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
Console.WriteLine("The following numbers are divisible by 3:");
for (int i = 0; i < results.Count; i++)
{
Console.WriteLine(results[i]);
}
Console.ReadLine();
#endregion
}
}
Something that will work even with numbers other than 3 and 9 would be to implement long division and only keep track of the carry remainder (added a Linq version since it seemed like an appropriate problem for it):
static bool IsDivisibleBy(string input, long divBy = 3)
{
long remainder = 0;
foreach (char c in input)
{
var num = Convert.ToInt64(c);
remainder = ((remainder * 10) + num) % divBy;
}
return remainder == 0;
}
static bool IsDivisibleByLinq(string input, long divBy = 3)
{
return input.Select(c => Convert.ToInt64(c))
.Aggregate(0L, (remainder, num) =>
((remainder * 10) + num) % divBy) == 0;
}
Is there a way to keep my Ackerman function from creating a stack over flow is does it for relatively small numbers , i.e. (4,2). This is the error
{Cannot evaluate expression because the current thread is in a stack
overflow state.}
private void Button1Click(object sender, EventArgs e)
{
var t = Ackermann(4,2);
label1.Text += string.Format(": {0}", t);
label1.Visible = true;
}
int Ackermann(uint m, uint n)
{
if (m == 0)
return (int) (n+1);
if (m > 0 && n == 0)
return Ackermann(m - 1, 1);
if (m > 0 && n > 0)
return Ackermann(m - 1, (uint)Ackermann(m, n - 1));
else
{
return -1;
}
}
The best way to avoid StackOverflowException is to not use the stack.
Let's get rid of the negative case, as it's meaningless when we call with uint. Alternatively, what follows here will also work if we make the negative test the very first thing in the method, before the other possibilities are considered:
First, we're going to need a bigger boat:
public static BigInteger Ackermann(BigInteger m, BigInteger n)
{
if (m == 0)
return n+1;
if (n == 0)
return Ackermann(m - 1, 1);
else
return Ackermann(m - 1, Ackermann(m, n - 1));
}
Now success is at least mathematically possible. Now, the n == 0 case is a simple enough tail-call. Let's eliminate that by hand. We'll use goto because it's temporary so we don't have to worry about velociraptors or Dijkstra:
public static BigInteger Ackermann(BigInteger m, BigInteger n)
{
restart:
if (m == 0)
return n+1;
if (n == 0)
{
m--;
n = 1;
goto restart;
}
else
return Ackermann(m - 1, Ackermann(m, n - 1));
}
This will already take a bit longer to blow the stack, but blow it, it will. Looking at this form though, note that m is never set by the return of a recursive call, while n sometimes is.
Extending this, we can turn this into an iterative form, while only having to deal with tracking previous values of m, and where we would return in the recursive form, we assign to n in our iterative form. Once we run out of ms waiting to be dealt with, we return the current value of n:
public static BigInteger Ackermann(BigInteger m, BigInteger n)
{
Stack<BigInteger> stack = new Stack<BigInteger>();
stack.Push(m);
while(stack.Count != 0)
{
m = stack.Pop();
if(m == 0)
n = n + 1;
else if(n == 0)
{
stack.Push(m - 1);
n = 1;
}
else
{
stack.Push(m - 1);
stack.Push(m);
--n;
}
}
return n;
}
At this point, we have answered the OP's question. This will take a long time to run, but it will return with the values tried (m = 4, n = 2). It will never throw a StackOverflowException, though it will end up running out of memory above certain values of m and n.
As a further optimisation, we can skip adding a value to the stack, only to pop it immediately after:
public static BigInteger Ackermann(BigInteger m, BigInteger n)
{
Stack<BigInteger> stack = new Stack<BigInteger>();
stack.Push(m);
while(stack.Count != 0)
{
m = stack.Pop();
skipStack:
if(m == 0)
n = n + 1;
else if(n == 0)
{
--m;
n = 1;
goto skipStack;
}
else
{
stack.Push(m - 1);
--n;
goto skipStack;
}
}
return n;
}
This doesn't help us with stack nor meaningfully with heap, but given the number of loops this thing will do with large values, every bit we can shave off is worth it.
Eliminating goto while keeping that optimisation is left as an exercise for the reader :)
Incidentally, I got too impatient in testing this, so I did a cheating form that uses known properties of the Ackerman function when m is less than 3:
public static BigInteger Ackermann(BigInteger m, BigInteger n)
{
Stack<BigInteger> stack = new Stack<BigInteger>();
stack.Push(m);
while(stack.Count != 0)
{
m = stack.Pop();
skipStack:
if(m == 0)
n = n + 1;
else if(m == 1)
n = n + 2;
else if(m == 2)
n = n * 2 + 3;
else if(n == 0)
{
--m;
n = 1;
goto skipStack;
}
else
{
stack.Push(m - 1);
--n;
goto skipStack;
}
}
return n;
}
With this version, I can get a result of true for Ackermann(4, 2) == BigInteger.Pow(2, 65536) - 3 after a little over a second (Mono, Release build, running on a Core i7). Given that the non-cheating version is consistent in returning the correct result for such values of m, I take this as reasonable evidence of the correctness of the previous version, but I'll leave it running and see.
Edit: Of course, I'm not really expecting the previous version to return in any sensible timeframe, but I thought I'd leave it running anyway and see how its memory use went. After 6 hours it's sitting nicely under 40MiB. I'm pretty happy that while clearly impractical, it would indeed return if given enough time on a real machine.
Edit: Apparently it's being argued that Stack<T> hitting its internal limit of 2³¹ items counts as a sort of "stack overflow", too. We can deal with that also if we must:
public class OverflowlessStack <T>
{
internal sealed class SinglyLinkedNode
{
//Larger the better, but we want to be low enough
//to demonstrate the case where we overflow a node
//and hence create another.
private const int ArraySize = 2048;
T [] _array;
int _size;
public SinglyLinkedNode Next;
public SinglyLinkedNode()
{
_array = new T[ArraySize];
}
public bool IsEmpty{ get{return _size == 0;} }
public SinglyLinkedNode Push(T item)
{
if(_size == ArraySize - 1)
{
SinglyLinkedNode n = new SinglyLinkedNode();
n.Next = this;
n.Push(item);
return n;
}
_array [_size++] = item;
return this;
}
public T Pop()
{
return _array[--_size];
}
}
private SinglyLinkedNode _head = new SinglyLinkedNode();
public T Pop ()
{
T ret = _head.Pop();
if(_head.IsEmpty && _head.Next != null)
_head = _head.Next;
return ret;
}
public void Push (T item)
{
_head = _head.Push(item);
}
public bool IsEmpty
{
get { return _head.Next == null && _head.IsEmpty; }
}
}
public static BigInteger Ackermann(BigInteger m, BigInteger n)
{
var stack = new OverflowlessStack<BigInteger>();
stack.Push(m);
while(!stack.IsEmpty)
{
m = stack.Pop();
skipStack:
if(m == 0)
n = n + 1;
else if(m == 1)
n = n + 2;
else if(m == 2)
n = n * 2 + 3;
else if(n == 0)
{
--m;
n = 1;
goto skipStack;
}
else
{
stack.Push(m - 1);
--n;
goto skipStack;
}
}
return n;
}
Again, calling Ackermann(4, 2) returns:
Which is the correct result. The stack structure used will never throw, so the only limit remaining is the heap (and time of course, with large enough inputs you'll have to use "universe lifetime" as a unit of measurement...).
Since the way it's used is analogous to the tape of a Turing machine, we're reminded of the thesis that any calculable function can be calculated on a Turing machine of sufficient size.
Use memoization. Something like:
private static Dictionary<int, int> a = new Dictionary<int, int>();
private static int Pack(int m, int n) {
return m * 1000 + n;
}
private static int Ackermann(int m, int n) {
int x;
if (!a.TryGetValue(Pack(m, n), out x)) {
if (m == 0) {
x = n + 1;
} else if (m > 0 && n == 0) {
x = Ackermann(m - 1, 1);
} else if (m > 0 && n > 0) {
x = Ackermann(m - 1, Ackermann(m, n - 1));
} else {
x = -1;
}
a[Pack(m, n)] = x;
}
return x;
}
However, this example only shows the concept, it will still not give the correct result for Ackermann(4, 2), as an int is way too small to hold the result. You would need an integer with 65536 bits instead of 32 for that.
Is there a more efficient method of converting a string integer to int rather than using Convert.ToInt32() in c#?
I have a program which converts a lot of strings to integers. These values are read from a text file in string format.
No, probably not, at least not by far. I tried this quick and dirty benchmark:
private static int toint(string s) {
int res = 0;
foreach (var c in s) {
res = 10*res + (c - '0');
}
return res;
}
static void Main() {
var s = DateTime.Now;
for (int i = 0 ; i != 10000000 ; i++) {
if (Convert.ToInt32("112345678") == 0) break;
}
var m = DateTime.Now;
for (int i = 0; i != 10000000; i++) {
if (toint("112345678") == 0) break;
}
Console.WriteLine("{0} {1}", DateTime.Now-m, m-s);
}
My toint method skips all sorts of validations, and gets a result that is only a 40% improvement on Convert.ToInt32: 1.14 s vs. 1.86 s.
Adding just a basic validation to the dirty toint eliminates its advantage almost entirely: this method
private static int toint(string s) {
int res = 0;
foreach (var c in s) {
if (Char.IsDigit(c))
res = 10*res + (c - '0');
}
return res;
}
runs in 1.62 s, or a 13% improvement while staying fundamentally incorrect.
Using this method:
private static int Parse(string s)
{
int value = 0;
for (var i = 0; i < s.Length; i++)
{
value = value*10 + (s[i] - '0');
}
return value;
}
I get 750 ms instead of 18+ seconds with int.Parse for 100M conversions.
I won't recommend it unless this is your real bottleneck and you don't care about any form of validation.
If you’re reading your integers from a Stream, then you could optimize by avoiding the overhead of initializing a string.
For example, assuming that your numbers will always be non-negative and terminated by a , character, you could use:
int num = stream.ReadByte() - '0';
byte next = (byte)stream.ReadByte();
while (next != ',')
{
num = num * 10 + next - '0';
next = (byte)stream.ReadByte();
}
This page benchmarks 4 techniques. The fastest method was as Romain wrote about above:
y = 0;
for (int i = 0; i < s[x].Length; i++)
y = y * 10 + (s[x][i] - '0');
Here are some other methods that were tested that proved almost 10x slower (where "s" is the array of strings the author used for conversion) :
int.Parse(s[x]);
Int32.TryParse(s[x], out y);
Convert.ToInt32(s[x]);
Convert.ToInt32() uses Int32.Parse() (with a little validation thrown in). Int32.Parse() in turn uses Number.Parse().
The actual implementation is about as fast as you could get unless you had significant knowledge regarding the input value (e.g. your input is always a fixed number of digits, it is never hex, has a certain precision, it is always unsigned, etc.)
private unsafe static Boolean NumberToInt64(ref NumberBuffer number, ref Int64 value) {
Int32 i = number.scale;
if (i > Int64Precision || i < number.precision) {
return false;
}
char* p = number.digits;
BCLDebug.Assert(p != null, "");
Int64 n = 0;
while (--i >= 0) {
if ((UInt64)n > (0x7FFFFFFFFFFFFFFF / 10)) {
return false;
}
n *= 10;
if (*p != '\0') {
n += (Int32)(*p++ - '0');
}
}
if (number.sign) {
n = -n;
if (n > 0) {
return false;
}
}
else {
if (n < 0) {
return false;
}
}
value = n;
return true;
}
I use the Convert.ToXYZ() methods extensively in my own base framework and in profiler sessions they represent a trivial amount of overhead even when called hundreds of times in a single operation (such as deserializing a complex object tree).
I have encountered places where it is possible to improve upon the performance of the BCL with a specialized algorithm, but this probably isn't one of them.
The method should work like Math.Max(), but take 3 or more int parameters.
You could use Enumerable.Max:
new [] { 1, 2, 3 }.Max();
Well, you can just call it twice:
int max3 = Math.Max(x, Math.Max(y, z));
If you find yourself doing this a lot, you could always write your own helper method... I would be happy enough seeing this in my code base once, but not regularly.
(Note that this is likely to be more efficient than Andrew's LINQ-based answer - but obviously the more elements you have the more appealing the LINQ approach is.)
EDIT: A "best of both worlds" approach might be to have a custom set of methods either way:
public static class MoreMath
{
// This method only exists for consistency, so you can *always* call
// MoreMath.Max instead of alternating between MoreMath.Max and Math.Max
// depending on your argument count.
public static int Max(int x, int y)
{
return Math.Max(x, y);
}
public static int Max(int x, int y, int z)
{
// Or inline it as x < y ? (y < z ? z : y) : (x < z ? z : x);
// Time it before micro-optimizing though!
return Math.Max(x, Math.Max(y, z));
}
public static int Max(int w, int x, int y, int z)
{
return Math.Max(w, Math.Max(x, Math.Max(y, z)));
}
public static int Max(params int[] values)
{
return Enumerable.Max(values);
}
}
That way you can write MoreMath.Max(1, 2, 3) or MoreMath.Max(1, 2, 3, 4) without the overhead of array creation, but still write MoreMath.Max(1, 2, 3, 4, 5, 6) for nice readable and consistent code when you don't mind the overhead.
I personally find that more readable than the explicit array creation of the LINQ approach.
Linq has a Max function.
If you have an IEnumerable<int> you can call this directly, but if you require these in separate parameters you could create a function like this:
using System.Linq;
...
static int Max(params int[] numbers)
{
return numbers.Max();
}
Then you could call it like this: max(1, 6, 2), it allows for an arbitrary number of parameters.
As generic
public static T Min<T>(params T[] values) {
return values.Min();
}
public static T Max<T>(params T[] values) {
return values.Max();
}
off topic but here is the formula for middle value.. just in case someone is looking for it
Math.Min(Math.Min(Math.Max(x,y), Math.Max(y,z)), Math.Max(x,z));
Let's assume that You have a List<int> intList = new List<int>{1,2,3} if You want to get a max value You could do
int maxValue = intList.Max();
Maximum element value in priceValues[] is maxPriceValues :
double[] priceValues = new double[3];
priceValues [0] = 1;
priceValues [1] = 2;
priceValues [2] = 3;
double maxPriceValues = priceValues.Max();
If, for whatever reason (e.g. Space Engineers API), System.array has no definition for Max nor do you have access to Enumerable, a solution for Max of n values is:
public int Max(int[] values) {
if(values.Length < 1) {
return 0;
}
if(values.Length < 2) {
return values[0];
}
if(values.Length < 3) {
return Math.Max(values[0], values[1]);
}
int runningMax = values[0];
for(int i=1; i<values.Length - 1; i++) {
runningMax = Math.Max(runningMax, values[i]);
}
return runningMax;
}
You could try this code:
private float GetBrightestColor(float r, float g, float b) {
if (r > g && r > b) {
return r;
} else if (g > r && g > b) {
return g;
} else if (b > r && b > g) {
return b;
}
}
This function takes an array of integers. (I completely understand #Jon Skeet's complaint about sending arrays.)
It's probably a bit overkill.
public static int GetMax(int[] array) // must be a array of ints
{
int current_greatest_value = array[0]; // initializes it
for (int i = 1; i <= array.Length; i++)
{
// compare current number against next number
if (i+1 <= array.Length-1) // prevent "index outside bounds of array" error below with array[i+1]
{
// array[i+1] exists
if (array[i] < array[i+1] || array[i] <= current_greatest_value)
{
// current val is less than next, and less than the current greatest val, so go to next iteration
continue;
}
} else
{
// array[i+1] doesn't exist, we are at the last element
if (array[i] > current_greatest_value)
{
// current iteration val is greater than current_greatest_value
current_greatest_value = array[i];
}
break; // next for loop i index will be invalid
}
// if it gets here, current val is greater than next, so for now assign that value to greatest_value
current_greatest_value = array[i];
}
return current_greatest_value;
}
Then call the function :
int highest_val = GetMax (new[] { 1,6,2,72727275,2323});
// highest_val = 72727275
You can use if and else if method for three values but it would be much easier if you call call twice Math.Max method like this
Console.WriteLine("Largest of three: " + Math.Max(num1, Math.Max(num2, num3)));
Console.WriteLine("Lowest of three: " + Math.Min(num1, Math.Min(num2, num3)));
If you don't want to repeatedly calling the Max function, can do like this
new List<int>() { A, B, C, D, X, Y, Z }.Max()
in case you need sorting as well:
var side = new double[] {5,3,4}
Array.Sort(side);
//side[2] is a maximum
as an another variant:
T[] GetMax<T>(int number, List<T> source, T minVal)
{
T[] results = new T[number];
for (int i = 0; i < number; i++)
{
results[i] = minVal;
}
var curMin = minVal;
foreach (var e in source)
{
int resComp = Comparer.DefaultInvariant.Compare(curMin, e);
if (resComp < 0)
{
int minIndex = Array.IndexOf(results, curMin);
results[minIndex] = e;
curMin = results.Min();
}
}
return results;
}
var source = new int[] { 5, 5, 1, 2, 4, 3 }.ToList();
var result = GetMax(3, source, int.MinValue);
I am trying to write a method to calculate the sum of the odd numbers in all the numbers less than the given number. so eg. CalcOdd(7) would return 5 + 3 + 1 = 9. CalcOdd (10) would return 9 + 7 + 5 + 3 + 1 = 25 etc
The method needs to take in a number, subtract 1, then recursively work backwards adding all odd numbers until it reaches 0. This is what I have so far.
private static int CalcOdd(int n)
{
if (n <= 1)
return 1;
else
if (n % 2 == 0)
n--;
return n + CalcOdd(n - 2);
}
It doesn't work so well, it includes the number passed in in the addition which is not what I want. Can anyone suggest a better way of doing this ? I would also loke to be able to port the answer to work for even numbers and add the option to include the original passed in number in the answer.
Many thanks
Why would you use recursion here? Just loop; or better, figure out the math to do it in a simple equation...
The fact is that C# doesn't make for excellent deep recursion for things like maths; the tail-call isn't really there at the moment.
Loop approach:
private static int CalcOdd(int n)
{
int sum = 0, i = 1;
while (i < n)
{
sum += i;
i += 2;
}
return sum;
}
You could do this with recursion as you say, but if you wish to do it quicker, then I can tell you that the sum of the n first odd numbers is equal to n*n.
private static int CalcOdd(int n) {
if (n<=1)
return 0;
if (n%2 == 1)
n--;
int k = n/2;
return k*k;
}
The reason this works is:
Every even number is of the form 2k, and the odd number before it is 2k-1.
Because 2*1-1 = 1, there are k odd numbers below 2k.
If n is odd, we don't want to include it, so we simply go down to the even number below it and we automatically have what we want.
Edited to fix broken code.
the sum of odd numbers less than a given number is a perfect square.
get the whole part of (n/2) to get the number of odd number less than itself.
square that and voila!
private static int CalcSumOdd(int n)
{
int i;
int.tryParse(n / 2, out i);
return i*i;
}
for even numbers its:
int i = n/2;
return i*(i+1);
correction. The above "even number sum" includes the original number "n". ie fn(12) = 42 = 2 + 4 + 6 + 8 + 10 + 12
if you want to exclude it, you should either unilaterally exclude it, or remove it with logic based on a passed in parameter.
Here is a correction,
int CalcOdd(int n)
{
n--; // <----
if (n <= 1)
return 0; // <----
else
if (n % 2 == 0)
n--;
return n + CalcOdd(n); // <----
}
i'm new here but this seems like a silly recursion exercise, given it can be done with a simple equation:
int sum(n,isEven,notFirst) {
int c=1; //skip the else
if (isEven) c=2;
if (notFirst) n-=2;
return ((n+c)*((n+c)/2))/2; }
classic discrete math sum series..
sum from 1 to 100 (odds and evens) is ((100+1)*(100/2))=5050
edit: in my code here, if you're calculating the sum of odds with n being even, or vice versa, it doesn't work, but i'm not going to put the work into that (and slop the code) right now. i'll assume your code will take care of that by the time it hits the function.. for example 7/2 isn't an int (obviously)
Why use recursion?
private Int32 CalcOdd(Int32 value)
{
Int32 r = 0;
{
while (value >= 1)
{
value--;
if (value % 2 != 0)
{
r += value;
}
}
}
return r;
}
Use a helper function. CalcOdd consists of testing n to see if it is even or odd; if it is even, return helper(n); if it is odd, return helper(n-2).
The helper function must handle three cases:
1) n is less than 1; in this case return 0.
2) n is even, in this case return helper(n-1).
3) n is odd, in this case return n+helper(n-1).
public static int CalcOdd(int n) {
// Find the highest even number. (Either n, or n-1.)
// Divide that by 2, and the answer should be the square of that number.
n = (n & 0x3FFFFFFE) >> 1;
return (int)Math.Pow(n, 2);
}
private static int CalcOdd(int n) {
n -= 1;
if ((n & 1) == 0) n--;
if (n <= 1) return 1;
return n + CalcOdd(n - 1);
}
But I would say doing loops is better and cleaner.
private static int CalcOdd(int n) {
int i, r = 1;
for (i = 3; i < n; i+=2)
r += i;
return r;
}
Since you want the option of including or excluding the first answer (and, keeping your "recursion" constraint in mind):
int calcOdd(int n, bool includeN)
{
if( !includeN )
return calcOdd(n-1, true);
if(n<=1)
return 1;
else
if(n%2 == 0)
n--;
return n+calcOdd(n-1, true);
}
The includeFirst, if passed as true, will include n in the calculations. Otherwise, the next layer down will start "including N".
Granted, as others have said, this is a horribly inefficient use of recursion, but... If you like recursion, try Haskell. It's a language built almost entirely on the concept.
int CalcOdd(int n)
{
n -= 1;
if (n <= 0)
return 0;
if (n % 2 == 0)
n--;
return n + CalcOdd(n);
}
This function is also recursive, and it has parameters which makes you able to decide wether to do even or odd number and wether you want to include the first number or not. If you are confused as to how it works, remember that bools also can be seen as 1 (true) and 0 (false)
int Calc(int n, bool even = false, bool includeFirst = false)
{
n -= !includeFirst;
if (n <= 0)
return 0;
if (n % 2 == even)
n--;
return n + Calc(n - includeFirst, even);
}
Håkon, I have ported your code to c# in VS 2008 as follows
static int Calc(int n, bool bEven, bool bIncludeFirst)
{
int iEven = Bool2Int(bEven);
int iIncludeFirst = Bool2Int(bIncludeFirst);
n -= 1 - iIncludeFirst;
if (n <= 0)
return 0;
if (n % 2 == iEven)
n--;
return n + Calc(n - iIncludeFirst, bEven, bIncludeFirst);
}
private static int Bool2Int(bool b)
{
return b ? 1 : 0;
}
It seems to be working. Now is there anything I can do to optomise ? i.e. I dont want to have to parse those bools to ints every time etc ?
I'd isolate the 'make it odd' part from the 'sum every other descending number' part: (forgive the Python)
def sumEveryTwoRecursive(n):
if n <= 0:
return 0
return n + sumEveryTwoRecursive(n - 2)
def calcOdd(n):
return sumEveryTwoRecursive(n - (2 if n % 2 else 1))
Just because there isn't one here yet, I've decided to use the LINQ hammer on this nail...
(borrowed from Nick D and Jason's pair programmed answer here)
void Main()
{
GetIterator(7, true, false).Sum().Dump();
// Returns 9
GetIterator(10, true, false).Sum().Dump();
// Returns 25
}
public IEnumerable<int> GetIterator(int n, bool isOdd, bool includeOriginal)
{
if (includeOriginal)
n++;
if (isOdd)
return GetIterator(n, 1);
else
return GetIterator(n, 0);
}
public IEnumerable<int> GetIterator(int n, int odd)
{
n--;
if (n < 0)
yield break;
if (n % 2 == odd)
yield return n;
foreach (int i in GetIterator(n, odd))
yield return i;
}
#include <iostream>
using namespace std;
int sumofodd(int num);
int main()
{
int number,res;
cin>>number;
res=sumofodd(number);
cout<<res;
return 0;
}
int sumofodd(int num)
{ if(num<1) return 0;
if (num%2==0) num--;
return num+sumofodd(num-1);
}