Re: Filling an array at compile time

2022-02-09 Thread bauss via Digitalmars-d-learn

On Wednesday, 9 February 2022 at 16:37:22 UTC, Ali Çehreli wrote:

On 2/9/22 01:07, bauss wrote:

> It will not run at compile-time because csvText is a runtime
variable.
> It should be enum to be accessible at compile-time.

Yes. For the sake of completeness, any expression needed at 
compile time will be (attempted to be) executed at compile 
time. For example, an expression used as a template parameter 
will be executed at compile time as well.


> The append operation
> will be executed at runtime, which means that even if the
loop runs at
> compile-time then you're effectively not winning anything and
it
> basically just becomes a loop-unroll manually done.

That's not true. It all depends on how the expression is 
needed. If for example, the variable were defined as enum, the 
compiler had to execute the code at compile time to compute its 
value.


> The solution would be to create a function that returns a
string [...]
> And then simply using mixin

That is unnecessary and hurts readability. :/ Most programmers 
see string mixins as a last resort.


In any case, some people may find a compile-time file parsing 
example that I included in a presentation:


  https://youtu.be/dRORNQIB2wA?t=3157

Ali


Thank you Ali for the clarifications


Re: how to handle very large array?

2022-02-09 Thread forkit via Digitalmars-d-learn

On Thursday, 10 February 2022 at 01:43:54 UTC, H. S. Teoh wrote:
On Thu, Feb 10, 2022 at 01:32:00AM +, MichaelBi via 
Digitalmars-d-learn wrote:
On Wednesday, 9 February 2022 at 19:48:49 UTC, H. S. Teoh 
wrote:

> [...]

thanks, very helpful! i am using a assocArray now...


Are you sure that's what you need?


T


https://youtu.be/yJjpXJm7x0o?t=213


Re: how to handle very large array?

2022-02-09 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Feb 10, 2022 at 01:32:00AM +, MichaelBi via Digitalmars-d-learn 
wrote:
> On Wednesday, 9 February 2022 at 19:48:49 UTC, H. S. Teoh wrote:
> > [...]
> 
> thanks, very helpful! i am using a assocArray now...

Are you sure that's what you need?


T

-- 
Computers are like a jungle: they have monitor lizards, rams, mice, c-moss, 
binary trees... and bugs.


Re: how to handle very large array?

2022-02-09 Thread MichaelBi via Digitalmars-d-learn

On Wednesday, 9 February 2022 at 19:48:49 UTC, H. S. Teoh wrote:

[...]


thanks, very helpful! i am using a assocArray now...


Re: How to use sets in D?

2022-02-09 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Feb 10, 2022 at 12:53:08AM +, Siarhei Siamashka via 
Digitalmars-d-learn wrote:
> On Wednesday, 9 February 2022 at 21:05:47 UTC, Siarhei Siamashka wrote:
> > Is the current implementation of associative arrays in D language
> > resistant to Denial of Service hash collision attacks?
> 
> Answering to myself. No, it isn't. Here's a simple example:
[...]
> ulong[] generate_bad_array(ulong n)
> {
> return iota(n).map!(x => (x << 46)).array;
> }
[...]
> == adversarially constructed array ==
> n=10, unique_elements=10, assoc time: 22626 ms, rbtree time: 15 ms
> ```

Nice investigation!  This should be filed as a bug.

I remember browsing through various hash functions in druntime before
(built-in AA's use per-type hash functions), and many of them were
trivial, which would imply that it's trivial to construct adversarial
input that triggers a large number of collisions for various basic
types.


T

-- 
Give me some fresh salted fish, please.


Re: How to use sets in D?

2022-02-09 Thread Siarhei Siamashka via Digitalmars-d-learn
On Wednesday, 9 February 2022 at 21:05:47 UTC, Siarhei Siamashka 
wrote:
Is the current implementation of associative arrays in D 
language resistant to Denial of Service hash collision attacks?


Answering to myself. No, it isn't. Here's a simple example:

```D
import std, core.time;

