Thread overview
[BEGINNER] reccurence! and sequence!
Jun 26, 2017
helxi
Jun 26, 2017
ag0aep6g
Jul 05, 2017
helxi
Jul 06, 2017
Ali Çehreli
Jul 06, 2017
helxi
Jul 06, 2017
ag0aep6g
June 26, 2017
Can someone give me a very watered-down explanation of what std.range's recurrence! and sequence! do?

> auto tri = sequence!((a,n) => n*(n+1)/2)();

/** okay, it's a triangular number array
* I understand n is the index number, the nth term
* However where does this 'a' go?
*/

> auto odds = sequence!("a[0] + n * a[1]")(1, 2);

/** okay, this is a range of odd numbers
/ where and how do I plug (1, 2) into ""a[0] + n * a[1]"

> sequence!("n+2")(1).take(10).writeln;
//[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
> recurrence!("n+2")(1).take(10).writeln;
//[1, 3, 4, 5, 6, 7, 8, 9, 10, 11]

June 26, 2017
On 06/26/2017 11:51 AM, helxi wrote:
>> auto tri = sequence!((a,n) => n*(n+1)/2)();
> 
> /** okay, it's a triangular number array
> * I understand n is the index number, the nth term
> * However where does this 'a' go?
> */

`a` is a tuple of the run-time arguments you pass to `sequence`. In this example, no arguments are passed (empty parens at the end of the call), so `a` is empty.

>> auto odds = sequence!("a[0] + n * a[1]")(1, 2);
> 
> /** okay, this is a range of odd numbers
> / where and how do I plug (1, 2) into ""a[0] + n * a[1]"

a[0] = 1
a[1] = 2

>> sequence!("n+2")(1).take(10).writeln;
> //[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

`a` isn't used in the string lambda, and it's not considered an element of the range. So n starts at 0 and this just prints 0+2, 1+2, 2+2, etc.

>> recurrence!("n+2")(1).take(10).writeln;
> //[1, 3, 4, 5, 6, 7, 8, 9, 10, 11]

`a` is still not used in the string lambda, but `recurrence` uses the values in `a` as the first elements of the range. `n` is incremented accordingly (to 1), so this prints:

1 = a[0],
3 = (n = 1) + 2,
4 = (n = 2) + 2,
etc.

Another difference between `sequence` and `recurrence` is that `a` always refers to the same initial value(s) in `sequence`, while in `recurrence` it gets updated and refers to the previous element(s) of the range:

----
sequence!((a, n) => a[0] + 1)(1).take(10).writeln;
    // [2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
    // because a[0] is always 1

recurrence!((a, n) => a[0] + 1)(1).take(10).writeln;
    // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    // because a[0] refers to the previous value
----
July 05, 2017
On Monday, 26 June 2017 at 10:34:22 UTC, ag0aep6g wrote:
> On 06/26/2017 11:51 AM, helxi wrote:
>> [...]
>
> `a` is a tuple of the run-time arguments you pass to `sequence`. In this example, no arguments are passed (empty parens at the end of the call), so `a` is empty.
>
>> [...]
>
> a[0] = 1
> a[1] = 2
>
>> [...]
>
> `a` isn't used in the string lambda, and it's not considered an element of the range. So n starts at 0 and this just prints 0+2, 1+2, 2+2, etc.
>
>> [...]
>
> `a` is still not used in the string lambda, but `recurrence` uses the values in `a` as the first elements of the range. `n` is incremented accordingly (to 1), so this prints:
>
> 1 = a[0],
> 3 = (n = 1) + 2,
> 4 = (n = 2) + 2,
> etc.
>
> Another difference between `sequence` and `recurrence` is that `a` always refers to the same initial value(s) in `sequence`, while in `recurrence` it gets updated and refers to the previous element(s) of the range:
>
> ----
> sequence!((a, n) => a[0] + 1)(1).take(10).writeln;
>     // [2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
>     // because a[0] is always 1
>
> recurrence!((a, n) => a[0] + 1)(1).take(10).writeln;
>     // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>     // because a[0] refers to the previous value
> ----

Oh thank you. Just 2 follow-up questions:
> recurrence!((a, n) => a[0] + 1)(1).take(10).writeln;
1. In the last example of reccurence, what does n in (a,n) refer to?
2. How would you chain until! with reccurence? For example I want to compute 1, 10, 100, ..., (until the value remains smaller than 1000_000)?
July 05, 2017
On 07/05/2017 04:38 PM, helxi wrote:

>> ----
>> sequence!((a, n) => a[0] + 1)(1).take(10).writeln;
>>     // [2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
>>     // because a[0] is always 1
>>
>> recurrence!((a, n) => a[0] + 1)(1).take(10).writeln;
>>     // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>     // because a[0] refers to the previous value
>> ----
>
> Oh thank you. Just 2 follow-up questions:
>> recurrence!((a, n) => a[0] + 1)(1).take(10).writeln;
> 1. In the last example of reccurence, what does n in (a,n) refer to?

n is "the index of the current value". Each time the lambda is called,

  a[n] is what is being generated
  a[n-1] is the previous value
  a[0] is the same as a[n-1]? (I find this confusing)

> 2. How would you chain until! with reccurence? For example I want to
> compute 1, 10, 100, ..., (until the value remains smaller than 1000_000)?

import std.stdio;
import std.algorithm;
import std.range;

void main() {
    auto r = recurrence!((a, n) => a[n-1] * 10)(1);
    auto u = r.until!(a => a >= 1_000_000);
    writeln(u);
}

[1, 10, 100, 1000, 10000, 100000]

Ali

July 06, 2017
On Thursday, 6 July 2017 at 00:21:44 UTC, Ali Çehreli wrote:
> On 07/05/2017 04:38 PM, helxi wrote:
>
> >> [...]
> >
> > Oh thank you. Just 2 follow-up questions:
> >> [...]
> > 1. In the last example of reccurence, what does n in (a,n)
> refer to?
>
> n is "the index of the current value". Each time the lambda is called,
>
>   a[n] is what is being generated
>   a[n-1] is the previous value
>   a[0] is the same as a[n-1]? (I find this confusing)
>
> > 2. How would you chain until! with reccurence? For example I
> want to
> > compute 1, 10, 100, ..., (until the value remains smaller
> than 1000_000)?
>
> import std.stdio;
> import std.algorithm;
> import std.range;
>
> void main() {
>     auto r = recurrence!((a, n) => a[n-1] * 10)(1);
>     auto u = r.until!(a => a >= 1_000_000);
>     writeln(u);
> }
>
> [1, 10, 100, 1000, 10000, 100000]
>
> Ali

Hmm, I get it now. Thank you very much.
July 06, 2017
On 07/06/2017 02:21 AM, Ali Çehreli wrote:
> On 07/05/2017 04:38 PM, helxi wrote:
[...]
>  >> recurrence!((a, n) => a[0] + 1)(1).take(10).writeln;
>  > 1. In the last example of reccurence, what does n in (a,n) refer to?
> 
> n is "the index of the current value". Each time the lambda is called,
> 
>    a[n] is what is being generated
>    a[n-1] is the previous value
>    a[0] is the same as a[n-1]? (I find this confusing)

Looks like I was wrong when I stated that "a[0] refers to the previous value". `a[0]` is actually invalid for n > 1.

The documentation for `recurrence` says you have to index relative to n, and you can only go back as many values as you gave initially. I should have used `a[n - 1]`.