Re: length's type.

2024-02-13 Thread Ivan Kazmenko via Digitalmars-d-learn

On Monday, 12 February 2024 at 19:56:09 UTC, H. S. Teoh wrote:
But regardless, IMNSHO any programmer worth his wages ought to 
learn what an unsigned type is and how it works. A person 
should not be writing code if he can't even be bothered to 
learn how the machine that's he's programming actually works.


I'd like to note that even C++20 onwards has `.ssize`, which is 
signed size.


I do use lengths in arithmetic sometimes, and that leads to 
silent bugs currently.  On the other hand, since going from 16 
bits to 32 and then 64, in my user-side programs, I had a flat 
zero bugs because some length was 2^{31} or greater -- but at the 
same time not 2^{32} or greater.  So, in D, I usually `to!int` or 
`to!long` them anyway.  Or cast in performance-critical places.


Another perspective.  Imagine a different perfect world, where 
programmers just had 64-bit integers and 64-bit address space, 
everywhere, from the start.  A clean slate, engineers and 
programmers designing their first hardware and languages, but 
with such sizes already feasible.  Kinda weird, but bear with me 
a bit.  Now, imagine someone proposing to make sizes unsigned.  
Wouldn't that be a strange thing to do?  The benefit of having a 
universal arithmetic type for everything, from the ground up -- 
instead of two competing types producing bugs at glue points -- 
seems to far outweigh any potential gains.  Unsigned integers 
could have their small place, too, for bit masks and 
microoptimizations and whatnot, but why sizes?  The few 
applications that really benefit from sizes of [2^{63}..2^{64}) 
would be the most odd ones, deserving some workarounds.


Right now though, we just have to deal with the legacy, in 
software, hardware, and mind -- and with the fact that quite some 
environments are not 64-bit.


Ivan Kazmenko.



Re: HTTP Post Body Parameters

2023-08-01 Thread Ivan Kazmenko via Digitalmars-d-learn

On Tuesday, 1 August 2023 at 23:57:29 UTC, Vahid wrote:
I want to submit a request to server with 
"x-www-form-urlencoded" header.


Isn't https://dlang.org/library/std/net/curl/post.html what you 
need?




Re: Breaking ";" rule with lambda functions

2022-08-01 Thread Ivan Kazmenko via Digitalmars-d-learn

On Monday, 1 August 2022 at 20:36:12 UTC, pascal111 wrote:
My complaint is about that a function is not a same as an 
expression that functions return values, but expressions being 
evaluated to provide values.


An analogy.

With a ternary expression, we write:
`x = (cond ? a : b);`
The traditional look of it is:
`if (cond) x = a; else x = b;`
Note how we have a semicolon after `x = a` in the latter form, 
but can't have it in the former.


Ivan Kazmenko.



vectorization of a simple loop -- not in DMD?

2022-07-11 Thread Ivan Kazmenko via Digitalmars-d-learn

Hi.

I'm looking at the compiler output of DMD (-O -release), LDC (-O 
-release), and GDC (-O3) for a simple array operation:


```
void add1 (int [] a)
{
foreach (i; 0..a.length)
a[i] += 1;
}
```

Here are the outputs: https://godbolt.org/z/GcznbjEaf

From what I gather at the view linked above, DMD does not use XMM 
registers for speedup, and does not unroll the loop either.  
Switching between 32bit and 64bit doesn't help either.  However, 
I recall in the past it was capable of at least some of these 
optimizations.  So, how do I enable them for such a function?


Ivan Kazmenko.



Re: d strings are the bane of my existance

2021-12-06 Thread Ivan Kazmenko via Digitalmars-d-learn

On Sunday, 5 December 2021 at 16:37:21 UTC, Chris Katko wrote:
Yes! Thank you! I just realized the latter part was broken when 
I switched to using a uint for the addr. But I didn't know 
string is an alias for immutable(char)[]! Thank you!


Yeah, a `const(char)[]` argument is designed to accept both 
`immutable(char)[]` (strings) and just `char[]` (mutable arrays 
of chars) for the arguments.


Ivan Kazmenko.


Re: Map of functions

2018-12-14 Thread Ivan Kazmenko via Digitalmars-d-learn
On Friday, 14 December 2018 at 15:38:49 UTC, Giovanni Di Maria 
wrote:

Hi
Is there an utility to print
the functions in a source file, for example:

- main()
--- calculate()
- print()
--- simulate()
- print()
.
Thank you very much
Giovanni Di Maria


Do you really have a nested function print() inside a nested 
function calculate() inside main()?  That is,


void main()
{
void calculate()
{
void print()
{
}
// maybe some calls to print()
}
// maybe some calls to calculate()
}

Or are you talking about the sequence in which function are 
*called*, and from where?  Please clarify.


Ivan Kazmenko.



Re: dmd64 on Windows: how?

2018-08-12 Thread Ivan Kazmenko via Digitalmars-d-learn

On Sunday, 12 August 2018 at 03:49:04 UTC, Mike Parker wrote:
On Saturday, 11 August 2018 at 19:50:30 UTC, Ivan Kazmenko 
wrote:
I've installed the components shown in wiki image: v141 tools 
and the SDKs.


VS 2017 Community includes everything you need. There's no 
reason to install the SDK separately. If it's installed first, 
the DMD installer will find it. The latest version will install 
the MinGW system libs and the lld linker if no VS installation 
is found. And for the past few versions, when you run dmd it 
will look for the VS installation as needed. So it should work 
out of the box without the need for the separate SDK or mucking 
about with the paths in sc.ini.


Is your VS 2017 the Community edition?


Yeah, I have VS 2017 Community Edition, and I was struggling 
trying to make 64-bit linking work, both with .7z archive and 
with .exe installer.


The .exe installer dmd-2.081.1.exe I've just tried again.
With default settings, it just installs into C:\D\ .
Its sc.ini is almost empty, no sign of Visual Studio environment 
variables or paths.


Then I run cmd.exe:

~
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\D>dmd2vars64.bat

Setting up 64-bit environment for using DMD 2 from 
C:\D\dmd2\windows\bin.


dmd must still be called with -m64 in order to generate 64-bit 
code.
This command prompt adds the path of extra 64-bit DLLs so 
generated programs

which use the extra DLLs (notably libcurl) can be executed.

C:\D>echo void main () {} > a.d

C:\D>dmd -m64 a.d
C:\D\dmd2\windows\bin\lld-link.exe: error: could not open 
libcmt.lib: no such fi

le or directory
Error: linker exited with status 1
~

My Windows version is Windows Server 2008 R2.
Microsoft Visual Studio Community 2017, version 15.7.6.
At C:\Program Files (x86), there are:
Microsoft Visual Studio[ 2754M ]
Microsoft Visual Studio 12.0   [   50M ]
Microsoft Visual Studio 14.0   [  954M ]
The latter two contain some remains of the previous 
installations, so that may be the issue with detecting the 
current Visual Studio version.


Ivan Kazmenko.



Re: dmd64 on Windows: how?

2018-08-11 Thread Ivan Kazmenko via Digitalmars-d-learn

Well, I tried all your suggestions.
(Actually re-tried a few times.)
Thanks, Laurent and Kagamin!

On Friday, 10 August 2018 at 14:47:04 UTC, Laurent Tréguier wrote:
Did you have a look at the wiki ? It looks like the image shows 
what needs to be installed:

https://wiki.dlang.org/Installing_DMD#Installing_the_Microsoft_toolchain


This was most close to solving my problem.  Thanks!

I've installed the components shown in wiki image: v141 tools and 
the SDKs.


The sc.ini information in the wiki looks outdated.
At least the sc.ini from the .7z archive is much cleaner than it 
used to be.

The whole 64-bit section looks like this:
~
[Environment64]
LIB=%@P%\..\lib64
; needed to avoid COMDAT folding (bugzilla 10664)
DFLAGS=%DFLAGS% -L/OPT:NOICF
~

So I proceeded with the wiki instructions:
to find and run a 64-bit Visual Studio command prompt,
to ask the environment variables from there.

And Visual Studio 2017 brings new tricky paths to handle.

Here is how my sc.ini 64-bit section looks now, when everything 
seems to work:

~
[Environment64]
LIB=%@P%\..\lib64
; needed to avoid COMDAT folding (bugzilla 10664)
DFLAGS=%DFLAGS% -L/OPT:NOICF

; here are the actual paths
VCINSTALLDIR=C:\Program Files (x86)\Microsoft Visual 
Studio\2017\Community\VC\

WindowsSdkDir=C:\Program Files (x86)\Windows Kits\10\
UniversalCRTSdkDir=C:\Program Files (x86)\Windows Kits\10\
UCRTVersion=10.0.17134.0

; here is the actual version
LINKCMD=%VCINSTALLDIR%\Tools\MSVC\14.14.26428\bin\HostX64\x64\link.exe

; needed with /DEBUG to find mspdb*.dll (only for VS2012 or later)
PATH=%PATH%;%VCINSTALLDIR%\bin\HostX64\x64
~

Specifically, LINKCMD part deviates from the instructions.
The linker is now buried deeper into 
\Tools\MSVC\14.14.26428\bin\HostX64\x64\.
Yep, that contains a version number too, which may change with 
each update.

Meanwhile, the tutorial suggests just the following:
LINKCMD=%VCINSTALLDIR%\bin\x86_amd64\link.exe

Anyway, now 64-bit linking seems to be working, so I'll stop 
digging.


Ivan Kazmenko.



dmd64 on Windows: how?

2018-08-10 Thread Ivan Kazmenko via Digitalmars-d-learn

Hi,

How should I set up DMD to be able to `dmd -m64` on Windows 
nowadays?


I usually download the 7z, but it broke when I replaced my Visual 
Studio with 2017 edition.


Now, I tried the current 2.081.1 .exe installer.  It didn't 
propose any additional 64-bit related options.  After the 
installation, `dmd -m64` complains that the linker could not find 
`libcmt.lib`.


The previous time I tried finding the right `libcmt` and treating 
the subsequent errors, I failed to locate all the correct 
libraries in Microsoft's Visual Studio and SDKs.  This time, I'd 
rather follow some up-to-date guide than waste the time again.


So, what's the most current guide to make 64-bit linking work on 
Windows?  I'm fine with having to install more LLVM or MinGW or 
Microsoft stuff, I just don't seem to know what I need.


Ivan Kazmenko.



Re: how to correctly populate an array of dynamic closures?

2018-03-29 Thread Ivan Kazmenko via Digitalmars-d-learn

On Thursday, 29 March 2018 at 15:38:14 UTC, ag0aep6g wrote:
<...> With immutable, this is certainly a problem. 
https://issues.dlang.org/show_bug.cgi?id=2043


Wow, such history for the bug!


Two possible workarounds:

int delegate () [] iuns;
foreach (i; 0..2) iuns ~= (j) { return () => j; } (i);
foreach (i; 0..2) writeln (iuns[i] ());  /* 0 and 1 */

static struct S
{
int i;
int m() { return i; }
}
int delegate () [] juns;
foreach (i; 0..2) juns ~= &(new S(i)).m;
foreach (i; 0..2) writeln (juns[i] ());  /* 0 and 1 */


Thank you ag0aep6g and Dennis for showing the possible 
workarounds!


On Thursday, 29 March 2018 at 15:47:33 UTC, Dennis wrote:
A delegate is a function with a pointer to the stack frame 
where it was created. It doesn't copy or insert the value of 
'i', it still refers to the very same location in memory as the 
i from the for-loop. After the for-loop, that value is 1, so 
all delegates refering to that i return 1. The solution is to 
generate a new local variable for each closure with a helper 
function:


So, basically, one has to create and call another function, or 
explicitly copy onto the heap, in order to ensure the copy of the 
loop variable is stored for the closure.
My (mis)understanding was that there's some additional magic 
happening for closures that get stored on the heap, as opposed to 
delegates used before their context goes out of scope.

As long as the whole story is that simple, fine.

Ivan Kazmenko.



how to correctly populate an array of dynamic closures?

2018-03-29 Thread Ivan Kazmenko via Digitalmars-d-learn

Here's a simplified example of what I want to achieve.

I first create funs, an array of two delegates.
I want funs[0] to always return 0 and funs[1] to always return 1.

By assigning the constants directly (see the code below), I 
achieve exactly that.
Now, I want to use a loop to assign the values, and this is where 
things stop working.


My first try is guns, populated with `foreach (i; 0..2) guns ~= 
() => i;`.

But both guns[0] and guns[1] return 1.

I tried to circumvent that by populating another array, huns, 
with functions returning immutable copies of the loop variable, 
but the effect was the same.


import std.stdio;
void main () {
int delegate () [] funs;
funs ~= () => 0;
funs ~= () => 1;
foreach (i; 0..2) writeln (funs[i] ());  // 0 and 1 as expected

int delegate () [] guns;
foreach (i; 0..2) guns ~= () => i;
foreach (i; 0..2) writeln (guns[i] ());  // 1 and 1, why?

int delegate () [] huns;
foreach (i; 0..2) {
immutable int j = i;
huns ~= () => j;
}
foreach (i; 0..2) writeln (huns[i] ());  // 1 and 1, why?
}

In my real use case, the delegates actually get stored in 
different structs or classes instead of a single array, and 
instead of returning 0 and 1, they call another function with 
argument 0 and 1, respectively.

Also, the number of delegates to create is known only at runtime.
However, I believe that won't be a problem once I grasp how to do 
this basic example.


So, why do delegates of guns[] and huns[] all return 1, and how 
to correctly reproduce the behavior of funs[] while populating it 
in a loop?


Ivan Kazmenko.



Re: Why 2 ^^ 1 ^^ 2 = 2?

2017-10-27 Thread Ivan Kazmenko via Digitalmars-d-learn

On Thursday, 26 October 2017 at 10:02:54 UTC, Kagamin wrote:

On Sunday, 22 October 2017 at 22:28:48 UTC, Ivan Kazmenko wrote:

Yeah, and a height-3 tower $a^{b^c}$ (TEX notation)


Is $a^{b^c}$ the same as ${a^b}^c$ ? They are drawn slightly 
differently, so I suppose it's ambiguous indeed.


Surely not the same.

"3 to the power of (3 to the power of 3)" is "3 to the power of 
27", or 7,625,597,484,987.
"(3 to the power of 3) to the power of 3" is "27 to the power of 
3", or 2187.


For an argument, the TEX command "^" accepts either a single 
character or a bracket-enclosed string of arbitrary length.  So 
$3^3^3$ indeed transforms to ${3^3}^3$, but not for some deeper 
reason this time.


Ivan Kazmenko.



Re: Why 2 ^^ 1 ^^ 2 = 2?

2017-10-22 Thread Ivan Kazmenko via Digitalmars-d-learn

On Sunday, 22 October 2017 at 14:44:04 UTC, Timon Gehr wrote:

On 22.10.2017 16:20, Ilya Yaroshenko wrote:

.. i thought it should be (2 ^^ 1) ^^ 2 = 4


2 ^^ (1 ^^ 2) == 2

It is standard for ^/**/^^ to be right-associative. (This is 
also the standard convention in mathematics.)


