digitalmars.D.learn - array of randomly generated names
- spir (43/43) Oct 15 2010 Hello,
- Jesse Phillips (26/26) Oct 15 2010 First listen to Jonathan. Data should be accepted in as strings and retu...
- Simen kjaeraas (17/33) Oct 16 2010 Here's my version of the same, in highly unidiomatic D:
- Steven Schveighoffer (9/32) Oct 16 2010 Can't you just use addition?
Hello, A few questions raised by a single func. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D alias char[] Text ; Text letters =3D ['a','b','c',...] ; Text[] nameSet (uint count , uint size) { /* set of count random names of size size */ Text[] names ; names.length =3D count ; Text name ; name.length =3D size ; for (int i=3D0 ; i<count ; i++) { for (int j=3D0 ; j<size ; j++) name[j] =3D letters[uniform(0u,26u)] ; names[i].length =3D size ; names[i][] =3D name ; } return names ; } =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 1. In the inner loop generating name, I have found neither a way to feed d= irectly ints into name, nore a way to cast ints to chars using to! (also fo= und no chr()). So, I had to list letters. But this wouldn't work with a wid= e range of unicode chars... How to build name directly from random ints? 2. I was surprised to get all names equal... Seems that "names[i] =3D name"= actually copies a ref to the name. Is there another way to produce a copy = than "names[i][] =3D name"? 3. As you see, I individually set the length of each names[i] in the outer = loop. (This, only to be able to copy, else the compiler complains about une= quals lengths.) How can I set the length of all elements of names once and = for all? 4. Is there a kind of map(), or a syntax like list comprehension, to genera= te array content from a formula? (This would here replace both loops.) 5. Seems there is no auto-conversion between char[] and string. Thus, I use= only char[], else I'm constantly blocked with immutability. But for this r= eason I cannot use nice facilities to construct text expressions, like form= at(). Also, I need to convert every literal, even chars, when they must go = into a char[]. Grrr! Even to initialise: Text text =3D to!Text("start text") ; Hints welcome. Thank you, Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Oct 15 2010
First listen to Jonathan. Data should be accepted in as strings and returned as strings (supporting wstring, dstring is fine). Your function should then build on a local dchar[] and convert it to string when finished. There are some algorithms that will help with the method you are using. However, if you wish to generate names you'll likely want to have more than just random letters. The examples below do not compile on ideone because of a bug in the 2.042 compiler used. They work with 2.049. http://ideone.com/7c6cr import alg = std.algorithm; import std.stdio; import std.string; import std.conv; import std.random; string makeName(uint wordSize) { auto rnd = Random(unpredictableSeed); dchar[] newWord = new dchar[wordSize]; alg.fill(newWord[], randomCover(lowercase[], rnd)); return to!string(newWord); } void main() { writeln(makeName(6)); } As you can see I did not build you an array of words, but this is just to push you in the correct direction. The slices of newWord and lowercase (provided by std.string) are required. And now that you know of a few nice library functions (std.algorithm.fill) Let us move on to creating a Range of names so you can make use of this to fill an array of names instead of letters. http://ideone.com/jtbtn As it is a larger piece of code I do not wish to duplicate it here. The code is mostly the same just stored in a struct and the functions: front, empty, popFront, save. By doing this you can use an assortment of functions found in std.algorithm[1]. Not all of functions will work with the Range I have created, as there are many types of ranges[2]: InputRange, OutputRange, ForwardRange, BidirectionalRange, RandomAccessRange, Infinite (I only covered InputRange, ForwardRange, Infinite). However that is really just the list of named ranges, there are even more requirements that may come up. At last I digress. I hope your interest has been obtained on some of this and maybe it explains why some things just don't work as you are expecting. Any questions on a specific item you can start a new thread for. And comments about the code from other onlookers is also welcome. 1. http://digitalmars.com/d/2.0/phobos/std_algorithm.html 2. http://digitalmars.com/d/2.0/phobos/std_range.html
Oct 15 2010
spir <denis.spir gmail.com> wrote:=================== alias char[] Text ; Text letters = ['a','b','c',...] ; Text[] nameSet (uint count , uint size) { /* set of count random names of size size */ Text[] names ; names.length = count ; Text name ; name.length = size ; for (int i=0 ; i<count ; i++) { for (int j=0 ; j<size ; j++) name[j] = letters[uniform(0u,26u)] ; names[i].length = size ; names[i][] = name ; } return names ; } ===================Here's my version of the same, in highly unidiomatic D: auto nameSet( uint count, uint size ) { auto randomWordsRandomLength = map!"a()"( repeat({ return repeat({ return cast(char)iota(65,91)[ uniform( 0, 26 ) ]; }); }) ); return array( take( map!( ( randomWord ){ return array( take( map!"a()"( randomWord ), size ) ); })( randomWordsRandomLength ), count ) ); } -- Simen
Oct 16 2010
On Fri, 15 Oct 2010 15:50:53 -0400, spir <denis.spir gmail.com> wrote:Hello, A few questions raised by a single func. =================== alias char[] Text ; Text letters = ['a','b','c',...] ; Text[] nameSet (uint count , uint size) { /* set of count random names of size size */ Text[] names ; names.length = count ; Text name ; name.length = size ; for (int i=0 ; i<count ; i++) { for (int j=0 ; j<size ; j++) name[j] = letters[uniform(0u,26u)] ; names[i].length = size ; names[i][] = name ; } return names ; } =================== 1. In the inner loop generating name, I have found neither a way to feed directly ints into name, nore a way to cast ints to chars using to! (also found no chr()). So, I had to list letters. But this wouldn't work with a wide range of unicode chars... How to build name directly from random ints?Can't you just use addition? i.e. i = 0-25 mapped to letters a-z is cast(char)('a' + i) If you are going for unicode, I'd suggest using wchar or dchar (which could be directly cast from integers) to build the string, and then use to!(char[])(widename); Finally, I'd suggest accepting a dchar[] letters as a third optional parameter in case someone wants names in a specific language. -Steve
Oct 16 2010