digitalmars.D.learn - Two chunks but No allocation
- Salih Dincer (35/35) Mar 27 Is it possible to process both chunks without requiring memory
- rkompass (14/25) Mar 27 This works:
- Salih Dincer (43/44) Mar 27 I decided to give the full code. Maybe then it will be better
- rkompass (23/29) Mar 28 I didn't look exactly at you code but at the ranges problem.
- Salih Dincer (7/10) Mar 28 Thank you so much...
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
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 79This 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
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
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: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.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?
Mar 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
Mar 28