Yeah, and a height-3 tower $a^{b^c}$ (TEX notation) actually 
means "a to the power of (b to the power of c)", not the other 
way around.  Otherwise, it can be written as $a^{b \cdot c}$, 
which is only a height-2 tower.


The convention also makes at least the following sense.  An 
expression like

(((a ^^ b) ^^ c) ^^ d) ^^ e
already has an almost bracket-free notation as
a ^^ (b * c * d * e).
So it is useful to have a bracket-free way to write the 
other-way-associative variant,

a ^^ (b ^^ (c ^^ (d ^^ e))).

Ivan Kazmenko.



Re: floating point value rounded to 6digits

2017-09-19 Thread Ivan Kazmenko via Digitalmars-d-learn
On Tuesday, 19 September 2017 at 22:44:06 UTC, greatsam4sure 
wrote:
On Tuesday, 19 September 2017 at 21:52:57 UTC, Ivan Kazmenko 
wrote:
On Tuesday, 19 September 2017 at 20:47:02 UTC, greatsam4sure 
wrote:

double  value = 20.89766554373733;
writeln(value);
//Output =20.8977

How do I output the whole value without using writfln,write 
or format. How do I change this default


The default when printing floating-point numbers is to show 
six most significant digits.
You can specify the formatting manually with writefln, for 
example,


writefln ("%.10f", value);

will print the value with 10 digits after the decimal point.
The writef/writefln function behaves much like printf in C.

See here for a reference on format strings:
https://dlang.org/library/std/format/formatted_write.html#format-string

Ivan Kazmenko.


I don't  want to use write,writefln or format. I just want to 
change the default


Unlikely to be possible.  The built-in data types, such as float 
or double, by definition should not be customizable to such 
degree.


Anyway, under the hood, write uses format with the default format 
specifier "%s" for the values it takes.  So perhaps I'm not quite 
getting what exactly are you seeking to avoid.


For example, consider a helper function to convert the values, 
like the following:


import std.format, std.stdio;
string fmt (double v) {return v.format !("%.10f");}
void main () {
double x = 1.01;
writeln (x.fmt); // 1.01
}

Alternatively, you can wrap your floating-point numbers in a thin 
struct with a custom toString():


import std.format, std.stdio;
struct myDouble {
double v;
alias v this;
this (double v_) {v = v_;}
string toString () {return v.format !("%.10f");}
}
void main () {
myDouble x = 1.01, y = 2.02, z = x + y;
writeln (z); // 3.03
}

Ivan Kazmenko.



Re: floating point value rounded to 6digits

2017-09-19 Thread Ivan Kazmenko via Digitalmars-d-learn
On Tuesday, 19 September 2017 at 20:47:02 UTC, greatsam4sure 
wrote:

double  value = 20.89766554373733;
writeln(value);
//Output =20.8977

How do I output the whole value without using writfln,write or 
format. How do I change this default


The default when printing floating-point numbers is to show six 
most significant digits.
You can specify the formatting manually with writefln, for 
example,


writefln ("%.10f", value);

will print the value with 10 digits after the decimal point.
The writef/writefln function behaves much like printf in C.

See here for a reference on format strings:
https://dlang.org/library/std/format/formatted_write.html#format-string

Ivan Kazmenko.



Re: writeln() sometimes double prints from main() if I run a thread checking for input?

2017-08-31 Thread Ivan Kazmenko via Digitalmars-d-learn
On Thursday, 31 August 2017 at 14:43:39 UTC, Steven Schveighoffer 
wrote:
Just a thought, but the "double printing" could be a 
misunderstanding. It could be printing Output\nOutput2, but not 
getting the 2 out there.


No no, it's four lines instead of three.  If we change the lines 
to disjoint sets of letters, the problem persists.


Note that DMD 32-bit is using DMC libc. It might be that it 
gets hung up somehow when expecting input, like it locks the 
console somehow.


I would say that byLineCopy puts the thread to sleep waiting 
for input, and it doesn't get out of that state. So it could be 
that the bug only appears when it gets to that state at some 
point in the output. I'd pepper some sleeps around the outputs 
to see if you can make the context switches more predictable.


Inserting different sleeps into the threads makes the problem go 
away (cannot reproduce).  Inserting identical sleeps produces the 
error with roughly the same probability.


