Jump to page: 1 25  
Page
Thread overview
automate tuple creation
Jan 19, 2022
forkit
Jan 19, 2022
forkit
Jan 19, 2022
H. S. Teoh
Jan 19, 2022
Ali Çehreli
Jan 19, 2022
Ali Çehreli
Jan 19, 2022
forkit
Jan 19, 2022
forkit
Jan 19, 2022
H. S. Teoh
Jan 19, 2022
Ali Çehreli
Jan 20, 2022
forkit
Jan 20, 2022
H. S. Teoh
Jan 20, 2022
forkit
Jan 20, 2022
forkit
Jan 20, 2022
forkit
Jan 20, 2022
bauss
Jan 20, 2022
forkit
Jan 20, 2022
Stanislav Blinov
Jan 20, 2022
forkit
Jan 20, 2022
forkit
Jan 20, 2022
forkit
Jan 20, 2022
Ali Çehreli
Jan 20, 2022
Ali Çehreli
Jan 21, 2022
forkit
Jan 21, 2022
forkit
Jan 21, 2022
Ali Çehreli
Jan 21, 2022
forkit
Jan 21, 2022
forkit
Jan 21, 2022
H. S. Teoh
Jan 21, 2022
forkit
Jan 21, 2022
forkit
Jan 21, 2022
Stanislav Blinov
Jan 21, 2022
forkit
Jan 21, 2022
forkit
Jan 21, 2022
H. S. Teoh
Jan 21, 2022
forkit
Jan 21, 2022
forkit
Jan 21, 2022
forkit
Jan 21, 2022
H. S. Teoh
Jan 21, 2022
forkit
Jan 21, 2022
forkit
Jan 22, 2022
forkit
Jan 22, 2022
forkit
Jan 21, 2022
forkit
Jan 21, 2022
H. S. Teoh
January 19, 2022
so I have this code below, that creates an array of tuples.

but instead of hardcoding 5 tuples (or hardcoding any amount of tuples),
what I really want to do is automate the creation of how-ever-many tuples I ask for:

i.e.

instead of calling this: createBoolMatrix(mArrBool);
I would call something like this: createBoolMatrix(mArrBool,5); // create an array of 5 typles.

Some ideas about direction would be welcome ;-)


// ---
module test;

import std.stdio;
import std.range;
import std.traits;
import std.random;

@safe:

void main()
{
    uint[][] mArrBool;
    createBoolMatrix(mArrBool);
    process(mArrBool);
}

void process(T)(const ref T t) if (isForwardRange!T && !isInfinite!T)
{
    t.writeln; // sample output -> [[0, 1], [1, 0], [1, 1], [1, 1], [1, 1]]
}

void createBoolMatrix(ref uint[][] m)
{
    auto rnd = Random(unpredictableSeed);

    // btw. below does register with -profile=gc
    m = [ [cast(uint)rnd.dice(0.6, 1.4), cast(uint)rnd.dice(0.4, 1.6)].randomShuffle(rnd),
          [cast(uint)rnd.dice(0.6, 1.4), cast(uint)rnd.dice(0.4, 1.6)].randomShuffle(rnd),
          [cast(uint)rnd.dice(0.6, 1.4), cast(uint)rnd.dice(0.4, 1.6)].randomShuffle(rnd),
          [cast(uint)rnd.dice(0.6, 1.4), cast(uint)rnd.dice(0.4, 1.6)].randomShuffle(rnd),
          [cast(uint)rnd.dice(0.6, 1.4), cast(uint)rnd.dice(0.4, 1.6)].randomShuffle(rnd)
        ];
}
// --
January 19, 2022
On Wednesday, 19 January 2022 at 21:59:15 UTC, forkit wrote:
>

oh. that randomShuffle was unnecessary ;-)

January 19, 2022
On Wed, Jan 19, 2022 at 09:59:15PM +0000, forkit via Digitalmars-d-learn wrote:
> so I have this code below, that creates an array of tuples.
> 
> but instead of hardcoding 5 tuples (or hardcoding any amount of tuples), what I really want to do is automate the creation of how-ever-many tuples I ask for:
> 
> i.e.
> 
> instead of calling this: createBoolMatrix(mArrBool);
> I would call something like this: createBoolMatrix(mArrBool,5); //
> create an array of 5 typles.

Why can't you just use a loop to initialize it?

	uint[][] createBoolMatrix(size_t n) {
		auto result = new uint[][n]; // allocate outer array
		foreach (ref row; result) {
			row = new uint[n]; // allocate inner array
			foreach (ref cell; row) {
				cell = cast(uint) rnd.dice(0.6, 1.4);
			}
		}
		return result;
	}

Or, if you wanna use those new-fangled range-based idioms:

	uint[][] createBoolMatrix(size_t n) {
		return iota(n)
			.map!(i => iota(n)
				.map!(j => cast(uint) rnd.dice(0.6, 1.4))
				.array)
			.array;
	}


T

-- 
Verbing weirds language. -- Calvin (& Hobbes)
January 19, 2022
On 1/19/22 13:59, forkit wrote:

