Recursive loop (C#) - c#

Can someone please explain it to me? I wrote a function to calculate the factorial of a number like this in C#:
public int factorial(int input)
{
if (input == 0 || input == 1)
return 1;
else
{
int temp = 1;
for (int i = 1; i <= input; i++)
temp = temp * i;
return temp;
}
}
But I found some C++ code (I don't really know any C++ btw) which finds a factorial using a recursive loop:
int factorial(int number) {
int temp;
if(number <= 1) return 1;
temp = number * factorial(number - 1);
return temp;
}
Can someone explain to me how it works? Thanks.

Well, it uses the fact that factorial(n) is n * factorial(n - 1) with a base case of n = 1.
So for example:
factorial(5) = 5 * factorial(4)
= 5 * 4 * factorial(3)
= 5 * 4 * 3 * factorial(2)
= 5 * 4 * 3 * 2 * factorial(1)
= 5 * 4 * 3 * 2 * 1
The implementation just uses this recursive definition.

Syntactically, the C++ code is identical to the same code written in C#. Don't let the language discrepancy catch you off guard! It actually looks like C to me, given that the variable is declared at the top of the function; that's not strictly necessary in either C++ or C#. I prefer to declare variables the first time I use them, combining the declaration and initialization in one single statement, but that's merely a stylistic preference that doesn't change the function of the code.
I'll try to explain this by adding comments to each line of the code snippet:
// Declare a function named "Factorial" that accepts a single integer parameter,
// and returns an integer value.
int Factorial(int number)
{
// Declare a temporary variable of type integer
int temp;
// This is a guard clause that returns from the function immediately
// if the value of the argument is less than or equal to 1.
// In that case, it simply returns a value of 1.
// (This is important to prevent the function from recursively calling itself
// forever, producing an infinite loop!)
if(number <= 1) return 1;
// Set the value of the temp variable equal to the value of the argument
// multiplied by a recursive call to the Factorial function
temp = number * Factorial(number - 1);
// Return the value of the temporary variable
return temp;
}
Recursive calls simply mean that the function calls itself from within the same function. This works because the factorial of n is equivalent to the following statement:
n! = n * (n-1)!
One great way to understand how code works is to add it to a test project, then single-step through the code using the debugger. Visual Studio has very rich support for this in C# applications. You can watch how the function recursively calls itself, watching each line execute in sequence, and even seeing the values of the variables change as operations are performed on them.

Lets analyze this line by line:
if(number <= 1) return 1;
temp = number * factorial(number - 1);
return temp;
Line 1: If the number is less than or equal to zero, we return 1. This is saying that 0! = 1 and 1! = 1
Lines 2 + 3: Otherwise we return number * factorial(number - 1). Lets look at this for 5! (here i use n! as a synonym for factorial(n) for brevity)
5!
5 * 4!
5 * 4 * 3!
5 * 4 * 3 * 2!
5 * 4 * 3 * 2 * 1!
5 * 4 * 3 * 3 * 1 // Here we don't have to expand 1! in the same way because of the condition
So the whole thing expands out. Its just using the property that
n! = n * (n - 1) * ... * 2 * 1 = n * (n - 1)!
Warning: The recursive code, as always, will suffer from a stack overflow and increased memory usage as compared to an iterative (or tail-recursive-optimized) version, so use at your own risk.

A recursive function is a function that calls itself in its body. For it be bounded, and eventually return a value, two things must happen:
It has to have a base case where it doesn't call itself again, returning a known value. This base case stops the recursion. For the factorial function, this value is 1 when the input is 0.
Its recursive applications must converge to the base case. For factorial, the recursive application calls the function with the input subtracted by 1, which will eventually converge to the base case.
A simpler way to look at this function is this (only valid for positive input):
int factorial(int input) {
return input == 0 ? 1 : input * factorial(input - 1);
}

Recursive function are function calling from the same function
eg:
Test()
{
i++;
Test();
cout<<i;
}
look at the code it will call the function again and again
Problem with recursion it will work infinitely so want to stop it by a particular condition
some change in above code now look
int i=0;
Test()
{
if(i==10) return;
i++;
Test();
cout<<i;
}
output will be 10 printed 10 times, here this line cout<<i; will execute after return

Related

multiplicative persistence - recursion?

I'm working on this:
Write a function, persistence, that takes in a positive parameter num
and returns its multiplicative persistence, which is the number of
times you must multiply the digits in num until you reach a single
digit.
For example:
persistence(39) == 3 // because 3*9 = 27, 2*7 = 14, 1*4=4
// and 4 has only one digit
persistence(999) == 4 // because 9*9*9 = 729, 7*2*9 = 126,
// 1*2*6 = 12, and finally 1*2 = 2
persistence(4) == 0 // because 4 is already a one-digit number
This is what I tried:
public static int Persistence(long n)
{
List<long> listofints = new List<long>();
while (n > 0)
{
listofints.Add(n % 10);
n /= 10;
}
listofints.Reverse();
// list of a splited number
int[] arr = new int[listofints.Count];
for (int i = 0; i < listofints.Count; i++)
{
arr[i] = (int)listofints[i];
}
//list to array
int pro = 1;
for (int i = 0; i < arr.Length; i++)
{
pro *= arr[i];
}
// multiply each number
return pro;
}
I have a problem with understanding recursion - probably there is a place to use it. Can some1 give me advice not a solution, how to deal with that?
It looks like you've got the complete function to process one iteration. Now all you need to do is add the recursion. At the end of the function call Persistence again with the result of the first iteration as the parameter.
Persistence(pro);
This will recursively call your function passing the result of each iteration as the parameter to the next iteration.
Finally, you need to add some code to determine when you should stop the recursion, so you only want to call Persistence(pro) if your condition is true. This way, when your condition becomes false you'll stop the recursion.
if (some stop condition is true)
{
Persistence(pro);
}
Let me take a stab at explaining when you should consider using a recursive method.
Example of Factorial: Factorial of n is found by multiplying 1*2*3*4*..*n.
Suppose you want to find out what the factorial of a number is. For finding the answer, you can write a foreach loop that keeys multiplying a number with the next number and the next number until it reaches 0. Once you reach 0, you are done, you'll return your result.
Instead of using loops, you can use Recursion because the process at "each" step is the same. Multiply the first number with the result of the next, result of the next is found by multiplying that next number with the result of the next and so on.
5 * (result of rest)
4 * (result of rest )
3 * (result of rest)
...
1 (factorial of 0 is 1).---> Last Statement.
In this case, if we are doing recursion, we have a terminator of the sequence, the last statement where we know for a fact that factorial of 0 = 1. So, we can write this like,
FactorialOf(5) = return 5 * FactorialOf(4) = 120 (5 * 24)
FactorialOf(4) = return 4 * FactorialOf(3) = 24 (4 * 6)
FactorialOf(3) = return 3 * FactorialOf(2) = 6 (3 * 2)
FactorialOf(2) = return 2 * FactorialOf(1) = 2 (2 * 1)
FactorialOf(1) = return 1 * FactorialOf(0) = 1 (1 * 1)
FactorialOf(0) = Known -> 1.
So, it would make sense to use the same method over and over and once we get to our terminator, we stop and start going back up the tree. Each statement that called the FactorialOf would start returning numbers until it reaches all the way to the top. At the top, we will have our answer.
Your case of Persistence
It calls for recursive method as well as you are taking the result and doing the same process on it each time.
Persistence(39) (not single) = return 1 + Persistence(3 * 9 = 27) = 3
Persistence(27) (not single) = return 1 + Persistence(2 * 7 = 14) = 2
Persistence(14) (not single) = return 1 + Persistence(1 * 4 = 4) = 1
Persistence(4) (single digit) = Known -> 0 // Terminator.
At the end of the day, if you have same process performed after each calculation / processing with a termination, you can most likely find a way to use recursion for that process.
You definitely can invoke your multiplication call recursively.
You will need initial sate (0 multiplications) and keep calling your method until you reach your stop condition. Then you return the last iteration you've got up to as your result and pass it through all the way up:
int persistence(int input, int count = 0) {} // this is how I would define the method
// and this is how I see the control flowing
var result = persistence(input: 39, count: 0) {
//write a code that derives 27 out of 39
//then keep calling persistence() again, incrementing the iteration count with each invocation
return persistence(input: 27, count: 1) {
return persistence(input: 14, count: 2) {
return persistence(input: 4, count: 3) {
return 3
}
}
}
}
the above is obviously not a real code, but I'm hoping that illustrates the point well enough for you to explore it further
Designing a simple recursive solution usually involves two steps:
- Identify the trivial base case to which you can calculate the answer easily.
- Figure out how to turn a complex case to a simpler one, in a way that quickly approaches the base case.
In your problem:
- Any single-digit number has a simple solution, which is persistence = 1.
- Multiplying all digits of a number produces a smaller number, and we know that the persistence of the bigger number is greater than the persistence of the smaller number by exactly one.
That should bring you to your solution. All you need to do is understand the above and write that in C#. There are only a few modifications that you need to make in your existing code. I won't give you a ready solution as that kinda defeats the purpose of the exercise, doesn't it. If you encounter technical problems with codifying your solution into C#, you're welcome to ask another question.
public int PerRec(int n)
{
string numS = n.ToString();
if(numS.Length == 1)
return 0;
var number = numS.ToArray().Select(x => int.Parse(x.ToString())).Aggregate((a,b) => a*b);
return PerRec(number) + 1;
}
For every recursion, you should have a stop condition(a single digit in this case).
The idea here is taking your input and convert it to string to calculate that length. If it is 1 then you return 0
Then you need to do your transformation. Take all the digits from the string representation(in this case from the char array, parse all of them, after getting the IEnumerable<int>, multiply each digit to calculate the next parameter for your recursion call.
The final result is the new recursion call + 1 (which represents the previous transformation)
You can do this step in different ways:
var number = numS.ToArray().Select(x => int.Parse(x.ToString())).Aggregate((a,b) => a*b);
convert numS into an array of char calling ToArray()
iterate over the collection and convert each char into its integer representation and save it into an array or a list
iterate over the int list multiplying all the digits to have the next number for your recursion
Hope this helps
public static int Persistence(long n)
{
if (n < 10) // handle the trivial cases - stop condition
{
return 0;
}
long pro = 1; // int may not be big enough, use long instead
while (n > 0) // simplify the problem by one level
{
pro *= n % 10;
n /= 10;
}
return 1 + Persistence(pro); // 1 = one level solved, call the same function for the rest
}
It is the classic recursion usage. You handle the basic cases, simplify the problem by one level and then use the same function again - that is the recursion.
You can rewrite the recursion into loops if you wish, you always can.

Factorial Calculations using Recursive Method call

This code is from the book: "C# 5.0 in a Nutshell" and is a sample on LinqPad. On page 39 it says:
"This method is recursive, meaning that it calls itself. Each time the method is entered,
a new int is allocated on the stack, and each time the method exits, the int is
deallocated."
Using the literal 5 yields and answer of 120 (3 yields 6)
Can someone explain how this works? I'm a VB programmer trying to learn C# and would like to understand constructs like this. I've single stepped through it many times and can't understand what happens after x == 0 and 1 is returned. Until x equals zero, the flow of execution is easy to understand. After that, the last return statement seems to be repeatedly executed (magically) until x increments back to it's original value and then returns to the point where it was originally called and produces the aforementioned (magical) numeric result.
static void Main()
{
Console.WriteLine (Factorial(5));
}
static int Factorial (int x)
{
if (x == 0) return 1;
return x * Factorial (x-1);
}
Call Factorial(3) (which returns 3 * 2)
x doesn't == 0
return 3 * Factorial(2)
Calls Factorial(2) (which returns 2 * 1)
x doesn't == 0
return 2 * Factorial(1)
Calls Factorial(1) (which returns 1 * 1)
x doesn't == 0
return 1 * Factorial(0)
Calls Factorial(0) (which returns 1)
x == 0 so return 1
An important point is that the recursive function must have a termination condition, otherwise it would call itself infinitely (until it runs out of stack space). In your example, the if (x == 0) return 1; is the termination condition. Since the function calls itself with a parameter value of one less than it was called with, eventually it will end up calling itself with 0, and that is when the recursion ends.
This brings out a problem with this code though. If you call with a negative number, it will call itself recursively with increasingly negative numbers, will never reach 0, and you'll eventually run out of stack space. How best to handle that is probably outside the scope of your question though.
The concept of recursion is not really limited to any specific language. The idea behind it that the function calls itself.
Let's consider your example: factorial function. But for now let's put implementation aside and think of it in more abstract terms. The function consists of two elements:
i) Instruction how to calculate an element 'n'.
ii) Instruction how to calculate an initial element
So how do we calculate element n for factorial? We take n and multiply it by factorial of a previous element: n-1:
n * Factorial(n-1)
And there is only one initial item: 0. That is when n == 0 the result is 1 or in other words Factorial(0) gives 1.
The algorithm you provided contains really of these two steps
if (x == 0)
return 1; // Do this when calculating Factorial of 0
else
return x * Factorial (x-1); // Do this when calculating an element n
Ok. Now what happens when we want to calculate factorial of 4? Let's break it down to specific steps.
Factorial(4) -> 4 * Factorial(4-1) -> 4 * Factorial(3)
We invoked factorial of 4. So we multiply 4 by factorial of 4-1. To get the factorial of 4-1 we again invoke factorial function:
Factorial(3) -> 3 * Factorial(3-1) -> 3 * Factorial(2)
Now we need to calculate factorial of 2.
Factorial(2) -> 2 * Factorial(2-1) -> 2 * Factorial(1)
And of 1
Factorial(1) -> 1 * Factorial(1-1) -> 1 * Factorial(0)
Note that now we have to calculate factorial of 0. But here we have a special instruction: if the argument is 0 the result has to be 1. Let's wind back our calculations:
Factorial(0) is 1. Replace the result in the calculation for factorial of 1.
Factorial(1) -> 1 * Factorial(1-1) -> 1 * 1 which is also 1
Factorial(2) -> 2 * Factorial(1) -> 2 * 1 -> 2
Factorial(3) -> 3 * Factorial(2) -> 3 * 2 -> 6
Factorial(4) -> 4 * Factorial(3) -> 4 * 3 -> 12
You mentioned following explanation:
Each time the method is entered, a new int is allocated on the stack,
and each time the method exits, the int is deallocated.
These steps when we go inside Factorial function to calculate factorial for a previous number is when a new int has to be allocated on the stack: for factorial of 4 the number 4 goes on the stack and the algorithm calculates factorial of 3, and so on.
And when we get to the very end that is to factorial of 0 we can finally start deallocating numbers. We have factorial of 0, multiply the result by 1. Factorial of 1 is returned and 1 is deallocated. Same happens for 2, 3 and finally 4.
Hope that clarified whole concept a bit. I'm aware the explanation is extensive, but, on the other hand, it's tricky to grasp it at the beginning so I preferred to be too thorough.
It's recursive because this statement here:
return x * Factorial (x-1);
returns the result of x * the result of the call to Factorial (X-1)... It's calling itself to get the answer. It breaks out of the loop when x==0 simply by returning the value of 1.
But one thing to note, to whom does x==0 return the value? The answer is most likely the loop which is accumulating the values.
The method Factorial calls itself again, starting with 5, and decrements the argument (x-1), until the passed argument x is 0.
So the first call to Factorial passes 5, the second call 4, 3, 2, 1, 0.
And the math done is: 5*4*3*2*1 = 120.
What it is doing is calling itself repeatedly.
What's effectively happening is the following.
We enter Factorial with x equal to 5 and since we're greater than 0 we multiply our 5 with the result of calling our self (Factorial) again with 5 - 1 which is 4. Inside this recursive call we find our selves doing another recursive call with 4 - 1 which is 3. We do this repeatedly until we call Factorial with 0, where it returns 1. Then that 1 returns to the recursion which multiplies it by 2, which returns to the recursion which multiplies it by 3, and then the next by 4, and then the next by 5.
In the end you return the result of 1 * 2 * 3 * 4 * 5 which is 120.
There is one call to return for each call to Factorial. These are the recursive calls unwinding after x == 0.
I think this might be easier to see if you slightly modify your code, if only temporarily:
static int Factorial (int x)
{
if (x == 0) return 1;
else
{
int y = x * Factorial (x-1);
return y;
}
}
Thanks for all the great replies to my question. I have a both a better understanding now of this piece of code works and a realization that I need to put a more in-depth study of recursion on my TO-DO list.

Calculating Lucas Sequences efficiently

I'm implementing the p+1 factorization algorithm. For that I need to calculate elements of the lucas sequence which is defined by:
(1) x_0 = 1, x_1 = a
(2) x_n+l = 2 * a * x_n - x_n-l
I implemented it (C#) recursively but it is inefficient for bigger indexes.
static BigInteger Lucas(BigInteger a, BigInteger Q, BigInteger N)
{
if (Q == 0)
return 1;
if (Q == 1)
return a;
else
return (2 * a * Lucas(a, Q - 1, N) - Lucas(a, Q - 2, N)) % N;
}
I also know
(3) x_2n = 2 * (x_n)^2 - 1
(4) x_2n+1 = 2 * x_n+1 * x_n - a
(5) x_k(n+1) = 2 * x_k * x_kn - x_k(n-1)
(3) and (4) should help to calculate bigger Qs. But I'm unsure how.
Somehow with the binary form of Q I think.
Any help is appreciated.
Here one can see how to find Nth Fibbonaci number using matrix powering with matrix
n
(1 1)
(1 0)
You may exploit this approach to calculate Lucas numbers, using matrix (for your case x_n+l = 2 * a * x_n - x_n-l)
n
(2a -1)
(1 0)
Note that Nth power of matrix could be found with log(N) matrix multiplications by means of exponentiation by squaring
(3) x_2n = 2 * (x_n)^2 - 1
(4) x_2n+1 = 2 * x_n+1 * x_n - a
Whenever you see 2n, you should think "that probably indicates an even number", and similarly 2n+1 likely means "that's an odd number".
You can modify the x indices so you have n on the left (as to make it easier to understand how this corresponds to recursive function calls), just be careful regarding rounding.
3) 2n n
=> n n/2
4) it is easy to see that if x = 2n+1, then n = floor(x/2)
and similarly n+1 = ceil(x/2)
So, for #3, we have: (in pseudo-code)
if Q is even
return 2 * (the function call with Q/2) - 1
And for #4:
else // following from above if
return 2 * (the function call with floor(Q/2))
* (the function call with ceil(Q/2)) - a
And then we can also incorporate a bit of memoization to prevent calculating the return value for the same parameters multiple times:
Keep a map of Q value to return value.
At the beginning of the function, check if Q's value exists in the map. If so, return the corresponding return value.
When returning, add Q's value and the return value to the map.
The n-th Lucas number has the value:
Exponentiation by squaring can be used to evaluate the function. For example, if n=1000000000, then n = 1000 * 1000^2 = 10 * 10^2 * 1000^2 = 10 * 10^2 * (10 * 10^2 )^2. By simplifying in this way you can greatly reduce the number of calculations.
You can get some improvements (just a factor of a million...) without resorting to really fancy math.
First let's make the data flow a little more explicit:
static BigInteger Lucas(BigInteger a, BigInteger Q, BigInteger N)
{
if (Q == 0)
{
return 1;
}
else if (Q == 1)
{
return a;
}
else
{
BigInteger q_1 = Lucas(a, Q - 1, N);
BigInteger q_2 = Lucas(a, Q - 2, N);
return (2 * a * q_1 - q_2) % N;
}
}
Unsurprisingly, this doesn't really change the performance.
However, it does make it clear that we only need two previous values to compute the next value. This lets us turn the function upside down into an iterative version:
static BigInteger IterativeLucas(BigInteger a, BigInteger Q, BigInteger N)
{
BigInteger[] acc = new BigInteger[2];
Action<BigInteger> push = (el) => {
acc[1] = acc[0];
acc[0] = el;
};
for (BigInteger i = 0; i <= Q; i++)
{
if (i == 0)
{
push(1);
}
else if (i == 1)
{
push(a);
}
else
{
BigInteger q_1 = acc[0];
BigInteger q_2 = acc[1];
push((2 * a * q_1 - q_2) % N);
}
}
return acc[0];
}
There might be a clearer way to write this, but it works. It's also much faster. It's so much faster it's kind of impractical to measure. On my system, Lucas(4000000, 47, 4000000) took about 30 minutes, and IterativeLucas(4000000, 47, 4000000) took about 2 milliseconds. I wanted to compare 48, but I didn't have the patience.
You can squeeze a little more out (maybe a factor of two?) using these properties of modular arithmetic:
(a + b) % n = (a%n + b%n) % n
(a * b) % n = ((a%n) * (b%n)) % n
If you apply these, you'll find that a%N occurs a few times so you can win by precomputing it once before the loop. This is particularly helpful when a is a lot bigger than N; I'm not sure if that happens in your application.
There are probably some clever mathematical techniques that would blow this solution out of the water, but I think it's interesting that such an improvement can be achieved just by shuffling a little code around.