Anyway, I've reported it 
(https://issues.dlang.org/show_bug.cgi?id=17797), along with a 
more or less exact version (2.073.2) where the problem was 
introduced.


Ivan Kazmenko.



Re: writeln() sometimes double prints from main() if I run a thread checking for input?

2017-08-31 Thread Ivan Kazmenko via Digitalmars-d-learn

On Wednesday, 30 August 2017 at 13:33:06 UTC, Ivan Kazmenko wrote:
Interesting.  As to what to do with it, no idea for now.  At 
the very least we can issue a bug report, now that at least two 
people can reproduce it, so it is unlikely to be 
environment-dependent.


Reported: https://issues.dlang.org/show_bug.cgi?id=17797 .



Re: writeln() sometimes double prints from main() if I run a thread checking for input?

2017-08-30 Thread Ivan Kazmenko via Digitalmars-d-learn

On Wednesday, 30 August 2017 at 13:24:55 UTC, Ivan Kazmenko wrote:
On Wednesday, 30 August 2017 at 10:55:20 UTC, Timothy Foster 
wrote:

import std.stdio, core.thread;

void main(){
auto thread = new Thread().start;
writeln("Output");
writeln("Output2");
writeln("Output3");
while(true){}
}

void func(){
foreach(line; stdin.byLineCopy){}
}


I also cannot reproduce this.

My current system is Win7 64-bit.  I tried 32-bit dmd 2.072.0 
and 2.075.1, with optimizations turned on and off, but it 
prints correctly tens of times in each case.


Try running the program in a bare console (cmd.exe on Windows, 
or some *sh on Linux).  If the problem goes away, your usual 
environment is likely at fault.  If not,.. well, no idea for 
now.


Hey, I followed my own advice and do see the same issue! when:
1. compiling with dmd 2.075.1 (optimization switches seem to be 
irrelevant but the issue does not reproduce with 2.072.0),

2. running in a bare cmd.exe, and
3. running the program as just "a.exe", so that it waits for 
console input (previously I redirected some input to it, like 
"a.exe 

Re: writeln() sometimes double prints from main() if I run a thread checking for input?

2017-08-30 Thread Ivan Kazmenko via Digitalmars-d-learn
On Wednesday, 30 August 2017 at 10:55:20 UTC, Timothy Foster 
wrote:

import std.stdio, core.thread;

void main(){
auto thread = new Thread().start;
writeln("Output");
writeln("Output2");
writeln("Output3");
while(true){}
}

void func(){
foreach(line; stdin.byLineCopy){}
}


I also cannot reproduce this.

My current system is Win7 64-bit.  I tried 32-bit dmd 2.072.0 and 
2.075.1, with optimizations turned on and off, but it prints 
correctly tens of times in each case.


Try running the program in a bare console (cmd.exe on Windows, or 
some *sh on Linux).  If the problem goes away, your usual 
environment is likely at fault.  If not,.. well, no idea for now.


Ivan Kazmenko.



Re: writeln() sometimes double prints from main() if I run a thread checking for input?

2017-08-30 Thread Ivan Kazmenko via Digitalmars-d-learn
On Wednesday, 30 August 2017 at 10:13:57 UTC, Timothy Foster 
wrote:
I'm not sure if this is a known issue, or if I just don't 
understand how to use threads, but I've got writeln statements 
sometimes printing out twice in some areas of my code.

<...>
Does anyone know what is causing this or how I can fix it?


Difficult to say by what you posted.

You may want to provide a complete example so that others may try 
to reproduce it.  Additionally, as you gradually simplify your 
code until it is small enough to post here, or on DPaste, you may 
find the cause faster yourself.


Ivan Kazmenko.



Re: Get complete function declaration

2017-07-18 Thread Ivan Kazmenko via Digitalmars-d-learn

On Tuesday, 18 July 2017 at 13:35:49 UTC, SrMordred wrote:
There is a way to get the full function(or any other structure) 
declaration with traits? Or I will have to mount it with 
std.traits functions?


eg.
void add(int x, int y){}

GetFullFunctionDeclaration!add; //return "void add(int x, int 
y)"


There are several function traits in std.traits (see 
https://dlang.org/phobos/std_traits.html), which can hopefully be 
combined to reconstruct a function declaration.


I don't see a single method which would do what you want out of 
the box.  Perhaps there is none, since different use cases would 
require different small subsets of features, and all the 
orthogonal features are already available.


Ivan Kazmenko.



Re: Avoid if statements for checking neighboring indexes in a 2D array

2017-07-17 Thread Ivan Kazmenko via Digitalmars-d-learn

On Monday, 17 July 2017 at 07:14:26 UTC, Andrea Fontana wrote:


Probably using ndslice library could help you!


Unfortunately, that's not possible on most online contest 
platforms like Codeforces.  For each programming language and 
compiler available, only the most basic package is usually 
installed on the server.  There is a mix of reasons involved 
(historical, maintenance, choice of libraries, more equality for 
different languages, etc.).  That means, e.g., no numpy for 
Python, no Boost for C++, and no third-party libraries for D.


Ivan Kazmenko.



Re: Avoid if statements for checking neighboring indexes in a 2D array

2017-07-17 Thread Ivan Kazmenko via Digitalmars-d-learn

On Sunday, 16 July 2017 at 21:50:19 UTC, kerdemdemir wrote:


Process(row-1,column-1, maxrow, maxcolumn);
Process(row,column-1, maxrow, maxcolumn);
Process(row+1,column-1, maxrow, maxcolumn);
Process(row-1,column, maxrow, maxcolumn);
Process(row+1,column, maxrow, maxcolumn);
Process(row-1,column+1, maxrow, maxcolumn);
Process(row,column+1, maxrow, maxcolumn);
Process(row-1,column+1, maxrow, maxcolumn);


One of "row-1,column+1" should actually be "row+1,column+1".  
That's where the mentioned ways help.


As for the problem itself, it can be solved without finding 
connected components.  I won't post the solution right away 
because it is potentially a spoiler.  See 
http://codeforces.com/blog/entry/53268 for problem analysis 
(828B) and http://codeforces.com/contest/828/submission/28637184 
for an example implementation in D.


Ivan Kazmenko.



Re: Avoid if statements for checking neighboring indexes in a 2D array

2017-07-16 Thread Ivan Kazmenko via Digitalmars-d-learn

On Sunday, 16 July 2017 at 10:37:39 UTC, kerdemdemir wrote:
My goal is to find connected components in a 2D array for 
example finding connected '*'

chars below.

  x x x x x x
  x x x x x x
  x x * * x x
  x x * * x x
  x x x * * x
  * x x x x x



...


Is there any better way to achieve this with cool std functions 
like enumerate or iota without needing to write eight if checks?


I don't know of a library facility to do this.

Still, there is a language-agnostic way to make it more concise.  
Instead of repeating eight similar blocks, define an array of 
delta-rows and delta-columns to neighboring cells, and use that 
array in a loop.  A complete example follows:


-
import std.algorithm, std.array, std.range, std.stdio;

immutable int dirs = 8;
immutable int [dirs] dRow = [-1, -1, -1,  0, +1, +1, +1,  0];
immutable int [dirs] dCol = [-1,  0, +1, +1, +1,  0, -1, -1];

char [] [] arr;

int componentSizeRecur (int row, int col)
{
int res = 1;
arr[row][col] = 'x';
foreach (dir; 0..dirs)
{
auto nRow = row + dRow[dir];
auto nCol = col + dCol[dir];
if (arr[nRow][nCol] == '*')
res += componentSizeRecur (nRow, nCol);
}
return res;
}

void main ()
{
arr = ["xxx",
   "*xx",
   "xx**xxx",
   "xx**x*x",
   "xxx",
   ].map !(line => line.dup).array;

foreach (row; 0..arr.length)
foreach (col; 0..arr.front.length)
if (arr[row][col] == '*')
writeln (componentSizeRecur (row, col));
}
-

If the neighbors array is regular and known in advance (like, 4 
edge-connected cells, or 8 corner-connected cells as here), you 
may also like to loop over possible deltas and pick the good 
ones, like below:


-
int componentSizeRecur (int row, int col)
{
int res = 1;
arr[row][col] = 'x';
foreach (dRow; -1..+2)
foreach (dCol; -1..+2)
if (dRow || dCol)
{
auto nRow = row + dRow;
auto nCol = col + dCol;
if (arr[nRow][nCol] == '*')
res += componentSizeRecur (nRow, nCol);
}
return res;
}
-

I have to make two additional notes.

1. This works only if the border does not contain '*' characters. 
 To make it work without that restriction, either add two 
sentinel rows and columns at the four borders of the array, or 
put an if on nRow and nCol before using them.


2. The recursive solution can eat up lots of stack.  If you 
intend using it on large arrays, make sure you don't hit the 
stack size limit of the environment.  On Windows, it can be 
achieved by a compiler switch like "-L/STACK:268435456".  On 
Linux, the "ulimit" command may help.


Ivan Kazmenko.



Re: implib.exe no output files

2017-06-21 Thread Ivan Kazmenko via Digitalmars-d-learn

On Monday, 19 June 2017 at 23:11:29 UTC, Joel wrote:

On Sunday, 18 June 2017 at 09:48:31 UTC, Ivan Kazmenko wrote:

On Sunday, 18 June 2017 at 07:41:27 UTC, Joel wrote:

I got the file here: http://ftp.digitalmars.com/bup.zip

It works on other computers.

I was trying to update to the latest DAllegro 
(https://github.com/SiegeLord/DAllegro5).


Though, I used another computer for the lib files and still 
couldn't get the latest DAllegro5 working.


The .bat files in https://github.com/SiegeLord/DAllegro5 work 
fine for me.


Could you please be more specific about what exactly you are 
doing, and what went wrong?


Keep in mind that you need Allegro binaries (e.g. from 
http://liballeg.org/download.html#windows) to use implib.


Ivan Kazmenko.


I have the dll's in the same directory where I run the create 
lib .bat file. It displays the normal stuff, but no lib files!


I'm wondering if implib needs to be worked on.


Sorry, that's still not specific enough.

I've just tested this in a fresh directory:
1. Get https://github.com/SiegeLord/DAllegro5
2. Get 
https://github.com/liballeg/allegro5/releases/download/5.2.2.0/allegro-mingw-gcc6.2.0-x86-static-5.2.2.zip
3. Put, for example, allegro-5.2.dll from the archive to 
DAllegro5 directory.

4. Run create_import_libs.bat, here is the output:
-
...>rem This batch file creates import dlls in the current folder 
and strips the version number

...>rem because OPTLINK sucks.
Digital Mars Import Library Manager Version 7.6B1n
Copyright (C) Digital Mars 2000.  All Rights Reserved.
Input is a Windows NT DLL file 'allegro-5.2.dll'.
Output is a Windows NT import library.
Digital Mars Import Library Creator complete.
-
5. Now I got allegro.lib in the directory.

Which of these steps fails for you, and how?

Ivan Kazmenko.



Re: implib.exe no output files

2017-06-18 Thread Ivan Kazmenko via Digitalmars-d-learn

On Sunday, 18 June 2017 at 07:41:27 UTC, Joel wrote:

I got the file here: http://ftp.digitalmars.com/bup.zip

It works on other computers.

I was trying to update to the latest DAllegro 
(https://github.com/SiegeLord/DAllegro5).


Though, I used another computer for the lib files and still 
couldn't get the latest DAllegro5 working.


The .bat files in https://github.com/SiegeLord/DAllegro5 work 
fine for me.


Could you please be more specific about what exactly you are 
doing, and what went wrong?


Keep in mind that you need Allegro binaries (e.g. from 
http://liballeg.org/download.html#windows) to use implib.


Ivan Kazmenko.



Re: Help with an algorithm!

2017-06-15 Thread Ivan Kazmenko via Digitalmars-d-learn

On Thursday, 15 June 2017 at 13:41:07 UTC, MGW wrote:
On Thursday, 15 June 2017 at 13:16:24 UTC, CRAIG DILLABAUGH 
wrote:


The purpose - search of changes in file system.
Sorting is a slow operation as well as hashing. Creation of a 
tree, is equally in sorting.

So far the best result:

foreach(str; m2) {
bool fFind; int j;
foreach(int i, s; m1) {
if(str == s) { fFind = true; j = i; break; }
}
if(!fFind) { rez ~= str; }
else   {m1[j] = m1[$-1]; m1.length = m1.length - 1; }
}


Ugh.  This can work as slow as length-of-m1 *multiplied* by 
length-of-m2.  For 5,000,000 strings, it is 5,000,000 * 5,000,000 
= 25,000,000,000,000.  Granted, if you run it very often, the 
arrays are almost equal, and it's closer to linear.  But once 
there are substantial changes between two consecutive runs, this 
approach is seriously screwed.


Sorting would work in length-of-array * log(length-of-array).  
For 5,000,000 strings, it is 5,000,000 * 23 = 115,000,000.  This 
is ~217,391 times better than your method above.  May be a bit 
slower because of long common prefixes.  Anyway, a couple of 
seconds at most.  How fast you need it to be?  Did you actually 
try it?


Ivan Kazmenko.



Re: Help with an algorithm!

2017-06-15 Thread Ivan Kazmenko via Digitalmars-d-learn

On Thursday, 15 June 2017 at 06:06:01 UTC, MGW wrote:
There are two arrays of string [] mas1, mas2; Size of each 
about 5M lines. By the size they different, but lines in both 
match for 95%. It is necessary to find all lines in an array of 
mas2 which differ from mas1. The principal criterion - speed. 
There are the 8th core processor and it is good to involve a 
multithreading.


The approaches which come to mind are:

1. Sort both arrays, then traverse them in sorted order, like in 
merge step of merge sort:


sort (mas1);
sort (mas2);

size_t index1 = 0;
foreach (str2; mas2)
{
while (index1 < mas1.length && mas1[index1] < str2)
index1 += 1;
if (mas1[index1] != str2)
writeln (str2);
}

Sorting takes O (n log n * c) time, where n is the size of the 
arrays, and c is the expected time of two strings comparison when 
sorting.  The subsequent step is O (n * c) which is faster than 
sorting.


2. Hashing.  Just put the contents of the first array into a bool 
[string], and then, for each string from the second array, check 
whether it is contained in the associative array.  The time will 
be O (total length of all strings) multiplied by a moderate 
constant, unless the strings are designed specifically to 
generate hash collisions, in which case it will be slower.


3. Trie.  Similar to hashing, but the constant multipliers will 
be much higher unless the strings have large common prefixes.


Whether we can do faster depends on context.  For example, if the 
strings tend to all have long common prefixes, any string 
comparison will be slow, but otherwise it can be thought of as 
taking constant time.


Ivan Kazmenko.



Re: DMD [-O flag] vs. [memory allocation in a synchronized class]

2017-06-08 Thread Ivan Kazmenko via Digitalmars-d-learn

On Thursday, 8 June 2017 at 15:35:06 UTC, Ivan Kazmenko wrote:
Perhaps a regression should be filed, or searched for, at 
issues.dlang.org.  I can do it, but not right now, and would be 
glad if someone beats me to it.


Reported: https://issues.dlang.org/show_bug.cgi?id=17481



Re: DMD [-O flag] vs. [memory allocation in a synchronized class]

2017-06-08 Thread Ivan Kazmenko via Digitalmars-d-learn

On Thursday, 8 June 2017 at 11:41:40 UTC, realhet wrote:

I've managed to narrow the problem even more:

//win32 dmd -O

class Obj{
  synchronized void trigger(){ new ubyte[1]; }
}

void main(){
  auto k = new shared Obj;
  k.trigger;
}

This time I got a more sophisticated error message:

object.Error@(0): Access Violation

0x7272456D in SymInitialize
0x00402667
0x00402A97
0x00402998
0x004022A0
0x76F13744 in BaseThreadInitThunk
0x773B9E54 in RtlSetCurrentTransaction
0x773B9E1F in RtlSetCurrentTransaction


I can reproduce this under win32, and it breaks somewhere between 
2.068.2 and 2.069.0.


The move instructive message with "dmd -O -g":

object.Error@(0): Access Violation

0x0065
0x00402C33 in _d_newarrayU
0x004022EB in _d_newarrayT
0x00402A7F in scope void rt.dmain2._d_run_main(int, char**, 
extern (C) int function(char[][])*).runAll()

0x00402980 in _d_run_main
0x00402288 in main at C:\a.d(8)
0x757F336A in BaseThreadInitThunk
0x77409902 in RtlInitializeExceptionChain
0x774098D5 in RtlInitializeExceptionChain

Perhaps a regression should be filed, or searched for, at 
issues.dlang.org.  I can do it, but not right now, and would be 
glad if someone beats me to it.


Ivan Kazmenko.



Re: Rosetta Commatizing numbers

2017-06-01 Thread Ivan Kazmenko via Digitalmars-d-learn

On Thursday, 1 June 2017 at 08:45:23 UTC, Solomon E wrote:

On Wednesday, 31 May 2017 at 15:44:51 UTC, Ivan Kazmenko wrote:



So, two custom calls, two minor changes, no sweat.  Is 
everything right now?  Even if not: that was fast, we can do 
another iteration.  When we have a short readable solution 
with no special cases, the first few changes are going to be 
easy.






Ivan Kazmenko.


I followed that advice, and found and fixed more bugs that were 
lurking in the original and in my complications. When the 
number begins with a decimal point, that's an edge case none of 
the earlier versions were handling right. I added a regression 
test for that.


I just posted my latest version at Rosetta, without the 
unnecessary complications. I hope you like it better.


http://rosettacode.org/wiki/Commatizing_numbers#D

(The complications weren't totally useless though. Without 
trying the complications, I wouldn't have tested enough to make 
as much improvement as I have. Overcomplicated features are 
something to avoid releasing, except in a repo folder of extras 
for other programmers to try fiddling with, and Rosetta code 
isn't exactly that.)


I very much like the current version.  It is concise, has no 
arbitrary constants in implementation, and does the job better 
than the version before your edits.


As for commatizeSpec (which is currently removed), I still 
believe it is too magically specialized to be useful.  But as 
long as vanilla commatize is available, I'd see commatizeSpec as 
just a way to run the tests, and be fine with it.


Thank you for bearing with me, and being a better listener than I 
am.


Ivan Kazmenko.



Re: Rosetta Commatizing numbers

2017-05-31 Thread Ivan Kazmenko via Digitalmars-d-learn

On Wednesday, 31 May 2017 at 13:27:24 UTC, Solomon E wrote:

Fine, by the numbers:

1. pi has the commas start at the wrong digit, and doesn't 
follow the explicit instructions to use spaces as the separator 
and a grouping of 5


Can be solved by calling the function with a right set of 
parameters: start = 6 and step = 5.  That's what function 
parameters are for.


Here, I understand that a real-world solution would try to center 
around the decimal point.  There are, however, two reasons not to 
do so.  First, it is not required in the problem statement.  
Second, the solutions in other languages don't interpret the 
statement like that, and instead, just add a parameter to start 
reading from a certain point.  Remember that one of the main 
purposes of Rosettacode is to provide a translation from one 
language to another.  There are other places on the web for 
solving the problems in the best possible way.


2. There are no newlines (although the input is the list of 
lines to be "commatized" not concatenated.)


write -> writeln

3. Zimbabwe dollars are given commas, against the explicit 
request to have dots. (That would be undesirable in the real 
world, not just in this silly example, because comma is used as 
a decimal point in the Zimbabwe press, and spaces for thousands 
separators.)


Can be solved by calling the function with a right set of 
parameters: ins = '.'.  That's what function parameters are for.



4. The second number in the line
===US$0017,440 millions=== (in 2,000 dollars)
is "commatized" which is against the explicit instructions to 
"commatize" the first number only, given in the task 
description and explained on the task's talk page.


replaceAll -> replaceFirst

5. The exponent in 123.e8000 is "commatized" which is against 
explicit and repeated instructions not to "commatize" exponents.


replaceAll -> replaceFirst


6. (The commas in the Eddington number are acceptable enough.)


OK.

7. The year in 6/9/1946 is "commatized" against explicit 
instructions to "commatize" only the first number field. It was 
discussed in the task's talk page that years shouldn't be 
commatized, and that's easy to avoid by never "commatizing" 
past the first number.


replaceAll -> replaceFirst

So, two custom calls, two minor changes, no sweat.  Is everything 
right now?  Even if not: that was fast, we can do another 
iteration.  When we have a short readable solution with no 
special cases, the first few changes are going to be easy.


For the Eddington number, the task didn't explicitly state to 
use spaces in that long a number, but the task does say there 
should be spaces in the digits of pi, which leaves open to 
interpretation whether that's a special request or a rule that 
could apply to any sufficiently long number, AND the task 
includes a reference to a Wikipedia page on the number that 
does use spaces.


Here, I'd say you are greatly overthinking the problem.

The other language solutions to Rosetta tasks may be 
"inspirational" in some ways, but there are also errors in 
them, at least for this task, that would be found if they were 
fully tested. They're made by human beings, and Rosetta code is 
just a game. It's not something that's been around as long as 
the older languages used there have existed, to look up to 
solutions in old languages with awe as time-worn and carved in 
stone.


If you see a problem, ~10 solutions, and think all of them have 
serious issues, you may well be right.  But it is also likely 
that all other solution authors read the problem differently.  
Which leaves an open formal question whether you are reading it 
correctly.  As well as an open informal question whether 
enforcing your reading is a good goal, keeping in mind that 
Rosettacode is a collection of translations.


-

If you still insist you are doing the right thing and all others 
are wrong, let's agree to disagree on that, and please just leave 
the original solution there by introducing two versions.


Ivan Kazmenko.



Re: Rosetta Commatizing numbers

2017-05-30 Thread Ivan Kazmenko via Digitalmars-d-learn

On Wednesday, 31 May 2017 at 04:31:14 UTC, Ivan Kazmenko wrote:


Now, where is the old version wrong? ...


Actually, it also changes every number in the string, not only 
the first one as required.  Because of that, it also fails the 
"do not touch the exponent" requirement.  Sadly, both are not 
covered by the examples.


The program is perhaps easily fixed by changing replaceAll into 
replaceFirst.  As for adding examples to better check the 
requirements, I don't know Rosettacode's policy for that.




Re: Rosetta Commatizing numbers

2017-05-30 Thread Ivan Kazmenko via Digitalmars-d-learn

On Tuesday, 30 May 2017 at 10:54:49 UTC, Solomon E wrote:
I ran into a Rosetta code solution in D that had obvious 
errors. It's like the author or the previous editor wasn't even 
trying to do it right, like a protest against how many detailed 
rules the task had. I assumed that's not the way we want to do 
things in D.

...
Does anyone have any thoughts about this? Did I do right by D?


I'd say the previous version (by bearophile) suited the task much 
better, but both aren't perfect.


As a general note, consider the following paragraph of the 
problem statement:


"Some of the commatizing rules (specified below) are arbitrary, 
but they'll be a part of this task requirements, if only to make 
the results consistent amongst national preferences and other 
disciplines."


This literally means that, while there are complex rules in the 
real world for commatizing numbers, the problem is kept simple by 
enforcing strict rules.  The minute concerns of the Real World, 
like "Current New Zealand dollar format overrides old Zimbabwe 
dollar format", are irrelevant to the formal problem being 
solved.  Perhaps the example inputs section ("Strings to be used 
as a minimum") gets misleading, but that's what they are: 
examples, not general rules.  By the way, as it's a wiki page, 
problem statement text could also be improved ;) .


Why?  For example, look at Indian numbering system where 
commatizing is visibly different 
(https://en.wikipedia.org/wiki/Indian_numbering_system) - and we 
don't know whether the string should use it or not without the 
context.  Or consider that hexadecimal numbers are usually split 
in groups of four digits, not three - and we don't know whether a 
[0-9]+ number is decimal or hexadecimal without the context.  
See, trying to provide an ultimate solution to real-world 
commatizing, while keeping it a single function without the 
context, can't possibly succeed.


What can be done, then?  Well, the page authors already did the 
difficult part for us: they extracted the essence of a complex 
real-world problem into a small set of formal rules, which are 
now the formal problem statement.  Now comes the easy part: to do 
exactly what is asked in the problem statement.  The flexibility 
comes from having function parameters.  If we have a solution to 
a formal problem, using it for the real-world version of the 
problem is either just specifying the right parameters 
(hopefully), or changing the function if the real world gets too 
complex for it.  In the latter case, the more short and readable 
the existing solution is, the faster can we change the function 
to suit our real-world case.


-

Now, where is the old version wrong?  Turns out it just calls the 
function with default parameters for every line of input - which 
is wrong since the first two input lines need to be handled 
specially.  Well, that's what the function parameters are for.  
To have a correct solution, we have to use custom parameters for 
the first two lines of input.  The function itself is fine.


Your solution addresses this problem by special-casing the inputs 
inside the function, perhaps because of the misleading inputs 
section in the problem statement.  That's a wrong approach.  
First, it introduces magic numbers 33 and 36 into the code, which 
is a bad programming practice (see here: 
https://en.wikipedia.org/wiki/Magic_number_(programming)#Unnamed_numerical_constants).  Second, it's plain wrong.  According to the problem statement, we don't have these rules for every possible line of >33 standalone decimals, or >36 characters in total.  We just have to call our function with a concrete set of custom parameters for one concrete example, and other set of parameters for another example.  That's to demonstrate that our function accepts and makes proper use of custom parameters!  Special-casing example inputs inside the function is not a solution: if we go down this path, the perfect solution would be a bunch of "if" statements for every possible example input producing the respective example outputs, and empty function for all other possible inputs.


So, how do we call with special parameters?  Currently, we can 
look at every other language except C# as inspiration: ALGOL 68, 
J, Java, Perl 6, Phix, Racket, and REXX.  Your solution also has 
a good way to check example inputs: a unittest block.  It even 
shows one of D's strengths compared to other languages.  And 
there, you do use custom parameters to check that the function 
works.  A good approach would be to put all the examples in the 
unittest instead of reading them from a file.  This way, the 
program will be immediately usable and runnable: no need to 
create an additional arbitrarily-named file just to test it.


-

All in all, the only thing I'd change in bearophile's solution is 
to remove the file reading loop, add the unittest block from your 
solution instead, and place all the examples there.  Printing the 
result does not 

Re: How to avoid throwing an exceptions for a built-in function?

2017-05-10 Thread Ivan Kazmenko via Digitalmars-d-learn

On Wednesday, 10 May 2017 at 12:40:41 UTC, k-five wrote:
I have a line of code that uses "to" function in std.conv for a 
purpose like:


int index = to!int( user_apply[ 4 ] ); // string to int

When the user_apply[ 4 ] has value, there is no problem; but 
when it is empty: ""
it throws an ConvException exception and I want to avoid this 
exception.


currently I have to use a dummy catch:
try{
index = to!int( user_apply[ 4 ] );
} catch( ConvException conv_error ){
// nothing
}

I no need to handle that, so is there any way to prevent this 
exception?


I assume that an empty string is a valid input then.
The question is, what value do you want `index` to have when the 
string is empty?

Maybe the old value, or some constant?
In any case, to better express your intent, you may write 
something like:


if (user_apply[4] != "")
{
index = to !(int) (user_apply[4]);
}
else
{
index = ...;  // specify whatever your intent is
}

This way, the code is self-documenting, and the program still 
throws when `user_apply[4]` is neither empty nor an integer, 
which may be the right thing to do in the long run.


Ivan Kazmenko.



Re: Problem with using readln.

2017-04-30 Thread Ivan Kazmenko via Digitalmars-d-learn

On Sunday, 30 April 2017 at 02:07:48 UTC, JV wrote:
Hello i'm kinda new to D language and i wanted to make a simple 
program
but somehow my input does no go to my if statements and just 
continues to ask for the user to input.Kindly help me


One way would be:

import std.stdio;
int x;
readf (" %s", );

The "%s" means "default format for the type", which is I believe 
"%d" (decimal) for the int type.  The space before "%s" is to 
skip all whitespace before the actual input, it will matter when 
you read your second integer:


readf ("%s%s", , ); // error, got space for y instead of 
a digit

readf ("%s %s", , ); // ok

Another way is:

import std.conv, std.stdio, std.string;
int x = readln.strip.to!int;

Here, we read the line with readln, strip the trailing whitespace 
with strip, and convert the resulting string to an int with 
to!int.


Also, you might want to look at the corresponding chapter in Ali 
Cehreli's book:

http://ddili.org/ders/d.en/input.html

Ivan Kazmenko.



Re: Can you read the next line while iterating over byLine?

2017-02-04 Thread Ivan Kazmenko via Digitalmars-d-learn

On Thursday, 2 February 2017 at 19:34:37 UTC, John Doe wrote:
Thanks readln is perfect. Since I am calling readln in 
different places and I always need to remove the newline 
character I have line=line[0..$-1] all over my code. Is there 
are better way?


"readln.strip" gives the line without the trailing newline 
character.




Re: Associative array literal: length wrong when duplicate keys found

2017-02-02 Thread Ivan Kazmenko via Digitalmars-d-learn

On Tuesday, 31 January 2017 at 19:45:33 UTC, Ivan Kazmenko wrote:

On Tuesday, 31 January 2017 at 17:20:00 UTC, John Colvin wrote:
It's a bug, please report it. The initializer should be 
statically disallowed.


Anyway, I'll file a bug report.


Hmm, found it:  https://issues.dlang.org/show_bug.cgi?id=15290

I'll add details about my use case to the report, for what it's 
worth.




Re: Associative array literal: length wrong when duplicate keys found

2017-01-31 Thread Ivan Kazmenko via Digitalmars-d-learn

On Tuesday, 31 January 2017 at 17:20:00 UTC, John Colvin wrote:
It's a bug, please report it. The initializer should be 
statically disallowed.


Adding a .dup works around the problem.


OK.  Hmm, but the real use case was a bit more complicated, more 
like:


-
int n = 10;
foreach (i; 0..n)
foreach (j; 0..n)
foreach (k; 0..n)
... and maybe a couple more ...
if ([i: true, j: true, k: true].length == 3)
{...} // i, j, k is a set of distinct values
-

Here, we don't know i, j and k statically, yet the problem is the 
same.


Anyway, I'll file a bug report.

By the way, you can do sets like this, avoiding storing any 
dummy values, only keys:


struct Set(T)
{
void[0][T] data;

void insert(T x)
{
data[x] = (void[0]).init;
}

void remove(T x)
{
data.remove(x);
}

bool opBinaryRight(string op : "in")(T e)
{
return !!(e in data);
}

// other things like length, etc.
}

unittest
{
Set!int s;
s.insert(4);
assert(4 in s);
s.remove(4);
assert(4 !in s);
}


Yeah, thanks for the recipe!  I usually do bool [key] since it 
does not add much overhead, but would definitely like the real 
set (void[0] or otherwise) when performance matters.


Ivan Kazmenko.



Re: Partial arrays reclaimed?

2017-01-31 Thread Ivan Kazmenko via Digitalmars-d-learn

On Friday, 27 January 2017 at 23:22:17 UTC, Nick Sabalausky wrote:

Suppose an array is being used like a FIFO:

---
T[] slice;

// Add:
slice ~= T();

// Remove:
slice = slice[1..$];
---

Assuming of course there's no other references to the memory, 
as this gets used, does the any of the memory from the removed 
elements ever get GC'd?


As I see it, the line
slice = slice[1..$];
effectively ends slice's in-place appending capabilities.  So 
each append after remove will likely reallocate.  You have to use 
assumeSafeAppend to re-enable appending in place.


Here [1] is an old thread about the caveats of using built-in 
arrays as queues and stacks.  If not in a hurry, the better 
option is perhaps to just write the respective wrapper structs 
which explicitly store indices, instead of using built-in slices 
and assumeSafeAppend all over the place.


Ivan Kazmenko.

[1] 
http://forum.dlang.org/post/yrxspdrpusrrijmfy...@forum.dlang.org




Associative array literal: length wrong when duplicate keys found

2017-01-31 Thread Ivan Kazmenko via Digitalmars-d-learn

Hi.

I wanted to check whether a few variables of the same type are 
all distinct, in a quick and dirty way.  I tried to do it similar 
to Python's "len(set(value_list)) == len(value_list)" idiom by 
using an associative array (AA).  At this point, I found out that 
when initializing the AA with a literal, the length is the number 
of keys given, regardless of whether some of them were the same.


A minimized example:

-
import std.stdio;
void main () {
auto aa = [1 : 2, 1 : 3];
writeln (aa.length, " ", aa); // 2 [1:3, ]
}
-

See, the length is 2, but iteration over aa yields only one 
key:value pair.  Also, note the comma which is a sign of internal 
confusion as well.


My question is, what's the state of this?  Is this a bug?  Or 
should it be forbidden to have such an initializer?  Or maybe it 
is a feature with some actual merit?


Ivan Kazmenko.



Re: Yield from function?

2017-01-31 Thread Ivan Kazmenko via Digitalmars-d-learn

On Monday, 30 January 2017 at 11:03:52 UTC, Profile Anaysis wrote:
I need to yield from a complex recursive function too allow 
visualizing what it is doing.


e.g., if it is a tree searching algorithm, I'd like to yield 
for each node so that the current state can be shown visually.


I realize that there are several ways to do this but D a yield 
version without additional threads would be optimal. I don't 
need concurrency or speed, just simple.


Sounds like opApply (external iteration) may well be the way to 
go.
It is a great tool to separate (possibly complex) iteration logic 
from (possibly complex) instance processing logic.
Here is a random recipe: 
https://www.sociomantic.com/blog/2010/06/opapply-recipe


An example:

-
import std.stdio;

class Node {
int value;
Node left, right;
this (int value_) {value = value_;}
}

struct InOrderViewer {
Node root;
int opApply (int delegate (Node) process) {
void recur (Node cur) {
if (cur is null) return;
recur (cur.left);
			process (cur); // use return value here to allow break in 
foreach

recur (cur.right);
}
recur (root);
return 0;
}
}

void main () {
auto v1 = new Node (1);
auto v2 = new Node (2);
auto v3 = new Node (3);
auto v4 = new Node (4);
auto v5 = new Node (5);
v2.left = v1;
v2.right = v5;
v5.left = v3;
v3.right = v4;

foreach (node; InOrderViewer (v2)) {
writeln (node.value ^^ 2); // 1 4 9 16 25
}
}
-

Ivan Kazmenko.



Re: size of a string in bytes

2017-01-28 Thread Ivan Kazmenko via Digitalmars-d-learn

On Saturday, 28 January 2017 at 15:32:33 UTC, Nestor wrote:
I want to know variable size in memory. For example, say I have 
an UTF-8 string of only 2 characters, but each of them takes 2 
bytes. string length would be 2, but the content of the string 
would take 4 bytes in memory (excluding overhead for type size).


As said, the byte count is indeed string.length.
The number of code points can be found by std.range.walkLength, 
but be aware it takes O(answer) time to compute.


Example:

-
import std.range, std.stdio;
void main () {
auto s = "Привет!";
writeln (s.length); // 13 bytes
writeln (s.walkLength); // 7 code points
}
-

Ivan Kazmenko.



Re: Trying to understand multidimensional arrays in D

2017-01-26 Thread Ivan Kazmenko via Digitalmars-d-learn
On Thursday, 26 January 2017 at 05:20:07 UTC, Profile Anaysis 
wrote:
(On the contrary, declarations in C or C++ looks rather 
unintuitive from this perspective: `T a[4][5][6]` is means 
that `a` is an array of 4 arrays of 5 arrays of 6 arrays of 
`T`.  Note how we have to read left-to-right but then wrap 
around the string to get the meaning.)


lol, I don' tknow what the last sentence means. wrap around the 
string? Do you mean look at the variable?


For me the interpretation above is the most logical because it 
is a sequential operation in my mind, if you will. x of y of z 
and the chain can be cut off anywhere and the interpretation 
still be the same.


This means that in `T a[4][5][6]`, the type `T[4][5][6]` is 
spread on both sides of the variable name `a`.  In the 
interpretation,

"`a` is an array of 4 arrays of 5 arrays of 6 arrays of `T`",
note that 4, 5 and 6 are from the right side but T is from the 
left side.  That's what I meant by wrap around.


Re: Trying to understand multidimensional arrays in D

2017-01-25 Thread Ivan Kazmenko via Digitalmars-d-learn
On Thursday, 26 January 2017 at 01:47:53 UTC, Profile Anaysis 
wrote:

does this mean that have

int[][4][4] matrix_history;

backwards?

int[4][4][] matrix_history;

this creates even a more set of problems.


In short, you are right, `int[4][4][]` is a dynamic array of 
`int[4][4]`.  In turn, `int[4][4]` is a static length-4 array of 
`int[4]`, and that is a static length-4 array of `int`.  It's 
quite logical once you learn how to read it: if T is a type, then 
T[] is a dynamic array of that type, and T[4] is a static 
length-4 array of that type.


So, if I have `int[2][5][7] a;` somewhere, the very last element 
is `a[6][4][1]`.  If you are inclined to think in terms of this 
difference, the simple rule of thumb would be that the order of 
dimensions in the declaration is reversed.


Also, note that if you want to have, for example, a dynamic array 
of 5 dynamic arrays of the same length 7 (modeling a C 
rectangular array, or a D static array, but with possibility to 
change the length of each row, as well as the number of rows), 
you would go with

`auto a = new int [] [] (5, 7);` (initialization)
The static array of 5 static arrays of length 7 is still
`int [7] [5] a;` (type declaration)
So the reverse only happens in type declarations.

(On the contrary, declarations in C or C++ looks rather 
unintuitive from this perspective: `T a[4][5][6]` is means that 
`a` is an array of 4 arrays of 5 arrays of 6 arrays of `T`.  Note 
how we have to read left-to-right but then wrap around the string 
to get the meaning.)


Additionally, reading about various kinds of arrays in D might 
help:

https://dlang.org/spec/arrays.html

And more in-depth material about array slicing:
http://dlang.org/d-array-article.html

Ivan Kazmenko.



Re: switch to member

2017-01-14 Thread Ivan Kazmenko via Digitalmars-d-learn

On Saturday, 14 January 2017 at 11:32:10 UTC, Marc Schütz wrote:
You can utilize a little-known `switch` syntax trick in 
combination with `foreach`. Because a `foreach` over tuples is 
unrolled at compile time, it works even if your fields don't 
have exactly the same types:





That looks concise.  Perhaps enum Which can also be automatically 
filled by __traits (allMembers) or std.traits.Fields if needed.




Re: opOpAssign on object properties

2017-01-08 Thread Ivan Kazmenko via Digitalmars-d-learn

On Sunday, 8 January 2017 at 18:23:34 UTC, collerblade wrote:

On Sunday, 8 January 2017 at 10:03:50 UTC, Ivan Kazmenko wrote:

On Sunday, 8 January 2017 at 09:22:12 UTC, collerblade wrote:

[...]


1. If you want the member variable to change, naturally, you 
should provide a getter property which returns a reference to 
that variable:


[...]


yes i tried the reference return, but the problem is, that the 
setter does NOT gets called, no matter what the result type of 
the opOpAssign method is.

I want to detect changes, but this way i still not able.

A a = new A;

a.location+=Point(1,1); //the private value changes, but the 
setter does not get called


Hmm, right.

The setter is not called, and it's by the spec.
Which says that "a op= b" is rewritten as "a.opOpAssign !(op) 
(b)".

Here: https://dlang.org/spec/operatoroverloading.html#op-assign

So, no *assignment* happens when you call a.location+=Point(1,1).
To have a side effect triggered by opAssign-ment, you can do it 
inside the opOpAssign function.


Looking at it another way, actions with struct Point can be seen 
as the responsibility of struct Point.  If you want to monitor 
these actions, do it in the code of opOpAssign function.  After 
that, your class A can inspect the state of its corresponding 
Point.  If normal Points don't need that, you can have a special 
SelfAwarePoint which has an alias this to its member Point.


Alternatively, you can have two getter properties: one as const 
and one by reference.  When the reference one gets called, you 
know the value of Point *may* have changed.


Well, I'm out of ideas for now.  If these still don't quite 
satisfy you, including a bigger picture of what you want to 
achieve may help.


Ivan Kazmenko.



Re: opOpAssign on object properties

2017-01-08 Thread Ivan Kazmenko via Digitalmars-d-learn

On Sunday, 8 January 2017 at 09:22:12 UTC, collerblade wrote:

How can i do opOpAssign with properties??


1. If you want the member variable to change, naturally, you 
should provide a getter property which returns a reference to 
that variable:


ref Point location() @property {
  return m_location;
}

This alone solves the immediate problem.

2. Note that it is common for assignment expressions to return a 
reference to the result, which would, for example, make chains 
like "a = (b += c)" possible:


  ref Point opOpAssign(string op)(in Point p) if (op == "+") {
x+=p.x;
y+=p.y;
return this;
  }

Here's a complete working version of your example:

-
struct Point {
  float x=0,y=0;

  this(float _x, float _y) {
x=_x;
y=_y;
  }

  //opopassign for +=
  ref Point opOpAssign(string op)(in Point p) if (op == "+") {
x+=p.x;
y+=p.y;
return this;
  }
}

class A {
  public:
ref Point location() @property {
  return m_location;
}

void location(in Point newlocation) @property {
  m_location=newlocation;
}

  private:
Point m_location;
}

void main() {
  import std.stdio;
  auto a= new A;
  a.location+=Point(1,1);
  writeln (a.location); // Point(1, 1)
  a.location+=Point(1,1);
  writeln (a.location); // Point(2, 2)
}
-

Ivan Kazmenko.


Re: Adding linker paths with spaces using dmd and msvc toolchain

2016-12-30 Thread Ivan Kazmenko via Digitalmars-d-learn

On Friday, 30 December 2016 at 05:24:56 UTC, Jeremy DeHaan wrote:

On Friday, 30 December 2016 at 04:56:59 UTC, Jerry wrote:
On Friday, 30 December 2016 at 03:51:13 UTC, Jeremy DeHaan 
wrote:

How does one correctly add a linker path that has spaces?


The quotes get consumed by the command line. The way DMD 
spawns the linker by creating a new string with all the flags. 
So it smashes everything into a new string, ignoring how the 
string was passed into DMD. I think you can use triple quotes, 
"""string with space""", and it should make the string passed 
to DMD include the string. Might be different for powershell.


You mean I could do -L/LIBPATH:"""path"""?


There is also the dark and dirty way of using the short DOS path, 
which is still maintained on Windows file system partitions.


How to get DOS path: 
http://stackoverflow.com/questions/4051088/how-to-get-dos-path-instead-of-windows-path


I can't recommend it as a long-term solution, but it sure can 
help when one needs things working here and now.


Ivan Kazmenko.



Re: How to list aggregate members in order of declaration at compile time?

2016-11-11 Thread Ivan Kazmenko via Digitalmars-d-learn
On Friday, 11 November 2016 at 22:04:37 UTC, Jonathan M Davis 
wrote:

...

I expect that it never occurred to Walter to specify that the 
order of the members mattered with tupleof and that that's why 
the spec doesn't say.


So, use tupleof, and you can create an enhancement request in 
bugzilla for the spec to be made clearer about it: 
https://issues.dlang.org


Thanks for the answer!  So you think the order guarantee is 
likely to be just granted for .tupleof if asked for.  I hope to 
get to creating a documentation issue/PR next week, to see more 
reaction.


Ivan Kazmenko.



Re: How to list aggregate members in order of declaration at compile time?

2016-11-11 Thread Ivan Kazmenko via Digitalmars-d-learn
On Thursday, 10 November 2016 at 10:16:44 UTC, Ivan Kazmenko 
wrote:
I want to somehow list members of a class in the order of their 
declaration.


Bump.  Anyone?  I've met my immediate goal by other means, but 
the general question remains.


If classes are no-go, basically, any aggregate will do if the 
order of declarations is reliably and reproducibly known at 
compile time.


I'm not much into compile-time reflection, yet, but I thought 
that's a basic operation.  Otherwise, how do people, for example, 
approach serializing arbitrary containers reproducibly across 
compiler versions - or they just don't?  Well, I've seen one 
example (Cerealed), but the implementation details there seem to 
contradict the current language documentation.


Ivan Kazmenko.



How to list aggregate members in order of declaration at compile time?

2016-11-10 Thread Ivan Kazmenko via Digitalmars-d-learn

Hi.

I want to somehow list members of a class in the order of their 
declaration.  The immediate goal is to generate a few functions, 
like the "default" constructor for structs but only with all the 
fields, or the "reader" function, but I'm interested in the 
general question as well.


I can go the hard way and wrap every declaration into something 
that will collect them and then list in the right order.  The 
problem is, the declarations won't look normal then.


The documentation for __traits (allMembers, ...), __traits 
(derivedMembers, ...) and the like [1] explicitly says that the 
order is not defined.  Still, I've looked at Atila Neves' 
Cerealed serializer library, and it does use them [2].  Does it 
mean the order is unlikely to change at this point?


The documentation for std.traits' RepresentationTypeTuple [3] 
says things are listed in topological order, which formally does 
not restrict the order for flat structures again.  And the 
underlying implementation [4] of Fields uses .tupleof class 
property which, in turn, does not list any guarantees on the 
order [5].


So I'm confused.  What is considered the right way to list 
members when I care about their linear order?


Ivan Kazmenko.

[1] https://dlang.org/spec/traits.html#derivedMembers
[2] 
https://github.com/atilaneves/cerealed/blob/master/src/cerealed/cereal.d#L467
[3] 
https://dlang.org/phobos/std_traits.html#RepresentationTypeTuple
[4] 
https://github.com/dlang/phobos/blob/10cd84a/std/traits.d#L2279

[5] https://dlang.org/spec/class.html#class_properties



Re: Newbie: Error parsing csv file with very long lines

2016-04-23 Thread Ivan Kazmenko via Digitalmars-d-learn

On Saturday, 23 April 2016 at 10:40:13 UTC, salvari wrote:
It seems to be really simple, I read the columns name with no 
problem. But as soon as the program parses the first line of 
data, the array containing the columns names seems to be 
overwrited.


Another possibility yet not mentioned is to change
foreach(line; stdin.byLine())
into
foreach(line; stdin.byLineCopy())
to make the older lines' contents available after you read the 
next line.




Re: Ada-Style Modulo Integer Types

2016-04-22 Thread Ivan Kazmenko via Digitalmars-d-learn

On Friday, 22 April 2016 at 17:37:44 UTC, Nordlöw wrote:

Have anybody implement Ada-style modulo types

https://en.wikibooks.org/wiki/Ada_Programming/Types/mod


I've implemented a proof-of-concept for algorithmic programming 
competitions [1]. In these competitions, quite a few problems ask 
to calculate the result modulo some large prime number.  The 
usual idea is that, this way, you still have to solve the 
underlying algorithmic problem, but the magnitude of calculated 
values does not affect your algorithmic complexity.  Disclaimer: 
it is incomplete and tuned for the competitions, and thus not 
ready for general use.


For the record, there is also an implementation of modulo integer 
for the same problem in C++ by Vladislav Isenbaev.  Note that the 
solutions themselves are not the same, so the timing can't be 
compared directly.


Ivan Kazmenko.

[1] http://codeforces.com/contest/628/submission/16212299
[2] http://codeforces.com/contest/628/submission/16610362



Re: 111

2016-02-21 Thread Ivan Kazmenko via Digitalmars-d-learn

On Sunday, 21 February 2016 at 12:35:31 UTC, Lisa wrote:

...
Is there smth wrong again?


Yes.

As a programmer, most of the time, you will have to try your 
programs by yourself before you consider them correct.


Now, run a compiler, and it complains:
-
main.d(20): Error: cannot return non-void from void function
-

Line 20 of your program is "return 0;", and the void function in 
question is "void main() {...}".  So, you have to fix either of 
that: make main return int instead of void, or remove the return 
line.


After that, the program will finally compile.  But that's not the 
end, you have to try running it.

"Enter side A:"
shall we say,
"1"
and then it writes
"Enter side B:"
and fails:
-
std.conv.ConvException@c:\Tools\dmd\windows\bin\..\..\src\phobos\std\conv.d(2729):
 no digits seen

0x0040666A in ...
-

That's a whole lot of unfriendly error text on the screen, but 
the human-readable part is "no digits seen" when reading variable 
B.


Now, read the chapter of Ali's book again very carefully, or one 
of the posts here.  You may then notice that the space inside the 
quotes is important, and also learn why.


The bottom line: the task of writing a program is not finished 
until you can compile it, run it, give it at least a few example 
inputs, and it prints the right output for all these inputs.


Ivan Kazmenko.



Re: 111

2016-02-20 Thread Ivan Kazmenko via Digitalmars-d-learn

On Saturday, 20 February 2016 at 04:15:50 UTC, Lisa wrote:

module main;

import std.stdio;
import std.math;

int main() {
int A, B, C;
writef("A = ");
readf("%lf", %A);

writef("B = ");
readf("%lf", %B);

writef("C1= ");
readf("%lf", %C);

writefl("P = (%lf)", A + B + C);
return 0;
}

It whatever doesn't work


The line "int A, B, C;" should be "double A, B, C;" if you want 
to be able to operate non-integer lengths as well.


The lines like "readf("%lf", %A);" should be "readf(" %s", );". 
 Please read the reasoning again carefully in Ali's book: 
http://ddili.org/ders/d.en/input.html.  The " %s" can be " %f" 
but not " %lf" (that would be the correct string for C's printf 
but not for D's readf), and the leading space is important.


On the output line, you perhaps meant "writefln" instead of 
"writefl".  Again, "%lf" should be changed into "%f" or "%s".




Re: 111

2016-02-19 Thread Ivan Kazmenko via Digitalmars-d-learn

On Friday, 19 February 2016 at 23:56:29 UTC, Lisa wrote:
Can you please help me and explain how to create a program, 
which would find area of triangle and its perimeter?


First, one can't find these unless something is given.  So, what 
is given: sides? angles? two-dimensional coordinates?


The next stop is Google for how to do that mathematically, 
without touching the keyboard.


Once you have the above, you may have some specific difficulty 
expressing that in a programming language of your choice, one 
which Google (again) can't resolve in a few minutes.  If that is 
the case, please state that difficulty.




Re: inner functions calling each other - how to do this with inner struct?

2016-02-03 Thread Ivan Kazmenko via Digitalmars-d-learn
On Wednesday, 3 February 2016 at 15:09:35 UTC, Adam D. Ruppe 
wrote:

Read my post here:

http://stackoverflow.com/questions/34398408/struct-declaration-order/34398642#34398642

then see if you can use the same reasoning on your problem.


This indeed works without any other tricks such as compile-time 
parameters:


-
import std.stdio;

void outerFun () {
struct Holder {
static struct S {
void fun2 (int x) {
writeln (x);
if (x > 0) fun1 (x - 1);
}
}

static S s;

static void fun1 (int y) {
writeln (y);
if (y > 1) s.fun2 (y - 2);
}
}

Holder.fun1 (10);
}

void main () {outerFun ();}
-

Thank you!

Ivan Kazmenko.



Re: Get the return type of the function

2016-02-03 Thread Ivan Kazmenko via Digitalmars-d-learn

On Wednesday, 3 February 2016 at 22:09:37 UTC, sigod wrote:

On Wednesday, 3 February 2016 at 19:21:06 UTC, Meta wrote:
Ah, I see. I'd like to test something; can you please change 
`(a) => a * a` to

`(int a) => a * a` and post the results?


This works.

http://dpaste.dzfl.pl/92c254ef6cf6


Seems reasonable: `(int a) => a * a` has return type `int` but 
just `(a) => a * a` does not yet know the type of `a`, and so can 
not tell the return type.


Re: merging map/filter/reduce/... in D

2016-01-28 Thread Ivan Kazmenko via Digitalmars-d-learn

On Friday, 29 January 2016 at 07:17:04 UTC, glathoud wrote:
I have the impression that function implementations are not 
merged:


return fun0(fun1(a));

For example, fun1(a) outputs a temporary array, which is then 
used as input for fun0. Merging the implementations of fun0 and 
fun1 would eliminate the need for a temporary array.


If fun1(a) indeed eagerly returns a temporary array, you are 
right.  Still, if the author of fun1 cares to be generic enough, 
it usually returns a lazy range: a struct with front, empty and 
popFront.  Whenever fun0 requests the next element of the range, 
fun1 calculates it and gives it away (returns front and calls 
popFront).


Note that all this - which function calls which other function - 
is known at compile time.  To merge the actual code of fun0 and 
popFront of fun1's return value is then the job for the optimizer 
pass, it's basically inlining.


Note that a temporary array can theoretically also be optimized 
out by an advanced optimizer.


Ivan Kazmenko.



Re: Is this rdmd bug or my fault ?

2016-01-08 Thread Ivan Kazmenko via Digitalmars-d-learn

On Friday, 8 January 2016 at 15:45:52 UTC, zabruk70 wrote:

Should i create bugreport, or this is my mistake?


Same here:
rdmd moduleA.d works.
rdmd -g moduleA.d produces a linker error.
What's more:
rdmd -m64 -g moduleA.d fails, and
rdmd -m64 moduleA.d also fails.

I have dmd 2.069.2 here.  Older versions seem to behave the same.

Please file a report at issues.dlang.org.


Re: regex - match/matchAll and bmatch - different output

2016-01-02 Thread Ivan Kazmenko via Digitalmars-d-learn

On Friday, 1 January 2016 at 12:29:01 UTC, anonymous wrote:

On 30.12.2015 12:06, Ivan Kazmenko wrote:
As you can see, bmatch (usage discouraged in the docs) gives 
me the
result I want, but match (also discouraged) and matchAll (way 
to go) don't.


Am I misusing matchAll, or is this a bug?


The `\1` there is a backreference. Backreferences are not part 
of regular expressions, in the sense that they allow you to 
describe more than regular languages. [1]


As far as I know, bmatch uses a widespread matching mechanism, 
while match/matchAll use a different, less common one. It 
wouldn't surprise me if match/matchAll simply didn't support 
backreferences.


Backreferences are not documented, as far as I can see, but 
they're working in other patterns. So, yeah, this is possibly a 
bug.



[1] 
https://en.wikipedia.org/wiki/Regular_expression#Patterns_for_non-regular_languages


The overview by the module author 
(http://dlang.org/regular-expression.html) does mention in the 
last paragraph that backreferences are supported.  Looks like it 
is a common feature in other programming languages, too.


The "\1" part is working correctly when "abab" or "abxab" or 
"ababx" but not "abac".  This means it is probably intended to 
work, and handling "xabab" incorrectly is a bug.


Also, as I understand it from the docs, matchAll/matchFirst use 
the most appropriate of match/bmatch internally, so if match does 
not properly support the particular backreference but bmatch 
does, the bug is in using the incorrect one to handle a pattern.


At any rate, wrong result with a 8-character pattern produces a 
"regex don't work" impression, and I hope something can be done 
about it.


Re: regex - match/matchAll and bmatch - different output

2015-12-31 Thread Ivan Kazmenko via Digitalmars-d-learn
On Wednesday, 30 December 2015 at 11:06:55 UTC, Ivan Kazmenko 
wrote:

...

As you can see, bmatch (usage discouraged in the docs) gives me 
the result I want, but match (also discouraged) and matchAll 
(way to go) don't.


Am I misusing matchAll, or is this a bug?


Reported as https://issues.dlang.org/show_bug.cgi?id=15489.



regex - match/matchAll and bmatch - different output

2015-12-30 Thread Ivan Kazmenko via Digitalmars-d-learn

Hi,

While solving Advent of Code problems for fun (already discussed 
in the forum: 
http://forum.dlang.org/post/cwdkmblukzptsrsrv...@forum.dlang.org), I ran into an issue.  I wanted to test for the pattern "two consecutive characters, arbitrary sequence, the same two consecutive characters".  Sadly, my solution using regular expressions gave a wrong result, but a hand-written one was accepted.


The problem reduced to the following:

import std.regex, std.stdio;
void main ()
{
writeln (bmatch   ("abab",  r"(..).*\1"));  // [["abab", "ab"]]
writeln (match("abab",  r"(..).*\1"));  // [["abab", "ab"]]
writeln (matchAll ("abab",  r"(..).*\1"));  // [["abab", "ab"]]
writeln (bmatch   ("xabab", r"(..).*\1"));  // [["abab", "ab"]]
writeln (match("xabab", r"(..).*\1"));  // []
writeln (matchAll ("xabab", r"(..).*\1"));  // []
}

As you can see, bmatch (usage discouraged in the docs) gives me 
the result I want, but match (also discouraged) and matchAll (way 
to go) don't.


Am I misusing matchAll, or is this a bug?

Ivan Kazmenko.



Re: Lots of D code

2015-12-28 Thread Ivan Kazmenko via Digitalmars-d-learn

On Monday, 28 December 2015 at 14:24:04 UTC, Basile B. wrote:
On Wednesday, 23 December 2015 at 00:59:53 UTC, steven kladitis 
wrote:

...
All of the programs are from RosettaCode.org. The  script to 
compile them generates a log file and you will see a few that 
the linker just stops No idea why. A few have 64K link 
errors no idea why.



TIA,
Steven


what's up ?

;)

Did you upload, so that bugs can be verified ?


As the original poster mentioned RosettaCode, perhaps they are 
just programs from http://rosettacode.org/wiki/D ?  There are 742 
entries, but some (like 
http://rosettacode.org/wiki/99_Bottles_of_Beer#D) contain more 
than one D program.


Re: Is it possible to elegantly create a range over a binary heap?

2015-12-28 Thread Ivan Kazmenko via Digitalmars-d-learn
On Monday, 28 December 2015 at 12:58:36 UTC, Gary Willoughby 
wrote:
On Sunday, 27 December 2015 at 22:42:21 UTC, Ivan Kazmenko 
wrote:
Or do you mean you want to print variables in order without 
modifying the array?  Sounds like this would require at least 
N log N time and N additional memory for an N-element heap 
anyway (or quadratic time and constant memory).  So, you can 
just copy the array and exhaust the copied binary heap, 
getting the same asymptotic complexity: N log N time and N 
additional memory.


Thanks. I wanted to iterate through the range without modifying 
the original array but like you said the only way to do that is 
by copying the data which is not ideal.


Hmm.  On second thought:

1. You can find maximum, then second maximum, then third maximum 
and so on - each in constant memory and linear time.  So, if 
performance is somehow not an issue, there is a way to do it 
@nogc but in N^2 operations.


2. If you output the whole array anyway, you may sort the array 
in place.  A sorted array obeys the heap property, so subsequent 
heap operations will still work.


3. The tricky part is when we want to support parallel iteration 
over the same heap.  If we look closely at one iteration of 
heapsort algorithm, it will perhaps become clear how to output 
values so that the array is a heap between any two consecutive 
output operations.  At the very least, our heap struct over the 
array can just track which part of the array is already sorted, 
and work with it separately.


4. Reading and modifying the heap in parallel at the same time 
does not look possible anyway, so this is as far as we can get.


Ivan Kazmenko.



Re: Reducing array.length triggers reallocation

2015-12-27 Thread Ivan Kazmenko via Digitalmars-d-learn

On Sunday, 27 December 2015 at 22:36:32 UTC, Ali Çehreli wrote:

[Several hours later...]

You know what... I bet there is no actual allocation at all. I 
think what happens is, the code calls GC.realloc(24) and 
realloc() does not do anything. However, it still reports to 
the profiler that there was an allocation (attempt).


Can someone verify that please. At least, can someone show 
where GC.realloc() source is.


Thank you,
Ali


I believe it boils down to calling gc.gc.reallocNoSync in 
druntime: 
https://github.com/D-Programming-Language/druntime/blob/master/src/gc/gc.d#L603 .


Re: Is it possible to elegantly create a range over a binary heap?

2015-12-27 Thread Ivan Kazmenko via Digitalmars-d-learn
On Sunday, 27 December 2015 at 20:01:47 UTC, Gary Willoughby 
wrote:
On Sunday, 27 December 2015 at 17:23:35 UTC, Gary Willoughby 
wrote:
I have a binary tree storing ints implemented using an array. 
The internal state looks like this:


8,7,6,4,1,3,5,2

When extracting this data, it is returned as 8,7,6,5,4,3,2,1.

Is it possible to elegantly add a range on top of the internal 
state to return the correct value order I would expect when 
extracting? Is there an algorithm documented somewhere for 
doing this?


Some explanatory reference:

https://en.wikipedia.org/wiki/Binary_tree#Arrays


If you implement a struct with range primitives over it, you can 
use it as a range.


See the second code example in std.container.binaryheap's docs at
http://dlang.org/phobos/std_container_binaryheap.html#.BinaryHeap.

Or do you mean you want to print variables in order without 
modifying the array?  Sounds like this would require at least N 
log N time and N additional memory for an N-element heap anyway 
(or quadratic time and constant memory).  So, you can just copy 
the array and exhaust the copied binary heap, getting the same 
asymptotic complexity: N log N time and N additional memory.


Ivan Kazmenko.


Re: DMD -L Flag, maybe a bug?

2015-12-26 Thread Ivan Kazmenko via Digitalmars-d-learn

On Saturday, 26 December 2015 at 01:04:57 UTC, Bubbasaur wrote:

It's almost like the example in the URL you showed:

dmd test.d -LC:/gtkd/src/build/GtkD.lib


Note that -L passes flags (options) but not necessarily arguments 
or paths.  For example, I use "dmd -L/STACK:268435456" by default 
along with other options to increase the default stack size to 
256Mb.  The "/STACK:268435456" part is an OPTLINK switch, not a 
path.  Here is the list of OPTLINK switches: 
http://www.digitalmars.com/ctg/ctgLinkSwitches.html


Clearly, the forward slash (/) is reserved for switches, so the 
program will have trouble parsing paths with forward slashes.


Re: Most performant way of converting int to string

2015-12-24 Thread Ivan Kazmenko via Digitalmars-d-learn

On Tuesday, 22 December 2015 at 19:50:28 UTC, Daniel Kozák wrote:

V Tue, 22 Dec 2015 18:39:16 +
Ivan Kazmenko via Digitalmars-d-learn
<digitalmars-d-learn@puremagic.com> napsáno:
Does DMD, or Phobos function to!(string), do anything like 
that? The number of possible bases is not large anyway.  I've 
heard major C/C++ compilers do that, but have not looked for a 
proof myself.


Yes, IIRC, all D compilers should be able to change modulus and 
division to few additions, subtractions and bit shifts if base 
is known at compile time.


And phobos use this: 
https://github.com/D-Programming-Language/phobos/pull/1452


So, in a few common cases (bases 10 and 2, 4, 8, 16), you convert 
a runtime argument into a compile-time argument for the 
implementation function, and there, division is optimized at 
compile time.  Nice!


Re: Most performant way of converting int to string

2015-12-22 Thread Ivan Kazmenko via Digitalmars-d-learn

On Tuesday, 22 December 2015 at 18:11:24 UTC, rumbu wrote:
On Tuesday, 22 December 2015 at 17:15:27 UTC, Andrew Chapman 
wrote:
Sorry if this is a silly question but is the to! method from 
the conv library the most efficient way of converting an 
integer value to a string?


e.g.
string s = to!string(100);

I'm seeing a pretty dramatic slow down in my code when I use a 
conversion like this (when looped over 10 million iterations 
for benchmarking).


Cheers!


Converting numbers to string involves the most expensive known 
two operations : division and modulus by 10.


When the base is known in advance, division and modulus can be 
substituted by a few additions, subtractions and bit shifts.  For 
example, the Hacker's Delight book has a chapter dedicated to 
that, as well as a freely available additional chapter 
(www.hackersdelight.org/divcMore.pdf).


Does DMD, or Phobos function to!(string), do anything like that?  
The number of possible bases is not large anyway.  I've heard 
major C/C++ compilers do that, but have not looked for a proof 
myself.


Re: AA struct hashing bug?

2015-12-08 Thread Ivan Kazmenko via Digitalmars-d-learn

On Tuesday, 8 December 2015 at 11:45:25 UTC, Random D user wrote:
Ok. This is minimal app that crashes for me. If someone could 
try this:


At the very least, there is no crash when changing `struct Foo` 
to `static struct Foo`, so it is perhaps related to `Foo` being 
an inner struct with a pointer to parent class.


Re: AA struct hashing bug?

2015-12-08 Thread Ivan Kazmenko via Digitalmars-d-learn

On Tuesday, 8 December 2015 at 11:45:25 UTC, Random D user wrote:
Ok. This is minimal app that crashes for me. If someone could 
try this:


OK, this at least reproducibly crashes here, too (-m32 and -m64 
on Windows, tried dmd 2.069.0 and 2.067.1).


Re: AA struct hashing bug?

2015-12-08 Thread Ivan Kazmenko via Digitalmars-d-learn

On Tuesday, 8 December 2015 at 11:45:25 UTC, Random D user wrote:
Ok. This is minimal app that crashes for me. If someone could 
try this:


Interesting.

With dmd 2.064.2, your example compiles and runs fine.

With dmd 2.065.0, it does not compile, complaining that there is 
no opCmp for `Foo`s.


With dmd 2.066.0, and up to the current version, it compiles fine 
but crashes at runtime.


So I'd say it's a regression.

The tracker at issues.dlang.org does not report much bugs related 
to inner structs.

Can you please file a new issue there?


Re: AA struct hashing bug?

2015-12-08 Thread Ivan Kazmenko via Digitalmars-d-learn

On Tuesday, 8 December 2015 at 11:04:49 UTC, Random D user wrote:
On Tuesday, 8 December 2015 at 01:23:40 UTC, Ivan Kazmenko 
wrote:

On Monday, 7 December 2015 at 22:03:42 UTC, Alex Parrill wrote:

On Monday, 7 December 2015 at 18:48:18 UTC, Random D user
Tested the same code with -m32 and -m64 on Windows.  Works for 
me, too.


I tried this again. And it seems it might be my bug or that the 
runtime somehow corrupts it's state. Scary.


So I have an App class that gets created in main.
Basically
App = new App
App.start();

If I put that code as the first thing in the constructor 
everything works.
If I put that code as the first thing in the first method after 
constructor it crashes.

And that code is completely unrelated to everything else.
Without the code snippet the whole app works fine.
Also if I wrap the code in a local funtion or class, it works 
fine even in the first method.


Well, if you manage to reduce the code to a minimal example 
reproducing the bug, and then post it, only then we can try to 
help.  Otherwise, other people will have nothing but guesses.




Re: AA struct hashing bug?

2015-12-07 Thread Ivan Kazmenko via Digitalmars-d-learn

On Monday, 7 December 2015 at 22:03:42 UTC, Alex Parrill wrote:

On Monday, 7 December 2015 at 18:48:18 UTC, Random D user wrote:

struct Foo
{
this( int k )
{
a = k;
}
int a;
}

Foo foo;
int[ Foo ] map;

map[ foo ] = 1;  // Crash! bug?

// This also crashes. I believe crash above makes a call like 
this (or similar) in the rt.

//auto h = typeid( foo ).getHash(  ); // Crash!

win64 & dmd 2.69.2


Also works on DMD v2.069.2 on XUbuntu Linux x64. I can try it 
on Windows later.


Exact code I tested:

struct Foo
{
this( int k )
{
a = k;
}
int a;
}

void main() {
Foo foo;
int[ Foo ] map;

map[ foo ] = 1;
}


Tested the same code with -m32 and -m64 on Windows.  Works for 
me, too.


Re: foreach multiple loop sugar

2015-08-18 Thread Ivan Kazmenko via Digitalmars-d-learn

On Tuesday, 18 August 2015 at 16:51:01 UTC, ixid wrote:

On Tuesday, 18 August 2015 at 16:02:42 UTC, cym13 wrote:

On Tuesday, 18 August 2015 at 15:51:55 UTC, ixid wrote:
Though sugar seems to be somewhat looked down upon I thought 
I'd suggest this- having seen the cartesianProduct function 
from std.algorithm in another thread I thought it would be an 
excellent piece of sugar in the language. It's not an earth 
shattering change but it makes something very common more 
elegant and reduces indentation significantly for multiple 
nested loops. Braces make nested loops very messy and any 
significant quantity of code in the loop body benefits from 
not being in a messy nesting.


...


What would you do with associative arrays?

void main() {
auto aa = [1:1, 2:2];
foreach (a, b ; aa, 1..10)
foo(a, b);
}


Prevent both iterator count and associative value variables for 
foreach loops with nested loops. This behaviour of associative 
arrays is already an odd case as it clashes with the iterator 
behaviour for other arrays.


It is not iterator count, it is key and value.  And actually, it 
is pretty consistent.


import std.stdio;
void main () {
foreach (index, value; [2, 4, 8])
writefln (a[%s] = %s, index, value);
foreach (index, value; ['x': 2, 'y': 4, 'z': 8])
writefln (b[%s] = %s, index, value);
}

The output is:

a[0] = 2
a[1] = 4
a[2] = 8
b[z] = 8
b[x] = 2
b[y] = 4



Re: forward range properties with alias this - how?

2015-07-29 Thread Ivan Kazmenko via Digitalmars-d-learn

On Wednesday, 29 July 2015 at 12:25:14 UTC, Marc Schütz wrote:

On Tuesday, 28 July 2015 at 21:25:23 UTC, Ivan Kazmenko wrote:

Hello,

I wrap an array into a struct.  Then I use alias this to 
expose the array functionality.  Sadly, range properties of 
the array are not forwarded, and so I can't use the struct as 
an array with functions from std.algorithm and std.range.


-
import std.range, std.stdio;
struct S {
int[] contents;
alias contents this;
}
void main() {
S s;
writeln(hasSlicing!(S)); // false
}
-

I would like to be able to do that, however.

1. Why exactly hasSlicing (et al.) does not check the alias 
this-ed array when it checks the struct?


2. What should I do?

The solution I can think of is to insert the 3-6 range 
functions which forward the functionality to the underlying 
array, perhaps as a mixin.


Ivan Kazmenko.


`hasSlicing` explicitly checks whether the result of the slice 
operator has the same type as the original:


https://github.com/D-Programming-Language/phobos/blob/master/std/range/primitives.d#L1499-L1500

If you remove the `static assert()` and change the next line to 
use `auto`, and do the same in the other two places in this 
templates, it will work.


Thank you, the matter got clearer after reading the right piece 
of code and your explanation.


By the way, the documentation around these source lines always 
repeats a slightly outdated version of the unittests.  Shouldn't 
it be brought in sync, perhaps by using the modern DRY way:

///
unittest {...}
Or will that necessarily precede the unittest with Example:?

At any rate, I doubt the ~20 lines of introspection code - which 
sometimes gets outdated - should appear at all in hasSlicing et 
al. documentation.  If a developer encounters problems with 
hasSlicing and needs the source, a link to the up-to-date source 
itself may be enough.


I don't know whether this is intentional. I'd say we should 
allow a sliceable range to have slices of a different type.


EDIT:
The documentation even says that it's intentional, but gives no 
justification.


I don't know why the type should be the same, but that may well 
be needed.


Anyway, after more digging, I found out I only need to implement 
save() to satisfy isRandomAccessRange, which makes sense when I 
think of it: the save() for arrays returns an array and not my 
struct.  And opSlice(...) to satisfy hasSlicing, which also makes 
sense if we accept that the slice needs to be the same type: a 
generic opSlice is not possible since operator overloads must be 
member functions, and even if it were, it would not know how to 
construct an object of our specific type in the general case.  
So, that's some boilerplate, but its appearance seems justified.


Here's the working code I got:
-
import std.algorithm, std.random, std.range, std.stdio;
struct S {
int[] contents;
alias contents this;
@property auto save() {return S(contents.dup);}
auto opSlice(size_t lo, size_t hi) {return 
S(contents[lo..hi]);}

}
void main() {
S s;
s = [4, 3, 2, 1];
writeln(s[1..3]); // [3, 2]
writeln(isInputRange!(S)); // true
writeln(isForwardRange!(S)); // true
writeln(isBidirectionalRange!(S)); // true
writeln(isRandomAccessRange!(S)); // true
writeln(hasSlicing!(S)); // true
auto t = s;
sort(s);
writeln(s); // [1, 2, 3, 4]
randomShuffle(s);
writeln(s); // random permutation
writeln(t); // same as above
}
-

Now, if I remove the custom opSlice and alter the checks in 
hasSlicing as you suggested, I get the error:

-
sorting.d(1160): Error: quickSortImpl (S r, uint depth) is not 
callable using argument types (int[], uint)

-
Which means quickSortImpl (S r, uint depth) can't instantiate and 
call quickSortImpl (int[] r, uint depth) for recursively sorting 
its slices.  That is understandable.


Re: forward range properties with alias this - how?

2015-07-29 Thread Ivan Kazmenko via Digitalmars-d-learn

On Wednesday, 29 July 2015 at 23:54:29 UTC, Ivan Kazmenko wrote:

On Wednesday, 29 July 2015 at 12:25:14 UTC, Marc Schütz wrote:

On Tuesday, 28 July 2015 at 21:25:23 UTC, Ivan Kazmenko wrote:

...


Perhaps I still don't implement save() correctly.
The line
@property auto save() {return S(contents.dup);}
was meant to be just:
@property auto save() {return S(contents);}
But with either of them, I get an error when trying a function 
using save.


-
import std.algorithm, std.range, std.stdio;
struct S {
int[] contents;
alias contents this;
@property auto save() {return S(contents);}
auto opSlice(size_t lo, size_t hi) {return 
S(contents[lo..hi]);}

}
void main() {
S s;
s = [4, 3, 2, 1];
nextPermutation(s);
}
-

The error is:
-
sorting.d(2460): Warning: use std.algorithm.reverse instead of 
.reverse property
sorting.d(2460): Error: function expected before (), not 
_adReverse(range.contents, 4u) of type int[]

-

So, is something wrong with my save()?

Anyway, I reckon nextPermutation itself is wrong and should use
reverse(range);
instead of
range.reverse();
as it does ten lines later:
https://github.com/D-Programming-Language/phobos/blob/30e4ff1717d6d3eb82d2cb0e00a3c07af4263a7b/std/algorithm/sorting.d#L2468-L2478

If anybody can confirm that, I can file an issue and a patch.



forward range properties with alias this - how?

2015-07-28 Thread Ivan Kazmenko via Digitalmars-d-learn

Hello,

I wrap an array into a struct.  Then I use alias this to expose 
the array functionality.  Sadly, range properties of the array 
are not forwarded, and so I can't use the struct as an array with 
functions from std.algorithm and std.range.


-
import std.range, std.stdio;
struct S {
int[] contents;
alias contents this;
}
void main() {
S s;
writeln(hasSlicing!(S)); // false
}
-

I would like to be able to do that, however.

1. Why exactly hasSlicing (et al.) does not check the alias 
this-ed array when it checks the struct?


2. What should I do?

The solution I can think of is to insert the 3-6 range functions 
which forward the functionality to the underlying array, perhaps 
as a mixin.


Ivan Kazmenko.



Re: partialShuffle only shuffles subset.

2015-05-19 Thread Ivan Kazmenko via Digitalmars-d-learn

On Tuesday, 19 May 2015 at 10:00:33 UTC, BlackEdder wrote:
The documentation seems to indicate that partialShuffle: 
Partially shuffles the elements of r such that upon returning 
r[0..n] is a random subset of r, (which is what I want), but it 
seems that partialShuffle actually only shuffles the first 
subset of the range (which you could do probably also do by 
[0..n].randomShuffle).


This different behaviour was problem created since: 
https://issues.dlang.org/show_bug.cgi?id=11738. Does anyone 
know what the intended behaviour is/was?


Reading the current documentation and unittests, I now also 
believe the fix was a mistake.  Reopened the issue for now with a 
comment: https://issues.dlang.org/show_bug.cgi?id=11738#c2


I hope Joseph Rushton Wakeling looks into it soon.


Re: Feature or bug: print braces

2015-05-15 Thread Ivan Kazmenko via Digitalmars-d-learn

On Thursday, 14 May 2015 at 00:29:06 UTC, Dennis Ritchie wrote:

Why doesn't the compiler produces an error?

-
import std.stdio;

void main() {
writeln({});
}
-
http://ideone.com/qTZCAd


Somehow reminds me of this lambda:
https://github.com/Hackerpilot/Idiotmatic-D/blob/master/idiotmatic.d#L127-L128


Re: Possible to write a classic fizzbuzz example using a UFCS chain?

2015-04-28 Thread Ivan Kazmenko via Digitalmars-d-learn

On Tuesday, 28 April 2015 at 10:46:54 UTC, Gary Willoughby wrote:

After reading the following thread:

http://forum.dlang.org/thread/nczgumcdfystcjqyb...@forum.dlang.org

I wondered if it was possible to write a classic fizzbuzz[1] 
example using a UFCS chain? I've tried and failed.


[1]: http://en.wikipedia.org/wiki/Fizz_buzz


Here is another, hopefully readable, version with lambda built on 
ternary operators:

-
import std.algorithm, std.conv, std.functional, std.range, 
std.stdio;

void main () {
sequence !(q{n + 1})
.map !(x =
(x % 3 == 0   ? fizz : ) ~
(  x % 5 == 0 ? buzz : ) ~
(x % 3 != 0  x % 5 != 0 ? x.text : ))
.take (100)
.join ( )
.writeln;
}
-

Output:
-
1 2 fizz 4 buzz fizz 7 8 fizz buzz 11 fizz 13 14 fizzbuzz 16 17 
fizz 19 buzz fizz 22 23 fizz buzz 26 fizz 28 29 fizzbuzz 31 32 
fizz 34 buzz fizz 37 38 fizz buzz 41 fizz 43 44 fizzbuzz 46 47 
fizz 49 buzz fizz 52 53 fizz buzz 56 fizz 58 59 fizzbuzz 61 62 
fizz 64 buzz fizz 67 68 fizz buzz 71 fizz 73 74 fizzbuzz 76 77 
fizz 79 buzz fizz 82 83 fizz buzz 86 fizz 88 89 fizzbuzz 91 92 
fizz 94 buzz fizz 97 98 fizz buzz

-

Ivan Kazmenko.


Re: Convert hex to binary

2015-04-24 Thread Ivan Kazmenko via Digitalmars-d-learn
On Friday, 24 April 2015 at 18:55:07 UTC, Steven Schveighoffer 
wrote:
Thanks to all of you for the solutions, but what if the 
hex-string

exceeds the limit of ulong, for instance
123456789ABCDEF0123456789ABCDEF1234. How to convert them to a
ulong-array?


Well, technically, a hex string can be split on 16-character 
boundaries, and then you could parse each one.


-Steve


BigInt can be constructed from a decimal string:

-
import std.bigint, std.conv, std.stdio, std.string;
void main(){readln.strip.to!BigInt.writeln;}
-

The same could have been done in the library for function to 
accepting the second argument, like this:


-
import std.bigint, std.conv, std.stdio, std.string;
void main(){readln.strip.to!BigInt(16).writeln;}
-

It seems trivial technically, but I wonder if there's some 
library design drawback.  After all, to!BigInt from the default 
base 10 is the same O(n^2) as to!BigInt from a variable base, so 
it's not like the function is going to hide complexity more than 
it already does.


Ivan Kazmenko.


Re: Formatted output ranges

2015-04-20 Thread Ivan Kazmenko via Digitalmars-d-learn
Yes, it's a lot better but I did not get to concatenate the 
string ;; in each paragraph:


-
import std.conv, std.stdio, std.range, std.string;

void main() {

auto a = iota(10, 1101).text;

a = a[1 .. $ - 1], a ~= '.';

writeln(wrap(a, 30));
}
-
http://ideone.com/jsSbKj


writeln(wrap(a, 30, ;; , ;; ));

Works with dmd 2.066.1 and 2.067.0.


Re: Formatted output ranges

2015-04-17 Thread Ivan Kazmenko via Digitalmars-d-learn

On Saturday, 11 April 2015 at 22:45:39 UTC, Dennis Ritchie wrote:
I also want to know whether it is possible to D somehow set the 
maximum width of the print string in characters?


-
void main() {
import std.stdio, std.range;
writefln(;; %(%s, %))., iota(10, 1101));
}
-

For example, here's the code to Common Lisp which is given by 
the width of the line is 30 characters:

-
(let ((a (loop :for i :from 10 :to 1100 :collect i)))
(format t ~%;;~{ ~~%;; ~1,30:;~S~~^,~}.~% a))
-
http://ideone.com/hGguge


Looks like there's std.string.wrap to do that:
http://forum.dlang.org/thread/mgqiji$727$1...@digitalmars.com


Re: Two-dimensional slices in D

2015-04-14 Thread Ivan Kazmenko via Digitalmars-d-learn

On Tuesday, 14 April 2015 at 14:21:41 UTC, Dennis Ritchie wrote:
	writefln([%([%(%s, %)]%|\n %)], [a[4][4 .. $], a[5][4 .. $], 
a[6][4 .. $], a[7][4 .. $]]);

At least this can be done as
-
writefln([%([%(%s, %)]%|\n %)], a[4..8].map !(b = b[4 .. $]));
-


Re: Extracting Sorted Storage from BinaryHeap

2015-03-29 Thread Ivan Kazmenko via Digitalmars-d-learn

On Sunday, 29 March 2015 at 20:05:22 UTC, Nordlöw wrote:
What's the most efficient way to extract a the storage from a 
BinaryHeap and then sort it?


Is there a better way other than

binaryHeap.release.sort

than makes use of the heap property? For example

while (!binaryHeap.empty)
{
sortedStorage ~= binaryHeap.front;
binaryHeap.popFront;
}

?


Algorithm-wise, you can repeat the following:
1. Decrease the length of the heap by one.
2. Swap the first (largest) element with the one just removed.
3. Sift the new first element (which is most surely not largest) 
down the heap.
The array is sorted in place: the prefix is always a binary heap, 
and the suffix is always a sorted array.


This is still O(n log n), but may have a lower constant than just 
sorting the array.  Or it may give no benefit over sort() because 
sifting down a heap is not as local in memory as quicksort.  A 
benchmark would show what's best.


Unsure how to express that cleanly with the Phobos implementation 
of BinaryHeap.


Ivan Kazmenko.


Re: C# to D

2015-03-25 Thread Ivan Kazmenko via Digitalmars-d-learn

On Wednesday, 25 March 2015 at 20:02:20 UTC, Ivan Kazmenko wrote:

Will file an issue soon.

Here it is:
https://issues.dlang.org/show_bug.cgi?id=14340
And another one, a 2.067 regression:
https://issues.dlang.org/show_bug.cgi?id=14341


Re: C# to D

2015-03-25 Thread Ivan Kazmenko via Digitalmars-d-learn

On Wednesday, 25 March 2015 at 20:09:53 UTC, bearophile wrote:

Dennis Ritchie:


A more effective solution for C ++:

#include iostream
#include vector
#include range/v3/all.hpp

int main() {
 using namespace ranges;

 auto rng = istreamint( std::cin )
  | to_vector
  | action::sort
  | view::group_by( std::equal_toint() )
  | copy
  | action::stable_sort( []( const auto e1, const 
auto e2 ) { return distance( e1 )  distance( e2 ); } );

 std::cout  ( rng );
}



This is still not very efficient (perhaps the last sorting has 
to be stable):


void main() {
import std.stdio, std.algorithm, std.typecons, std.array;

[7, 5, 7, 3, 3, 5, 3, 3, 0, 3, 1, 1, 5, 1, 1, 1, 2, 2, 8, 
5, 8, 8]

.sort()
.groupBy!((a, b) = a == b)
.map!array
.array
.sort!q{a.length  b.length}
.joiner
.writeln;
}


Bye,
bearophile


5. An efficient version would be to count the integers by using 
an associative array (or a redBlackTree for guaranteed upper 
bound) and then use these.  It is O (n) time and memory spent in 
precalculation phase and O (n log n) time for sorting.  Looks 
like there is no way to write that as a chain of transforms, but 
many optimizations do require manual labor.


-
import std.algorithm, std.conv, std.range, std.stdio;
void main () {
auto arr = [7, 5, 7, 3, 3, 5, 3, 3, 0, 3, 1, 1, 5, 1,
1, 1, 2, 2, 8, 5, 8, 8];
int [int] counts;
foreach (e; arr) {
counts[e]++;
}
arr.multiSort !((a, b) = counts[a]  counts[b], (a, b) = a 
 b);

arr.map !(to !(string))
.join ( )
.writeln;
// prints 1 1 1 1 1 3 3 3 3 3 5 5 5 5 8 8 8 2 2 7 7 0
}
-

Also, some of my previously posted codes do not compile under 
2.066 or earlier unless you replace .join (' ') with .join ( ) 
there.


Re: C# to D

2015-03-25 Thread Ivan Kazmenko via Digitalmars-d-learn

On Wednesday, 25 March 2015 at 20:17:57 UTC, bearophile wrote:

Ivan Kazmenko:

(1) For me, the name of the function is obscure.  Something 
like sortBy would be a lot easier to find than schwartzSort.


I've asked to change the name of that function for years. But 
Andrei Alexandrescu is a adamantly against changing that pet 
name he has chosen. This is irrational behavour:

https://issues.dlang.org/show_bug.cgi?id=4909

There's lot of way to go for Phobos. And the only want to find 
holes, missed opportunities, sub-optimal performance spots, 
missing functions and features, and bad APIs and bad names is 
to actually try to use Phobos, like we are doing in this thread.


On the bright side, the list under Sorting at the docs
http://dlang.org/phobos/std_algorithm.html
is short enough for the curious to just look at the entries and 
find it.

The specific page
http://dlang.org/phobos/std_algorithm_sorting.html
does even contain a link explaining what that is, but I'd propose
-Sorts with the help of the Schwartzian transform.
+Sorts by key predicate with the help of the Schwartzian 
transform.

or some similar wording.


Re: C# to D

2015-03-25 Thread Ivan Kazmenko via Digitalmars-d-learn

On Wednesday, 25 March 2015 at 19:32:43 UTC, Dennis Ritchie wrote:

On Wednesday, 25 March 2015 at 19:01:43 UTC, bearophile wrote:

One solution:


Thanks.

On Wednesday, 25 March 2015 at 19:03:27 UTC, bearophile wrote:
But calling count for each item is not efficient (in both C# 
and D). If your array is largish, then you need a more 
efficient solution.


A more effective solution for C ++:

#include iostream
#include vector
#include range/v3/all.hpp

int main() {
  using namespace ranges;

  auto rng = istreamint( std::cin )
   | to_vector
   | action::sort
   | view::group_by( std::equal_toint() )
   | copy
   | action::stable_sort( []( const auto e1, const 
auto e2 ) { return distance( e1 )  distance( e2 ); } );

  std::cout  ( rng );
}


Here is my take at it:

1. A more verbose comparison function:

-
import std.algorithm, std.conv, std.range, std.stdio;
void main () {
auto arr = [7, 5, 7, 3, 3, 5, 3, 3, 0, 3, 1, 1, 5, 1,
1, 1, 2, 2, 8, 5, 8, 8];
arr.sort !((x, y) = arr.count (x)  arr.count (y) ||
(arr.count (x) == arr.count (y)  x  y))
.map !(to !(string))
.join ( )
.writeln;
// prints 1 1 1 1 1 3 3 3 3 3 5 5 5 5 8 8 8 2 2 0 7 7
}
-

This surprised me by printing ...0 7 7 instead of ...7 0 0, which 
is plain wrong.  Reproducible in 2.066 and 2.067 on win32.  With 
-debug, it triggers an assertion in Phobos:


-
core.exception.AssertError@c:\Tools\dmd\windows\bin\..\..\src\phobos\std\algorithm\sorting.d(900): 
Failed to sort range of type int[]


0x0041708D in _d_assert_msg
0x00416C2F in void rt.dmain2._d_run_main(int, char**, extern (C) 
int function(char[][])*).runAll()

0x00416B47 in _d_run_main
0x00416848 in main
0x76AD33CA in BaseThreadInitThunk
0x770C9ED2 in RtlInitializeExceptionChain
0x770C9EA5 in RtlInitializeExceptionChain
-

Will file an issue soon.

2. As above, but use the other sorting algorithm:

-
import std.algorithm, std.conv, std.range, std.stdio;
void main () {
auto arr = [7, 5, 7, 3, 3, 5, 3, 3, 0, 3, 1, 1, 5, 1,
1, 1, 2, 2, 8, 5, 8, 8];
arr.sort !((x, y) = arr.count (x)  arr.count (y) ||
(arr.count (x) == arr.count (y)  x  y), 
SwapStrategy.stable)

.map !(to !(string))
.join ( )
.writeln;
// prints 1 1 1 1 1 3 3 3 3 3 5 5 5 5 8 8 8 2 2 7 7 0
}
-

All fine here.

3. Sort by comparing a transform of the data, for some reason 
disguised by the name schwartzSort:


-
import std.algorithm, std.conv, std.range, std.stdio, 
std.typecons;

void main () {
auto arr = [7, 5, 7, 3, 3, 5, 3, 3, 0, 3, 1, 1, 5, 1,
1, 1, 2, 2, 8, 5, 8, 8];
arr.sort ()
.schwartzSort !(x = tuple (-arr.count (x), x))
.map !(to !(string))
.join (' ')
.writeln;
// prints 1 1 1 1 1 3 3 3 3 3 5 5 5 5 8 8 8 2 2 7 7 0
}
-

Similar to bearophile's solution.
(1) For me, the name of the function is obscure.  Something like 
sortBy would be a lot easier to find than schwartzSort.
(2) It does not offer multiple transforms (sort by this, then by 
that).  This seems doable as a Phobos enhancement.


4. Sort by a few binary predicates in one pass.

-
import std.algorithm, std.conv, std.range, std.stdio;
void main () {
auto arr = [7, 5, 7, 3, 3, 5, 3, 3, 0, 3, 1, 1, 5, 1,
1, 1, 2, 2, 8, 5, 8, 8];
arr.multiSort !((a, b) = arr.count (a)  arr.count (b),
(a, b) = a  b);
arr.map !(to !(string))
.join (' ')
.writeln;
// prints 1 1 1 1 1 3 3 3 3 3 5 5 5 5 8 8 8 2 2 7 7 0
}
-

Two concerns here.
(1) It returns void instead of a sorted range, so can't be 
chained as the others.  This seems doable as a Phobos 
enhancement.  Or is there a reason not to?
(2) The documentation says it is more efficient than the first 
version in the number of comparisons (verbose lambda with plain 
sort) [1], but I don't get how it is possible: unless we know 
than (not pred1(a,b)) and (not !pred1(a,b)), we can not proceed 
by evaluating pred2(a,b).


Ivan Kazmenko.


Re: C# to D

2015-03-25 Thread Ivan Kazmenko via Digitalmars-d-learn

On Wednesday, 25 March 2015 at 20:02:20 UTC, Ivan Kazmenko wrote:
(2) The documentation says it is more efficient than the first 
version in the number of comparisons (verbose lambda with plain 
sort) [1], but I don't get how it is possible: unless we know 
than (not pred1(a,b)) and (not !pred1(a,b)), we can not proceed 
by evaluating pred2(a,b).


[1] http://dlang.org/phobos/std_algorithm_sorting.html#.multiSort


Re: BigInt and xor

2015-03-24 Thread Ivan Kazmenko via Digitalmars-d-learn

On Tuesday, 24 March 2015 at 15:45:36 UTC, Dennis Ritchie wrote:

Tell me, please, how can I replace this code?

import std.conv : to;
import std.bigint : BigInt;
import std.string : format;
import std.stdio : writeln;

void main() {

BigInt[10] bitArr;

ulong n = 18_446_724_073_709_551_614U;

bitArr[0] = format(%b, n).to!BigInt;

writeln(bitArr[0]);
writeln(bitArr[0] ^ 1); // not work

}

Output:
11101101110001100011000110101010
11101101110001100011000110101011


What exactly is not working?
The only thing I see lacking is an ability to print a BigInt in 
binary via writefln(%b).


Up to 64 bits, arithmetic and bitwise operations, including xor, 
are available with long and ulong.  Just print the result as 
binary:


-
import std.stdio;
void main() {
ulong n = ulong.max - 0b1000101;
writeln (n);
writefln (%b, n);
writefln (%b, n ^ 1);
}
-
Output:
-
18446744073709551546
10111010
10111011
-

If you need more than 64 bits, take a look at BitArray here, it 
also has xor defined:

http://dlang.org/phobos/std_bitmanip.html#.BitArray

In the future, please explain what problem you are trying to 
solve, as the wrong code alone often leaves one guessing.


Ivan Kazmenko.


Re: refactoring issues

2015-03-22 Thread Ivan Kazmenko via Digitalmars-d-learn
On Friday, 20 March 2015 at 18:37:57 UTC, Vladimir Panteleev 
wrote:
On Friday, 20 March 2015 at 18:36:19 UTC, Vladimir Panteleev 
wrote:

On Friday, 20 March 2015 at 18:05:07 UTC, Ivan Kazmenko wrote:
Thanks.  I was able to reproduce the workflow you showed in 
the gif to the part where an error pop-up (e.g. no property 
iota for type int) is followed by suggesting the appropriate 
fix.  Do I need another tool for that?  Colorout does not 
seem to suggest fixes.


OK, here it is:

https://github.com/CyberShadow/AutoFix

It has some hardcoded paths though.


It's used like this:

C:\Path\To\colorout\colorout ^
 --json C:\Temp\colorout.json ^
 --trigger id=C:\Path\To\AutoFix\autofix.exe ^
 C:\Path\To\colorout\d.col ^
 dmd, rdmd etc...


Yay, I finally got it working!  Thank you, it feels nice.

Theoretically, AutoFix can be extended to handle cases similar to 
mine, though the details may be cumbersome.  The template 
constraint is reported by the compiler, so the identifier to be 
imported is right there in the error message. One may just 
tokenize the string and loop over the identifiers...  But that 
will perhaps generate too much noise in suggestions.


The biggest thing to learn for me however was that I can use JSON 
files of Phobos and druntime, which in turn can be generated by 
building them.


Ivan Kazmenko.


Re: The difference in string and char[], readf() and scanf()

2015-03-21 Thread Ivan Kazmenko via Digitalmars-d-learn

On Saturday, 21 March 2015 at 14:31:20 UTC, Dennis Ritchie wrote:

In C++ it is fully working:

char s[25], t[25];
scanf(%s%s, s, t);


Indeed.

Generate a 10-character string:
-
import std.range, std.stdio;
void main () {'a'.repeat (10).writeln;}
-

Try to copy it with D scanf and printf:
-
import std.stdio;
void main () {
char [10] a;
scanf (%s, a.ptr);
printf (%s\n, a.ptr);
}
-

Only 32767 first characters of the string are actually copied.


Re: The difference in string and char[], readf() and scanf()

2015-03-21 Thread Ivan Kazmenko via Digitalmars-d-learn

On Saturday, 21 March 2015 at 16:34:44 UTC, Dennis Ritchie wrote:
And why in D copied only the first 32767 characters of the 
string? I'm more days couldn't understand what was going on...


To me, it looks like a bug somewhere, though I don't get where 
exactly.  Is it in bits of DigitalMars C/C++ compiler code glued 
into druntime?


Anyway, as for Codeforces problems, you mostly need to read text 
input as tokens separated by spaces and/or newlines.  For that, D 
I/O is sufficient, there is no need to use legacy C++ I/O.


Usually, readf( %s, v) works for every scalar type of variable 
v (including reals and 64-bit integers) except strings, and 
readln() does the thing for strings.  Don't forget to get rid of 
the newline sequence on the previous line if you mix the two.  
Possible leading and trailing spaces in  %s  mean skipping all 
whitespace before or after the token, respectively, as is the 
case for scanf in C/C++.


As far as I remember, for reading a line of numbers separated by 
spaces,

-
auto a = readln.split.map!(to!int).array;
-
is a bit faster than a loop of readf filling the array, but that 
hardly matters in the majority of problems.  You can see my 
submissions (http://codeforces.com/submissions/Gassa) for example.


If you really feel the need for I/O better suited for the 
specifics of algorithmic programming contests (as Java people 
almost always do in their language for some reason), look at 
Kazuhiro Hosaka's submissions 
(http://codeforces.com/submissions/hos.lyric).


In case you want to go even further and write your own I/O layer 
for that, I'll point you to a recent discussion of text I/O 
methods here: http://stackoverflow.com/q/28922323/1488799 (see 
comments and answers).


Ivan Kazmenko.


Re: refactoring issues

2015-03-20 Thread Ivan Kazmenko via Digitalmars-d-learn
On Thursday, 19 March 2015 at 16:06:31 UTC, Vladimir Panteleev 
wrote:

On Thursday, 19 March 2015 at 14:32:53 UTC, Ivan Kazmenko wrote:
Hey, I also happen to use Far Manager and its internal editor, 
at least for simple projects.  Is that dcheck triggering a Far 
plugin?  I have a bit of experience with Far recording macros, 
but didn't try to write a plugin.


It's all a bit of a mess... A FAR Lua macro[1] runs dcheck, 
which is just a batch file that runs DMD piped through 
colorout[2], which in turn parses the compiler output and 
records the results to a temporary file, that's read by a 
second program that parses and caches the .json files generated 
as part of my D build process and then generates editing 
instructions read back by the Lua macro.


[1]http://dump.thecybershadow.net/5c0afb5c0f4306b1368dd8528c838133/F9.lua
[2]http://blog.thecybershadow.net/2013/07/27/colorize-your-compilers-output/


Thanks.  I was able to reproduce the workflow you showed in the 
gif to the part where an error pop-up (e.g. no property iota for 
type int) is followed by suggesting the appropriate fix.  Do I 
need another tool for that?  Colorout does not seem to suggest 
fixes.


Also, what about this?

2. When the compiler could not find a suitable overload of a 
function, if there are template and non-template overloads, it 
lists only non-template overloads.


Since no one replied by rationalizing that it works as intended, 
perhaps I should file an issue about it?


Ivan Kazmenko.


Re: refactoring issues

2015-03-19 Thread Ivan Kazmenko via Digitalmars-d-learn
On Thursday, 19 March 2015 at 10:21:09 UTC, Vladimir Panteleev 
wrote:

On Tuesday, 17 March 2015 at 15:11:02 UTC, Ivan Kazmenko wrote:
For the former problem, is there a tool which jumps out and 
tells you use Phobos without importing things properly, or 
suggests a Phobos import by the name of the stuff.


I did make something simple for myself, but it doesn't work in 
the more complicated cases you mentioned (contracts failing 
because of missing imports).


http://dump.thecybershadow.net/e91be687ebaeb0171d830025adf82848/autofix.gif

I could post the code but the editor integration part is pretty 
specific to my editor.


Hey, I also happen to use Far Manager and its internal editor, at 
least for simple projects.  Is that dcheck triggering a Far 
plugin?  I have a bit of experience with Far recording macros, 
but didn't try to write a plugin.


refactoring issues

2015-03-17 Thread Ivan Kazmenko via Digitalmars-d-learn

Hi,

I was just refactoring a project to compile under 2.067.

The fixes themselves were trivial: just adding import 
std.traits; to some files.  Apparently its pieces were publicly 
imported by another module in 2.066.  So, it's the right fix 
anyway.


Understanding what happened, however, took more time than fixing. 
 Surely, the compiler couldn't just say hey, I know, you forgot 
to import std.traits!, and threw some distant consequences at me 
instead.  Essentially, there were two complications:


1. In a complex template constraint, if some identifier 
disappears out of scope, the whole constraint silently fails, and 
the whole template instantiation fails with a rather generic 
error message.


2. When the compiler could not find a suitable overload of a 
function, if there are template and non-template overloads, it 
lists only non-template overloads.


My question therefore is: can the process be improved somehow to 
address the above issues?  For the former problem, is there a 
tool which jumps out and tells you use Phobos without importing 
things properly, or suggests a Phobos import by the name of the 
stuff.  For the latter one, I wonder if this is the intended 
behavior.


Ivan Kazmenko.


  1   2   >