Iteration methods for a recursive sequence - recursion

How would the recursive sequence a(n)=-a(n-1)+n-1 be solved?
I tried forward and backward iterations but haven't been able to get a explicit solution for a(n).

Your first step should be to write out a result table
f(n)=x
n | x
-----
0 | 7
1 | -7 (-7 + 1 - 1)
2 | 8 ( 7 + 2 - 1)
3 | -6 (-8 + 3 - 1)
4 | 9 ( 6 + 4 - 1)
5 | -5 (-9 + 5 - 1)
6 | 10 ( 5 + 6 - 1)
7 | -4 (-10 + 7 - 1)
8 | 11 ( 4 + 8 - 1)
9 | -3 (-11 + 9 - 1)
You should see a pattern emerging. Each pair of solutions [(0, 1), (2, 3), (4, 5), ...] have a difference of 14, starting with (7, -7) and incrementing one every two points of n. We can generalize this:
f(0) = 7
f(n) = 7 + k - 14 * b
where k is the increment value (each 1 k per 2 n)
b is 1 when n is odd, else 0.
Now we just have to define k and b in terms of n. k shouldn't be too hard, let's see:
n | k
0 | 0
1 | 0
2 | 1
3 | 1
Does that remind you of anything? That's a floored div2.
7 + (n // 2) - 14 * b
Now for b
n | b
0 | 0
1 | 1
2 | 0
3 | 1
That looks like mod 2 to me! Modulo is the remainder of a division problem, and is a great way to check if a number is even or odd. We're looking for the plain modulo, too, since we want b==1 when n is odd and vice versa.
f(0) = 7
f(n) = 7 + (n // 2) - 14 * (n%2)
where (//) is the floor division function
(%) is the modulo function
Now we can put that all together in a function. In Go this is:
func f(n int) int {
return 7 + n/2 - 14 * (n % 2)
}
In Python it's
def f(n):
return 7 + n//2 - 14 * (n%2)
In Haskell we've got
f :: Int -> Int
f n = 7 + n `div` 2 - 14 * (n `mod` 2)
or, since Haskell implements recursion exceedingly well, simply...
f :: Int -> Int
f 0 = 7
f n = f (n-1) + n - 1

Related

Pascal - Order Of Operations

I have a simple yet irritating problem.
When I execute the code below and write 10 for 'a' I get 1010 as a result,
but I really don't know how, if i try solve this problem by myself.
In know the order of operations, but I'm kinda stuck, like I'd overlook something.
Please, give me a kick-start. I would be very grateful.
program task1 (input,output);
var
a, b, c : integer;
begin
b := 0;
c := 1;
readln(a);
while a > 0 do
begin
b := b + c * (a mod 2);
a := a div 2;
c := c * 10;
end;
writeln(b)
end.
Here is what the program calculates. The table has the assignment of b on a separate line, followed by the assignments of a and c on the same line:
a b c
10 0 1 Initialization
0 10 mod 2 = 0
5 10
10 5 mod 2 = 1; 0 + 10 * 1 = 10
2 100
10 2 mod 2 = 0
1 1000
1010 1 mod 2 = 1; 10 + 1000 * 1 = 1010
0 10000

Number Power , multiple of 3

We have a Number N and Cost C,(range N<10^18 ,C<100)
Now we have to spend maximum of C rupees to convert the number into another.
The rules of conversion of a number to another are as follows:
1)A number can be converted into other number with same number of digits and no leading zeros.
2)The cost of converting a number into other is the sum of absolute difference of corresponding digits. For example, Cost to convert 235 to 331 is 5 (since the absolute difference in corresponding digits is |3−2|+|3−3|+|1−5| , which is |1|+0+|−4|=5.
Now we need to find how many numbers that are multiple of 3, which can be made within the maximum budget(C rupees).
My approach:
i tried first to use divisibility rule of 3 and find sum of digits of N
now if cost was just sum of difference of digits then we could simply do is make the sum a multiple of 3
like 2+3+5 = 10 cost is 2
we can make it 12 which can be achieved by increasing any number 2 , 3 or 5 by 2
435,255, 237 is this correct?
also how to go about solving it in this case when c is absolute sum
Let cost(a,b) denote the cost of transforming a into b and define
N(a,c) = # { b | cost(a,b) = c }
i.e., N(a,c) is the number of numbers whose cost from a is exactly c.
Let's futher suppose _a_is divisible by 3. Then the number we are interested in is:
answer = N(a,0) + N(a,3) + N(a,6) + N(a,9) + ... + N(a,99)
If a was 1 mod 3 we would want the sum N(a,2) + N(a,5) + ... + N(a,98).
To compute N(a,c), for each digit d in a, construct a polynomial P(d) where
the coefficient of x^k is the number of digits in [0..9] which are exactly k
away from d. These coefficients will always be 0, 1 or 2.
For example, for a = 3496 the polynomials are:
d 1 x x^2 x^3 x^4 x^5 x^6 x^7 x^8 x^9
-- --- --- --- --- --- --- --- --- --- ---
3 1 2 2 1 1 1 1 0 0 0
4 1 2 2 2 2 1 0 0 0 0
9 1 1 1 1 1 1 1 1 1 1
6 1 2 2 2 1 1 1 0 0 0
N.B.: The coefficient of x^3 for the digit 3
is 1 and not 2 because leading zeros are not allowed.
Now multiply the polynomials together and N(a,c) is coefficient of x^c
in the resulting product.

Create matrix with ascending intergers per column with additional shifts and maximal value

I need to create the following type of matrices in R. Let m be the maximal value to increment to per column, and n the number of columns of the resulting matrix.
For m=3 and n=2
1 0
2 0
3 0
3 1
3 2
3 3
For m=4 and n=3
1 0 0
2 0 0
3 0 0
4 0 0
4 1 0
4 2 0
4 3 0
4 4 0
4 4 1
4 4 2
4 4 3
4 4 4
Does anyone know a nice way how to do that?
+1 for the slickest answer ;)
Powered by my new knowledge about cummax thanks to #AnandaMahto and #alexis_laz, I found a slick one using the Kronecker product
apply(diag(n) %x% 1:m, 2, cummax)
This seems to be valid, unless I've missed something:
ff = function(m, n)
apply(xtabs(rep(seq_len(m), n) ~ seq_len(m * n) + rep(seq_len(n), each = m)),
2, cummax)
ff(3, 2)
ff(4, 3)
My suggested approach would be to create an empty matrix, use matrix indexing to fill in your first set of values, and cummax to get the rest.
myFun <- function(m, n) {
M <- matrix(0, ncol = n, nrow = m*n)
M[cbind(sequence(nrow(M)), 0:(m*n-1) %/% m + 1)] <- sequence(m)
apply(M, 2, cummax)
}

Find the summation of this series :0,1,3,6,10,15,...,n [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
How can I find summation formula for the sequence :
:0,1,3,6,10,15,...,n
please take care the first element is 0 .
That sequence is the Triangular number, also known as A000217.
The value of entry n can be calculated with f(n) = (n * (n+1)) / 2.
As a comment pointed out, this only calculates the value of f(n), not the summation of the series 0..n. The summation can be calculated by s(n) = n * (n+1) * (n+2) / 6 according to Wikipedia. These numbers are Thetrahedral numbers, or A000292.
n | f(n) | s(n)
0 | 0 * 1 / 2 = 0 | 0 * 1 * 2 / 6 = 0
1 | 1 * 2 / 2 = 1 | 1 * 2 * 3 / 6 = 1
2 | 2 * 3 / 2 = 3 | 2 * 3 * 4 / 6 = 4
3 | 3 * 4 / 2 = 6 | 3 * 4 * 5 / 6 = 10
4 | 4 * 5 / 2 = 10 | 4 * 5 * 6 / 6 = 20
5 | 5 * 6 / 2 = 15 | 5 * 6 * 7 / 6 = 35
The ith number in the sequence is i(i-1)/2=(i^2-i)/2. Summing this from 1 to n gives n(n+1)(2n+1)/12-n(n+1)/4=n(n+1)((2n+1)/12-3/12)=n(n+1)(2n-2)/12=n(n+1)(n-1)/6.
But yeah, math questions belong on http://math.stackexchange.com.
Here's a C implementation of an algorithm that should do the trick
int sum = 0;
for(int i = 0; sum <= n; i++)
{
sum = sum + (sum + i)
}

Apply in R: recursive function that operates on its own previous result

How do I apply a function that can "see" the preceding result when operating by rows?
This comes up a lot, but my current problem requires a running total by student that resets if the total doesn't get to 5.
Example Data:
> df
row Student Absent Consecutive.Absences
1 A 0 0
2 A 1 1
3 A 1 2
4 A 0 0 <- resets to zero if under 5
5 A 0 0
6 A 1 1
7 A 1 2
8 A 1 3
9 B 1 1 <- starts over for new factor (Student)
10 B 1 2
11 B 0 0
12 B 1 1
13 B 1 2
14 B 1 3
15 B 1 4
16 B 0 0
17 B 1 1
18 B 1 2
19 B 1 3
20 B 1 4
21 B 1 5
22 B 0 5 <- gets locked at 5
23 B 0 5
24 B 1 6
25 B 1 7
I've tried doing this with a huge matrix of shifted vectors.
I've tried doing this with the apply family of functions and half of them do nothing, the other half hit 16GB of RAM and crash my computer.
I've tried straight looping and it takes 4+ hours (it's a big data set)
What bothers me is how easy this is in Excel. Usually R runs circles around Excel both in speed and writability, which leads me to believe I'm missing something elementary here.
Forgetting even the more challenging ("lock at 5") feature of this, I can't even get a cumsum that resets. There is no combination of factors I can think of to group for ave like this:
Consecutive.Absences = ave(Absent, ..., cumsum)
Obviously, grouping on Student will just give the Total Cumulative Absences -- it "remembers" the kid's absence over the gaps because of the split and recombine in ave.
So as I said, the core of what I don't know how to do in R is this:
How do I apply a function that can "see" the preceding result when operating by rows?
In Excel it would be easy:
C3 = IF($A3=$A2,$B3+$C2,$B3)*$B3
This excel function is displayed without the 5-absence lock for easy readability.
Once I figure out how to apply a function that looks at previous results of the same function in R, I'll be able to figure out the rest.
Thank you in advance for your help--this will be very useful in a lot of my applications!
Genuinely,
Sam
UPDATE:
Thank you everyone for the ideas on how to identify if a student has 5 consecutive absences!
However, that's easy enough to do in the database at the STUDENTS table. What I need to know is the number of consecutive absences by student in the attendance record itself for things like, "Do we count this particular attendance record when calculating other summary statistics?"
If you're looking to apply a function to every element in a vector while making use the previous element's value, you might want to check out "Reduce", with the accumulate parameter set to True
Here's an example:
##define your function that takes two parameters
##these are the 'previous' and the 'current' elements
runSum <- function(sum, x){
res = 0
if (x == 1){
res = sum + 1
}
else if (x == 0 & sum < 5){
res = 0
}
else{
res = sum
}
res
}
#lets look at the absent values from subject B
x = c(1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1)
Reduce(x=x, f=runSum, accumulate=T)
# [1] 1 2 0 1 2 3 4 0 1 2 3 4 5 5 5 6 7
It's fairly easy to identify the students with one or more runs of 5:
tapply(dfrm$Absent, dfrm$Student, function(x) rle(x)$value[rle(x)$length >=5] )
$A
integer(0)
$B
[1] 1
Look for any values of "1" in the result:
tapply(dfrm$Absent, dfrm$Student, function(x) 1 %in% rle(x)$value[rle(x)$length >=5] )
A B
FALSE TRUE
I also struggled through to a Reduce solution (but am second in priority to #kithpradhan):
ave(dfrm$Absent, dfrm$Student,
FUN= function(XX)
Reduce(function(x,y) if( x[1] >= 5){ y+x[1]
} else{ x[1]*y+y } , #Resets to 0 if y=0
XX, accumulate=TRUE)
)
#[1] 0 1 2 0 0 1 2 3 1 2 0 1 2 3 4 0 1 2 3 4 5 5 5 6 7
For the record, you can also create your own Reduce-derivative which receives f and x, and applies f(x) on its output until x == f(x) or maxiter is reached:
ireduce = function(f, x, maxiter = 50){
i = 1
while(!identical(f(x), x) & i <= maxiter) {x = f(x); i = i+1}; x
}

Resources