> void createBoolMatrix(ref uint[][] m)
> {
>      auto rnd = Random(unpredictableSeed);

That works but would be unnecessarily slow and be against the idea of random number generators. The usual approach is, once you have a randomized sequence, you just continue using it. For example, I move rnd to module scope and initialize it once.

Random rnd;

shared static this() {
  rnd = Random(unpredictableSeed);
}

auto randomValue() {
  return cast(uint)rnd.dice(0.6, 1.4);
}

// Returning a dynamically allocated array looks expensive
// here. Why not use a struct or std.typecons.Tuple instead?
auto randomTuple() {
  return [ randomValue(), randomValue() ];
}

void createBoolMatrix(ref uint[][] m, size_t count)
{
  import std.algorithm : map;
  import std.range : iota;
  m = count.iota.map!(i => randomTuple()).array;
}

Ali

January 19, 2022
On 1/19/22 14:33, Ali Çehreli wrote:

> Random rnd;
>
> shared static this() {
>    rnd = Random(unpredictableSeed);
> }

But that's a mistake: If rnd is thread-local like that, it should be initialized in a 'static this' (not 'shared static this'). Otherwise, only the main thread's 'rnd' would be randomized, which is the only thread that executes 'shared static this' blocks.

Ali

January 19, 2022
On Wed, Jan 19, 2022 at 02:33:02PM -0800, Ali Çehreli via Digitalmars-d-learn wrote: [...]
> // Returning a dynamically allocated array looks expensive // here. Why not use a struct or std.typecons.Tuple instead?

Premature optimization. ;-)  There's nothing wrong with allocating an array.

If you're worried about memory efficiency, you could allocate the entire matrix in a single block and just assemble slices of it in the outer block, like this:

	uint[][] createBoolMatrix(size_t count) {
		auto buffer = new uint[count*count];
		return iota(count).map!(i => buffer[count*i .. count*(i+1)])
			.array;
	}

This lets you do only 2 GC allocations instead of (1+count) GC allocations.  May help with memory fragmentation if `count` is large and you create a lot of these things.  But I honestly wouldn't bother with this unless your memory profiler is reporting a problem in this aspect of your program.  It just adds complexity to your code (== poorer long-term maintainability) for meager benefits.


T

-- 
What do you call optometrist jokes? Vitreous humor.
January 19, 2022
On Wednesday, 19 January 2022 at 22:35:58 UTC, Ali Çehreli wrote:
>

so I combined ideas from all responses:

// --
module test;

import std.stdio : writeln;
import std.range : iota, isForwardRange, hasSlicing, hasLength, isInfinite, array;
import std.random : Random, unpredictableSeed, dice;
import std.algorithm : map;

@safe:

Random rnd;

static this()
{
  rnd = Random(unpredictableSeed);
}

void main()
{
    uint[][] mArrBool;

    // e.g: create a matrix consisting of 5 tuples, with each tuple containing 3 random bools (0 or 1)
    createBoolMatrix(mArrBool,5, 2);

    process(mArrBool);
}

void createBoolMatrix(ref uint[][] m, size_t numberOfTuples, size_t numberOfBoolsInTuple)
{
    m = iota(numberOfTuples)
            .map!(i => iota(numberOfBoolsInTuple)
            .map!(numberOfBoolsInTuple => cast(uint) rnd.dice(0.6, 1.4))
			.array).array;
}

void process(T)(const ref T t) if (isForwardRange!T && hasSlicing!T && hasLength!T && !isInfinite!T)
{
    t.writeln;
}

//--

January 19, 2022
On Wednesday, 19 January 2022 at 23:22:17 UTC, forkit wrote:
>

oops

// e.g: create a matrix consisting of 5 tuples, with each tuple containing 3 random bools (0 or 1)
    createBoolMatrix(mArrBool,5, 3);
January 19, 2022
On 1/19/22 15:21, H. S. Teoh wrote:
> On Wed, Jan 19, 2022 at 02:33:02PM -0800, Ali Çehreli via Digitalmars-d-learn wrote:
> [...]
>> // Returning a dynamically allocated array looks expensive
>> // here. Why not use a struct or std.typecons.Tuple instead?
>
> Premature optimization. ;-)

Not in this case because I am pointing at premature pessimization. :) There is no reason to use two-element dynamic arrays when uint[2], Tuple!(uint, uint), and structs are available.

> There's nothing wrong with allocating an
> array.

Agreed.

Ali

January 20, 2022
On Wednesday, 19 January 2022 at 21:59:15 UTC, forkit wrote:
>

so at the moment i can get a set number of tuples, with a set number of bool values contained within each tuple.

e.g.
createBoolMatrix(mArrBool,3, 2);
[[1, 0], [1, 1], [1, 0]]

my next challenge (more for myself, but happy for input)..

is to enhance this to an return an associative array:

e.g

createBoolAssociativeMatrix(mArrBool,3, 2);

[ [1000:[1, 0]], [1001:[1, 1]], [1001:[1, 0]]]


where 1000 is some random id...

« First   ‹ Prev
1 2 3 4 5