Fast algorithm for pandigital check

I'm working on a project for which I need a very fast algorithm for checking whether a supplied number is pandigital. Though the logic seems sound, I'm not particularly happy with performance of the methods described below.
I can check up to one million 9-digit numbers in about 520ms, 600ms and 1600ms respectively. I'm working on a low-latency application and in production I'll have a dataset of about 9 or 9.5 billion 7- to 9-digit numbers that I'll need to check.
I have three candidiates right now (well, really two) that use the following logic:
Method 1: I take an input N, split into into a byte array of its constituent digits, sort it using an Array.Sort function and iterate over the array using a for loop checking for element vs counter consistency:
byte[] Digits = SplitDigits(N);
int len = NumberLength(N);
Array.Sort(Digits);
for (int i = 0; i <= len - 1; i++)
{
if (i + 1 != Digits[i])
return false;
}
Method 2: This method is based on a bit of dubious logic, but I split the input N into a byte array of constituent digits and then make the following test:
if (N * (N + 1) * 0.5 == DigitSum(N) && Factorial(len) == DigitProduct(N))
return true;
Method 3: I dislike this method, so not a real candidate but I cast the int to a string and then use String.Contains to determine if the required string is pandigital.
The second and third method have fairly stable runtimes, though the first method bounces around a lot - it can go as high as 620ms at times.
So ideally I really like to reduce the runtime for the million 9-digit mark to under 10ms. Any thoughts?
I'm running this on a Pentium 6100 laptop at 2GHz.
PS - is the mathematical logic of the second method sound?
Method 1
Pre-compute a sorted list of the 362880 9-digit pandigital numbers. This will take only a few milliseconds. Then for each request, first check if the number is divisible by 9: It must be to be pandigital. If it is, then use a binary search to check if it is in your pre-computed list.
Method 2
Again, check if the number is divisible by 9. Then use a bit vector to track the presence of digits. Also use modular multiplication to replace the division by a multiplication.
static bool IsPandigital(int n)
{
if (n != 9 * (int)((0x1c71c71dL * n) >> 32))
return false;
int flags = 0;
while (n > 0) {
int q = (int)((0x1999999aL * n) >> 32);
flags |= 1 << (n - q * 10);
n = q;
}
return flags == 0x3fe;
}
Method 1 comes in at 15ms/1M. Method 2 comes in at 5.5ms/1M on my machine. This is C# compiled to x64 on an i7 950.
just a thought: (after the definitition of pandigital from wikipedia)
int n = 1234567890;
int Flags = 0;
int Base = 10;
while(n != 0)
{
Flags |= 1<<(n % Base); n /= Base;
}
bool bPanDigital = Flags == ((1 << Base) - 1);

