Re: length's type.
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
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
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?
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
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
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?
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?
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?
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?
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?
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?
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?
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
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
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?
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?
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?
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(&func).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 then). 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. Ivan Kazmenko.
Re: writeln() sometimes double prints from main() if I run a thread checking for input?
On Wednesday, 30 August 2017 at 10:55:20 UTC, Timothy Foster wrote: import std.stdio, core.thread; void main(){ auto thread = new Thread(&func).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?
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
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
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
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
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
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
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!
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!
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]
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]
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
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
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
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
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 see
Re: How to avoid throwing an exceptions for a built-in function?
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.
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", &x); 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", &x, &y); // error, got space for y instead of a digit readf ("%s %s", &x, &y); // 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?
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
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
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?
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
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?
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
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
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
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
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: switch to member
On Saturday, 14 January 2017 at 03:20:24 UTC, Ignacious wrote: switch(x) { case X: q.X = e; break; case Y: q.Y = e; break etc... } Do you mean that verbatim? Or are the case values strings, like: switch(x) { case "foo": q.foo = e; break; case "bar": q.bar = e; break } I imagine one could write a string mixin that generates the cases and assignments but I'm hoping for a more elegant solution. In any case, I also can imagine a mixin answer, but not much better. Unless you want to actually look at the broader picture and maybe redesign the surrounding code to somehow cleverly get rid of the switch altogether. The question as it is however doesn't give the context to make it possible. Ivan Kazmenko.
Re: Getch() Problem: C vs D
On Monday, 9 January 2017 at 17:22:41 UTC, LouisHK wrote: On Monday, 9 January 2017 at 13:10:30 UTC, Adam D. Ruppe wrote: ... Best solution is to skip those C library functions and do it yourself with the OS-level calls. Then you can turn it off and actually control the buffering behavior. That's what I was afraid of. I even tried your terminal.d, and it worked for those keys above, but unfortunately it's duplicating the values, one little example (From your source): if(input.kbhit()){ auto c = input.getch(); write(c); } As I could see with WinDBG, the condition "input.kbhit()" is true for the first 2 times after I hit a key. That's because special keys actually put two characters in the buffer, right? Otherwise, using that buffer alone, you won't be able to distinguish, for example, arrow keys from capital Latin letters with the same codes.
Re: opOpAssign on object properties
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
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
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?
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?
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?
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
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
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
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
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", &A);". 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
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: Get the return type of the function
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: inner functions calling each other - how to do this with inner struct?
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.
inner functions calling each other - how to do this with inner struct?
Hi, 1. What works. Inside a function (outerFun), I've got inner functions fun1 and fun2 which have to recursively call each other. Just writing them one after the other does not work. I've managed to find a trick to make it work though, which is to add empty compile-time parameters to fun1 and fun2: - import std.stdio; void outerFun () { void fun1 () (int x) { writeln (x); if (x > 0) fun2 (x - 1); } void fun2 () (int y) { writeln (y); if (y > 1) fun1 (y - 2); } fun2 (10); } void main () {outerFun ();} - 2. What doesn't work. Next, I'd like to have an inner function fun1 and an inner struct S with a method fun2, and an instance s of struct S. I want to be able to call s.fun2 from fun1 and fun1 back from s.fun2. Now, I can't figure out how to do that. The same trick does not seem to work: - import std.stdio; void outerFun () { struct S () { void fun2 (int x) { writeln (x); if (x > 0) fun1 !() (x - 1); } } S !() s; void fun1 () (int y) { writeln (y); if (y > 1) s.fun2 (y - 2); } fun1 (10); } void main () {outerFun ();} - Here are the errors I get: - test2.d(7): Error: template instance fun1!() template 'fun1' is not defined, did you mean fun2? test2.d(11): Error: template instance test2.outerFun.S!() error instantiating - So, is this mutual recursion (inner function and method of a fixed instance of an inner struct) possible? This does not seem theoretically wrong: we have to maintain exactly one outer context pointer (to outerFun's current stack frame) for each recursive call. 3. What also doesn't work. Here is another attempt, where the outer scope is a struct, not a function. Again, I want to be able to call fun1 from s.fun2 and s.fun2 from fun1. - import std.stdio; struct outerStruct { struct S { void fun2 (int x) { writeln (x); if (x > 0) fun1 (x - 1); } } S s; void fun1 (int y) { writeln (y); if (y > 1) s.fun2 (y - 2); } } void main () {outerStruct os; os.fun1 (10);} - With no compile-time parameters, this just says: - test3.d(7): Error: this for fun1 needs to be type outerStruct not type S - Apparently, the call to fun1 is not able to get the context pointer to outerStruct os and use it to call fun1. Again, I don't see a theoretical limitation here. Did I fail to express my intent to the compiler, or is what I want impossible with the current implementation? 4. Module scope. At module scope (no outer context pointer needed), everything works fine without the need for tricks: - import std.stdio; struct S { void fun2 (int x) { writeln (x); if (x > 0) fun1 (x - 1); } } S s; void fun1 (int y) { writeln (y); if (y > 1) s.fun2 (y - 2); } void main () {fun1 (10);} - Ivan Kazmenko.
Re: merging map/filter/reduce/... in D
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 ?
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
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
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
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
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?
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
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?
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?
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
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 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
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?
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?
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?
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?
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?
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( &foo ); // 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
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?
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.
Re: forward range properties with alias this - how?
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.
forward range properties with alias this - how?
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.
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
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?
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
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
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
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
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
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
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
On Wednesday, 25 March 2015 at 20:09:53 UTC, bearophile wrote: Dennis Ritchie: A more effective solution for C ++: #include #include #include int main() { using namespace ranges; auto rng = istream( std::cin ) | to_vector | action::sort | view::group_by( std::equal_to() ) | 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
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
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 #include #include int main() { using namespace ranges; auto rng = istream( std::cin ) | to_vector | action::sort | view::group_by( std::equal_to() ) | 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
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
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
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()
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: The difference in string and char[], readf() and scanf()
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.