const ulong n = 10;

// Count the number of unique elements using associative array
ulong count_unique_values_assoc(const ulong[] a)
{
bool[ulong] set;
foreach (x ; a)
set[x] = true;
return set.length;
}

// Count the number of unique elements using redBlackTree
ulong count_unique_values_rbtree(const ulong[] a)
{
auto set = redBlackTree!("a (x << 46)).array;
}

// Benchmark associative array vs. rbtree
void run_benchmark(ulong[] a)
{
auto t1 = MonoTime.currTime;
auto result_assoc = a.count_unique_values_assoc;
auto t2 = MonoTime.currTime;
auto result_rbtree = a.count_unique_values_rbtree;
auto t3 = MonoTime.currTime;

assert(result_assoc == result_rbtree);
writefln("n=%d, unique_elements=%d, assoc time: %d ms, rbtree 
time: %d ms",

 a.length, result_assoc,
 (t2 - t1).total!"msecs",
 (t3 - t2).total!"msecs");
}

void main()
{
assert([1UL, 1UL, 2UL].count_unique_values_assoc == 2);
assert([1UL, 1UL, 2UL].count_unique_values_rbtree == 2);

writefln("== consecutive numbers ==");
n.iota.array.run_benchmark;

writefln("\n== random numbers between 0 and 99 ==");
n.iota.map!(_ => uniform(0UL, 100UL)).array.run_benchmark;

writefln("\n== adversarially constructed array ==");
n.generate_bad_array.run_benchmark;
}
```

Benchmark results using a 64-bit LDC compiler:

```
== consecutive numbers ==
n=10, unique_elements=10, assoc time: 11 ms, rbtree time: 
20 ms


== random numbers between 0 and 99 ==
n=10, unique_elements=100, assoc time: 2 ms, rbtree time: 4 ms

== adversarially constructed array ==
n=10, unique_elements=10, assoc time: 22626 ms, rbtree 
time: 15 ms

```


Re: How to use sets in D?

2022-02-09 Thread Siarhei Siamashka via Digitalmars-d-learn

On Tuesday, 8 February 2022 at 21:42:06 UTC, H. S. Teoh wrote:
But as I said, this is overkill for something so trivial. Using 
`bool[E]` or an RBTree works just fine.


Is the current implementation of associative arrays in D language 
resistant to Denial of Service hash collision attacks?


 * https://github.com/dlang/dmd/blob/master/src/dmd/root/aav.d

 * 
https://arstechnica.com/information-technology/2011/12/huge-portions-of-web-vulnerable-to-hashing-denial-of-service-attack/


 * https://lwn.net/Articles/474912/

 * https://codeforces.com/blog/entry/62393

If not, then redBlackTree may be safer to use when dealing with 
potentially adversarially constructed input data.


Re: how to handle very large array?

2022-02-09 Thread H. S. Teoh via Digitalmars-d-learn
On Wed, Feb 09, 2022 at 11:05:23AM -0800, Ali Çehreli via Digitalmars-d-learn 
wrote:
> On 2/9/22 10:38, MoonlightSentinel wrote:
> 
> > There's a way to use a much smaller array to manage the lanternfish
> > population...
> 
> As soon as I read your comment, I was reminded of a certain ingenious
> sorting algorithm that is O(N). ;) After reading the problem
> description, I see your hint was useful.
[...]

If you know beforehand that your data is discrete and bounded, you can
achieve O(N) sort complexity (as opposed to O(N log N), which is the
lower bound if you cannot make any assumptions about your data beyond
their ordering).  You can use pigeonhole sort, for example, i.e., create
an M-element array of counters where M is the number of distinct values
your elements may have, then just iterate over your data and increment
the counter corresponding to each element you find (using array indexing
for O(1) access to each counter). Then iterate over the array of
counters in order and replace the input data with that many copies of
each element. Your overall complexity then would be O(N+M), which would
be O(N) if M is about the same order of magnitude as N or less.

However, this algorithm quickly becomes impractical when M grows large,
because you will soon need to create many more slots than there are
input elements. For example, sorting a general int[] this way would
require 2^32 counters, which is usually overkill unless your input has
close to 2^32 elements. (You could do it if you knew your int's are ≤ M
for some small value of M, though. But it won't work for general int[]
that can contain any value.) And trying to sort a general ulong[] this
way will not work because you would need an array of 2^64 counters,
which would not only exhaust all available RAM in today's computers, but
also take a ridiculously long amount of time to iterate in the second
step.

The insight here is *taking advantage of additional structure in your
data*.  If you take the general, minimal-assumptions approach, the best
you can do is the general O(N log N) algorithm.  However, by exploiting
additional structure in your data, you can do better.  Similarly, if you
take the naïve approach to modelling your lanternfish, you'll end up
with an unwieldy array that's far too large to fit in RAM.  If you
exploit the additional structure in your data, however, you can
accomplish the same task with a much smaller array.


T

-- 
Latin's a dead language, as dead as can be; it killed off all the Romans, and 
now it's killing me! -- Schoolboy


Re: how to handle very large array?

2022-02-09 Thread Ali Çehreli via Digitalmars-d-learn

On 2/9/22 10:38, MoonlightSentinel wrote:

> There's a way to use a much smaller array to manage the lanternfish
> population...

As soon as I read your comment, I was reminded of a certain ingenious 
sorting algorithm that is O(N). ;) After reading the problem 
description, I see your hint was useful.


Ali



Re: how to handle very large array?

2022-02-09 Thread MoonlightSentinel via Digitalmars-d-learn

On Wednesday, 9 February 2022 at 10:03:21 UTC, MichaelBi wrote:
day6 of the advent of code 2021 needs to handle an array of 
10^12 length, or even bigger...


As others have mentioned, huge arrays require appropriate memory 
/ the use of memory-mapped files to actually store it. But the 
calculation will take a *long* time even if your program could 
allocate an array of that size.


There's a way to use a much smaller array to manage the 
lanternfish population...


Re: Filling an array at compile time

2022-02-09 Thread Ali Çehreli via Digitalmars-d-learn

On 2/9/22 08:37, Ali Çehreli wrote:

> In any case, some people may find a compile-time file parsing example
> that I included in a presentation:

That should mean "may find interesting". And I've just realized that the 
chapter link is off in that video. This is the beginning of that section:


  https://www.youtube.com/watch?v=dRORNQIB2wA=3065s

Ali



Re: Filling an array at compile time

2022-02-09 Thread Ali Çehreli via Digitalmars-d-learn

On 2/9/22 01:07, bauss wrote:

> It will not run at compile-time because csvText is a runtime variable.
> It should be enum to be accessible at compile-time.

Yes. For the sake of completeness, any expression needed at compile time 
will be (attempted to be) executed at compile time. For example, an 
expression used as a template parameter will be executed at compile time 
as well.


> The append operation
> will be executed at runtime, which means that even if the loop runs at
> compile-time then you're effectively not winning anything and it
> basically just becomes a loop-unroll manually done.

That's not true. It all depends on how the expression is needed. If for 
example, the variable were defined as enum, the compiler had to execute 
the code at compile time to compute its value.


> The solution would be to create a function that returns a string [...]
> And then simply using mixin

That is unnecessary and hurts readability. :/ Most programmers see 
string mixins as a last resort.


In any case, some people may find a compile-time file parsing example 
that I included in a presentation:


  https://youtu.be/dRORNQIB2wA?t=3157

Ali



Re: Filling an array at compile time

2022-02-09 Thread user1234 via Digitalmars-d-learn

On Wednesday, 9 February 2022 at 10:25:34 UTC, bauss wrote:
Is it guaranteed that the value is initialized at compiletime 
however?


yes, D guarentees this at 100%.




Re: Filling an array at compile time

2022-02-09 Thread Vindex via Digitalmars-d-learn

On Wednesday, 9 February 2022 at 10:01:15 UTC, Anonymouse wrote:

On Wednesday, 9 February 2022 at 08:12:52 UTC, Vindex wrote:

[...]


I would do this.

```
import std;

alias Record = Tuple!(string, string, string);

static immutable string[][] table = () {
string[][] table;
string csvText = import("file.csv");

foreach (record; csvReader!Record(csvText)) {
table ~= [record[0], record[1], record[2]];
}

return table;
}();

pragma(msg, table);  // Available at compile-time

void main() {
writeln(table);
}
```

And then `-J{path}` to tell the compiler where to find 
`file.csv`.


```
dmd -J. csv.d
```


Thanks! It does indeed work at compile time.


Re: how to handle very large array?

2022-02-09 Thread user1234 via Digitalmars-d-learn

On Wednesday, 9 February 2022 at 10:29:03 UTC, ag0aep6g wrote:

Try to think of a more efficient way of storing the information.


I cant agree more. The problem of OP is not dynamic arrays, it's 
that he uses an inadequate data structure.


Re: how to handle very large array?

2022-02-09 Thread bauss via Digitalmars-d-learn

On Wednesday, 9 February 2022 at 10:03:21 UTC, MichaelBi wrote:
day6 of the advent of code 2021 needs to handle an array of 
10^12 length, or even bigger... plus change elements and append 
elements. normal implementation such as length, appender and 
ref element etc, seems cannot handle that big array? is there 
any alternative data structure or algorithm can handle such 
large array properly? thanks.


Use a memorymapped file that holds the array values, in theory it 
can be infinite then.


Since an array has a known size for each entry then you can treat 
the file as an array.


Let's say you have an array of ints.

For a memorymapped file you obviously only have bytes to work 
with, so each entry will be 4 bytes, since a 32 bit integer (int) 
is 4 bytes.


So to read something at a specific index you simply do N x I 
where N is the size of the type and I is the index you want to 
read at.


Otherwise the size of an array cannot exceed the RAM you have, if 
your system can't use diskspace as RAM of course.


Re: how to handle very large array?

2022-02-09 Thread ag0aep6g via Digitalmars-d-learn

On 09.02.22 11:09, MichaelBi wrote:

On Wednesday, 9 February 2022 at 10:05:23 UTC, MichaelBi wrote:

[...]

got outofmemory error:
core.exception.OutOfMemoryError@src\core\lifetime.d(126): Memory 
allocation failed


https://adventofcode.com/2021/day/6#part2

"Suppose the lanternfish live forever and have unlimited food and space. 
Would they take over the entire ocean?


After 256 days in the example above, there would be a total of 
26984457539 lanternfish!


How many lanternfish would there be after 256 days"

26984457539 in above is the array length.


If you store one byte per lanternfish, that's 25 GiB. You don't seem to 
have enough RAM for such a large array.


Try to think of a more efficient way of storing the information.


Re: Filling an array at compile time

2022-02-09 Thread bauss via Digitalmars-d-learn

On Wednesday, 9 February 2022 at 10:01:15 UTC, Anonymouse wrote:

On Wednesday, 9 February 2022 at 08:12:52 UTC, Vindex wrote:
Will the loop (foreach) run at compile time? How can I make it 
work at compile time?


```
import std.csv, std.stdio;

alias Record = Tuple!(string, string, string);

immutable string[][] table;

shared static this() {
string csvText = import("file.csv");
foreach (record; csvReader!Record(csvText)) {
table ~= [record[0], record[1], record[2]];
}
}

void main() {
writeln(table):
}
```


I would do this.

```
import std;

alias Record = Tuple!(string, string, string);

static immutable string[][] table = () {
string[][] table;
string csvText = import("file.csv");

foreach (record; csvReader!Record(csvText)) {
table ~= [record[0], record[1], record[2]];
}

return table;
}();

pragma(msg, table);  // Available at compile-time

void main() {
writeln(table);
}
```

And then `-J{path}` to tell the compiler where to find 
`file.csv`.


```
dmd -J. csv.d
```


Is it guaranteed that the value is initialized at compiletime 
however?


Something being available at compiletime isn't the same as being 
initialized at compiletime only.


If it's guaranteed then that's indeed the best solution.


Re: how to handle very large array?

2022-02-09 Thread MichaelBi via Digitalmars-d-learn

On Wednesday, 9 February 2022 at 10:03:21 UTC, MichaelBi wrote:
day6 of the advent of code 2021 needs to handle an array of 
10^12 length, or even bigger... plus change elements and append 
elements. normal implementation such as length, appender and 
ref element etc, seems cannot handle that big array? is there 
any alternative data structure or algorithm can handle such 
large array properly? thanks.


got outofmemory error:
core.exception.OutOfMemoryError@src\core\lifetime.d(126): Memory 
allocation failed


Re: how to handle very large array?

2022-02-09 Thread MichaelBi via Digitalmars-d-learn

On Wednesday, 9 February 2022 at 10:05:23 UTC, MichaelBi wrote:

On Wednesday, 9 February 2022 at 10:03:21 UTC, MichaelBi wrote:
day6 of the advent of code 2021 needs to handle an array of 
10^12 length, or even bigger... plus change elements and 
append elements. normal implementation such as length, 
appender and ref element etc, seems cannot handle that big 
array? is there any alternative data structure or algorithm 
can handle such large array properly? thanks.


got outofmemory error:
core.exception.OutOfMemoryError@src\core\lifetime.d(126): 
Memory allocation failed


https://adventofcode.com/2021/day/6#part2

"Suppose the lanternfish live forever and have unlimited food and 
space. Would they take over the entire ocean?


After 256 days in the example above, there would be a total of 
26984457539 lanternfish!


How many lanternfish would there be after 256 days"

26984457539 in above is the array length.


Re: Filling an array at compile time

2022-02-09 Thread Anonymouse via Digitalmars-d-learn

On Wednesday, 9 February 2022 at 08:12:52 UTC, Vindex wrote:
Will the loop (foreach) run at compile time? How can I make it 
work at compile time?


```
import std.csv, std.stdio;

alias Record = Tuple!(string, string, string);

immutable string[][] table;

shared static this() {
string csvText = import("file.csv");
foreach (record; csvReader!Record(csvText)) {
table ~= [record[0], record[1], record[2]];
}
}

void main() {
writeln(table):
}
```


I would do this.

```
import std;

alias Record = Tuple!(string, string, string);

static immutable string[][] table = () {
string[][] table;
string csvText = import("file.csv");

foreach (record; csvReader!Record(csvText)) {
table ~= [record[0], record[1], record[2]];
}

return table;
}();

pragma(msg, table);  // Available at compile-time

void main() {
writeln(table);
}
```

And then `-J{path}` to tell the compiler where to find `file.csv`.

```
dmd -J. csv.d
```


how to handle very large array?

2022-02-09 Thread MichaelBi via Digitalmars-d-learn
day6 of the advent of code 2021 needs to handle an array of 10^12 
length, or even bigger... plus change elements and append 
elements. normal implementation such as length, appender and ref 
element etc, seems cannot handle that big array? is there any 
alternative data structure or algorithm can handle such large 
array properly? thanks.


Re: Filling an array at compile time

2022-02-09 Thread bauss via Digitalmars-d-learn

On Wednesday, 9 February 2022 at 08:12:52 UTC, Vindex wrote:
Will the loop (foreach) run at compile time? How can I make it 
work at compile time?


```
import std.csv, std.stdio;

alias Record = Tuple!(string, string, string);

immutable string[][] table;

shared static this() {
string csvText = import("file.csv");
foreach (record; csvReader!Record(csvText)) {
table ~= [record[0], record[1], record[2]];
}
}

void main() {
writeln(table):
}
```


It will not run at compile-time because csvText is a runtime 
variable. It should be enum to be accessible at compile-time.


The second issue is that your foreach should probably be static 
foreach.


The third issue is how you're creating "table". The append 
operation will be executed at runtime, which means that even if 
the loop runs at compile-time then you're effectively not winning 
anything and it basically just becomes a loop-unroll manually 
done.


The solution would be to create a function that returns a string 
that is equivalent to the contents of the array you want to 
create, as if you wrote the content yourself.


And then simply using mixin to "set" the value of the table by 
calling that function.


Ex.

```
string getInt() { return "immutable a = 10;"; }

mixin(getInt);

// The variable a is accessible here ...

```


Re: How to verify DMD download with GPG?

2022-02-09 Thread Ola Fosheim Grøstad via Digitalmars-d-learn

On Tuesday, 8 February 2022 at 20:15:50 UTC, forkit wrote:

btw. the key is listed there - not sure what you mean.


I didn't see "3AAF1A18E61F6FAA3B7193E4DB8C5218B9329CF8" on the 
listing on the webpage https://dlang.org/gpg_keys.html


That pages is not similar to what I get with  "--list-keys 
--with-subkey-fingerprints".


```
pub   rsa4096 2014-09-01 [SC] [expired: 2020-03-25]
  AFC7DB45693D62BB472BF27BAB8FE924C2F7E724
uid   [ expired] Martin Nowak (dawg) 
uid   [ expired] Martin Nowak 


uid   [ expired] Martin Nowak 
uid   [ expired] Martin Nowak 

pub   rsa2048 2016-01-29 [SC]
  BBED1B088CED7F958917FBE85004F0FAD051576D
uid   [ unknown] Vladimir Panteleev 


sub   rsa2048 2016-01-29 [E]
  AB78BAC596B648B59A41983A3850E93043EBB12C

pub   rsa4096 2015-11-24 [SC] [expires: 2026-03-23]
  8FDB8D357AF468A9428ACE3C2055F76601A36FB0
uid   [ unknown] Sebastian Wilzbach 
uid   [ unknown] Sebastian Wilzbach 

pub   rsa4096 2018-03-26 [SC] [expired: 2020-03-25]
  F77158814C19E5E07BA1079A65394AFEF4A68565
uid   [ expired] DLang Nightly (bot) 



pub   rsa4096 2020-03-12 [SC] [expires: 2022-03-12]
  F46A10D0AB44C3D15DD65797BCDD73FFC3EB6146
uid   [ unknown] Martin Nowak 
uid   [ unknown] Martin Nowak 


uid   [ unknown] Martin Nowak 
sub   rsa4096 2020-03-12 [E] [expires: 2022-03-12]
  B92614C21EC5779DC678468E9A813AD3C11508BC
sub   rsa4096 2020-03-12 [S] [expires: 2022-03-12]
  3AAF1A18E61F6FAA3B7193E4DB8C5218B9329CF8
```

The last two lines on the webpage are:

```
sub   rsa4096/0x9A813AD3C11508BC 2020-03-12 [E] [expires: 
2022-03-12]
sub   rsa4096/0xDB8C5218B9329CF8 2020-03-12 [S] [expires: 
2022-03-12]

```

That is why I thought something was wrong.



Filling an array at compile time

2022-02-09 Thread Vindex via Digitalmars-d-learn
Will the loop (foreach) run at compile time? How can I make it 
work at compile time?


```
import std.csv, std.stdio;

alias Record = Tuple!(string, string, string);

immutable string[][] table;

shared static this() {
string csvText = import("file.csv");
foreach (record; csvReader!Record(csvText)) {
table ~= [record[0], record[1], record[2]];
}
}

void main() {
writeln(table):
}
```