www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Two chunks but No allocation

reply Salih Dincer <salihdb hotmail.com> writes:
Is it possible to process both chunks without requiring memory 
allocation (not using an array)?

For example:

```d
import std;
void main()
{
   auto fib = (real a, real b)
        => recurrence!"a[n-1] + a[n-2]"(a, b);

   auto myFib = fib(1, 1).take(48).array;
   auto goldenRadio = myFib.chunks(2).map!

   ((a) {
     const m = a.front;
     a.popFront();
     const n = a.front;

     return m/n; });//*/

   goldenRadio.back.writefln!"%.21f";
   writeln("0.61803398874989484820");
}
```

Of course, it also works if you remove the comment marks on line 

that.

So, not works this:

```d
fib(1, 1).take(48)
          //.array
          .chunks(2)
          .map!"a[1] / a[0]"
          .back
          .writeln; // 1.61803
```

Thanks...

SDB 79
Mar 27
parent reply rkompass <rkompass gmx.de> writes:
On Wednesday, 27 March 2024 at 13:38:29 UTC, Salih Dincer wrote:

 So, not works this:

 ```d
 fib(1, 1).take(48)
          //.array
          .chunks(2)
          .map!"a[1] / a[0]"
          .back
          .writeln; // 1.61803
 ```

 Thanks...

 SDB 79
This works: ```d import std.stdio; import std.range; import std.algorithm; void main() { auto fib = (real a, real b) => recurrence!"a[n-1] + a[n-2]"(a, b); auto golden = fib(1, 1).drop(46).take(2).fold!((a, e) => a/e); writefln("%.20f", golden); writeln("0.61803398874989484820"); } ```
Mar 27
parent reply Salih Dincer <salihdb hotmail.com> writes:
On Wednesday, 27 March 2024 at 20:50:05 UTC, rkompass wrote:
 This works:
I decided to give the full code. Maybe then it will be better understood what I mean. I actually pointed out the indirect solution above but it's a bit ugly and I'm sure there must be a better way? ```d import std.datetime.stopwatch; import std.stdio, std.algorithm, std.range; auto cube(T)(T n) => n * n * n; auto S1(T, R)(R a, T n) => n.cube - n; // auto s1(T)(T first, size_t skip = 3) => recurrence!S1(0, first).drop(skip); enum ITERATIONS = 14_000; enum BENCHMARKS = 100; void main() { real result; long total_time = 0; for(int i = 0; i < BENCHMARKS; i++) { auto sw = StopWatch(AutoStart.no); sw.start(); result = s1(3.0).take(ITERATIONS) .chunks(2) .map!(r => 4/r.front) .array // <- can't it be done without this? .chunks(2) .map!"a[0] - a[1]" .fold!"a + b"(3.0); sw.stop(); total_time += sw.peek.total!"nsecs"; } writefln("%f (nsecs)", total_time / BENCHMARKS / 1e9); writefln("%0.16f (result)", result);``` } /* 0.000456 (nsecs) 3.1415926535890670 (result) //*/ ``` SDB 79
Mar 27
parent reply rkompass <rkompass gmx.de> writes:
On Thursday, 28 March 2024 at 03:54:05 UTC, Salih Dincer wrote:
 On Wednesday, 27 March 2024 at 20:50:05 UTC, rkompass wrote:
 This works:
I decided to give the full code. Maybe then it will be better understood what I mean. I actually pointed out the indirect solution above but it's a bit ugly and I'm sure there must be a better way?
I didn't look exactly at you code but at the ranges problem. Perhaps this is of help: ```d import std.stdio; import std.range; import std.algorithm; void main() { auto fib = (real a, real b) => recurrence!"a[n-1] + a[n-2]"(a, b); auto golden3 = fib(1,1).chunks(2).map!(r => r.fold!((a, e) => a/e)).take(10); writeln(golden3); } ``` I thought what you wanted (and what I found to be an interesting problem) was to convert the subranges delivered by `chunks(2)` to values that still are generated lazily, without saving them in an array (which converts the range type to a higher one), according to original range. You can drop and take from the folded values range. I got `[1, 0.666667, 0.625, 0.619048, 0.618182, 0.618056, 0.618037, 0.618034, 0.618034, 0.618034]` from the above code.
Mar 28
parent Salih Dincer <salihdb hotmail.com> writes:
On Thursday, 28 March 2024 at 23:08:54 UTC, rkompass wrote:
 You can drop and take from the folded values range.

 I got `[1, 0.666667, 0.625, 0.619048, 0.618182, 0.618056, 
 0.618037, 0.618034, 0.618034, 0.618034]` from the above code.
Thank you so much... I solved the problem: r.back doesn't work because recurrence() runs forever and you need to use it with take. In other words, the range functions up to the map must have members such as length() and opSlice(). SDB 79
Mar 28