How to make this function process in constant time?

I need to find the n-th term of this infinite series: 1,2,2,3,3,3,4,4,4,4...
Can you give me a constant time function for this task?
int i = 1;
while(true)
{
if(i = n)
//do things and exit the loop
i++;
}
I think this isn`t going to be a constant time function...
Edit
After reading more comments, it appears I misunderstood the question.
If you want to find the item at nth position an array in constant time, then the answer is trivial: x[n], because array access is constant time. However, if for some reason you were using some container where access time is not constant (e.g. linked list), or did not want to look up value in the array, you'd have to use the arithmetic series formulas to find the answer.
Arithmetic series tells us that the position n of the ith unique item would be
n = i * (i - 1) / 2
So we just need to solve for i. Using quadratic formula, and discarding the nonsensical negative option, we get:
i = Math.Floor( (1 + Math.Sqrt(1 + 8 * n)) / 2)
Original Response
I'm assuming you're looking for the position of the nth unique term, because otherwise the problem is trivial.
Sounds like the first occurrence of the nth unique term should follow arithmetic series. I.e. the position of nth unique term would be:
n * (n - 1) / 2
Given my understanding of the problem, this is more of a math problem than a programming one.
If the problem is:
Given an infinite series that consists of 1 copy of 1, 2 copies of 2, 3 copies of 3... n copies of n, what is the kth value in this series?
Now the first clue when approaching this problem is that there are 1 + 2 + 3... + n values before the first occurance of n + 1. Specifically there are (sum of the first n numbers) values before n+1, or (n)(n-1)/2.
Now set (n)(n-1)/2 = k. Multiply out and rationalize to n^2 - n - 2k = 0. Solve using quadratic equation, you get n = (1 + sqrt(1+8k))/2. The floor of this gives you how many full copies of n there are before, and happily, given zero based indexing, the floor gives you the value at the kth point in the array.
That means your final answer in c# is
return (int) Math.Floor((1 + Math.Sqrt(1 + 8 * k)) / 2);
Given non zero based indexing,
return (int) Math.Floor((1 + Math.Sqrt(-7 + 8 * k)) / 2);
public static long Foo(long index)
{
if (index < 0)
{
throw new IndexOutOfRangeException();
}
long nowNum = 0;
long nowIndex = 0;
do
{
nowIndex += nowNum;
nowNum++;
} while (nowIndex < index);
return nowNum;
}

Categories