Thread overview
Two chunks but No allocation
Mar 27
rkompass
Mar 28
rkompass
March 27

Is it possible to process both chunks without requiring memory allocation (not using an array)?

For example:

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[1] / a[0]";/* line #9
  ((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 #9 but I'm still using .array because the .chunks error tells me that.

So, not works this:

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

Thanks...

SDB@79

March 27

On Wednesday, 27 March 2024 at 13:38:29 UTC, Salih Dincer wrote:

>

So, not works this:

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

Thanks...

SDB@79

This works:

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");
}
March 28

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?

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

March 28

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:

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.

March 28

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