View mode: basic / threaded / horizontal-split · Log in · Help
January 15, 2012
[your code here]
import std.conv, std.traits, std.ascii;

S rot13(S)(S s) if (isSomeString!S) {
    return rot(s, 13);
}

S rot(S)(S s, int key) if (isSomeString!S) {
    dchar[] r = new dchar[s.length];

    foreach (i, dchar c; s) {
        if (isLower(c))
            c = ((c - 'a' + key) % 26 + 'a');
        else if (isUpper(c))
            c = ((c - 'A' + key) % 26 + 'A');
        r[i] = c;
    }
    return to!S(r);
}


---

still learning this stuff, feel free to correct or improve

Jos
January 15, 2012
Re: [your code here]
Jos van Uden:

> still learning this stuff, feel free to correct or improve

Next time I suggest you to use D.learn.

This is a first draft with some changes:

import std.traits, std.string, std.ascii, std.conv, std.range;

// is partial application better here?
dstring rot13(C)(immutable(C[]) s) pure /*nothrow*/
if (isSomeChar!C) {
   return rot(s, 13);
}

// or maybe just use in int key=13 as default argument
// is it right to use a signed int for key?
dstring rot(C)(immutable(C[]) s, in int key) pure /*nothrow*/
if (isSomeChar!C)
in {
   // preconditions here...
   // only ASCII input chars?
   // Are std.ascii.isUpper / isLower working with UTF?
} out(result) {
   // don't use .length here unless the input is verified to contain
   // no past ASCII chars
   assert(walkLength(s) == walkLength(result));
} body {
   auto result = new dchar[s.length];

   foreach (i, dchar c; s) { // not nothrow
       // reassigning c here is not nice
       if (isLower(c))
           result[i] = ((c - 'a' + key) % 26 + 'a');
       else if (isUpper(c))
           result[i] = ((c - 'A' + key) % 26 + 'A');
   }

    return result; // implicit cast, but only dstring output.
    // Otherwise allocate a result with alloca() and copy
    // it at the end with to!S(result)
} unittest {
   // unit tests here...
}

void main() {
   import std.stdio;
   writeln(rot13("hello"));
}

Your little program also shows some of the current D2 problems. You need care to catch a function signature like that that allows implicit cast of the result of the pure function.

Bye,
bearophile
January 15, 2012
Re: [your code here]
On 1/15/12 8:23 AM, Jos van Uden wrote:
> import std.conv, std.traits, std.ascii;
>
> S rot13(S)(S s) if (isSomeString!S) {
> return rot(s, 13);
> }
>
> S rot(S)(S s, int key) if (isSomeString!S) {
> dchar[] r = new dchar[s.length];
>
> foreach (i, dchar c; s) {
> if (isLower(c))
> c = ((c - 'a' + key) % 26 + 'a');
> else if (isUpper(c))
> c = ((c - 'A' + key) % 26 + 'A');
> r[i] = c;
> }
> return to!S(r);
> }
>
>
> ---
>
> still learning this stuff, feel free to correct or improve
>
> Jos

Thanks! Well, we don't have yet the javascript that rotates the 
examples. Would anyone be interested to work on that?

Andrei
January 15, 2012
Re: [your code here]
Andrei Alexandrescu:

> Thanks! Well, we don't have yet the javascript that rotates the 
> examples. Would anyone be interested to work on that?

Do you want a large amount of D2 "examples"? Have you seen this page?
http://rosettacode.org/wiki/Category:D

Bye,
bearophile
January 15, 2012
Re: [your code here]
On 1/15/12 9:26 AM, bearophile wrote:
> Andrei Alexandrescu:
>
>> Thanks! Well, we don't have yet the javascript that rotates the
>> examples. Would anyone be interested to work on that?
>
> Do you want a large amount of D2 "examples"? Have you seen this page?
> http://rosettacode.org/wiki/Category:D
>
> Bye,
> bearophile

Great! For now it would be great to have the code that rotates the 
script on our homepage.

Andrei
January 15, 2012
Re: [your code here]
On 01/15/2012 03:23 PM, Jos van Uden wrote:
> import std.conv, std.traits, std.ascii;
>
> S rot13(S)(S s) if (isSomeString!S) {
> return rot(s, 13);
> }
>
> S rot(S)(S s, int key) if (isSomeString!S) {
> dchar[] r = new dchar[s.length];
>
> foreach (i, dchar c; s) {
> if (isLower(c))
> c = ((c - 'a' + key) % 26 + 'a');
> else if (isUpper(c))
> c = ((c - 'A' + key) % 26 + 'A');
> r[i] = c;
> }
> return to!S(r);
> }
>
>
> ---
>
> still learning this stuff, feel free to correct or improve
>
> Jos

Your code will fail for narrow strings containing Unicode.
dchar[] r = new dchar[s.length]; // creates a new dchar[] with as many 
elements as there are code units in the input string

You can use std.range.walkLength to get the number of code points.

Furthermore, that line mentions the type twice.

auto r = new dchar[s.walkLength()];
January 15, 2012
Re: [your code here]
On 15-1-2012 17:26, Timon Gehr wrote:
> On 01/15/2012 03:23 PM, Jos van Uden wrote:
>> import std.conv, std.traits, std.ascii;
>>
>> S rot13(S)(S s) if (isSomeString!S) {
>> return rot(s, 13);
>> }
>>
>> S rot(S)(S s, int key) if (isSomeString!S) {
>> dchar[] r = new dchar[s.length];
>>
>> foreach (i, dchar c; s) {
>> if (isLower(c))
>> c = ((c - 'a' + key) % 26 + 'a');
>> else if (isUpper(c))
>> c = ((c - 'A' + key) % 26 + 'A');
>> r[i] = c;
>> }
>> return to!S(r);
>> }
>>
>>
>> ---
>>
>> still learning this stuff, feel free to correct or improve
>>
>> Jos
>
> Your code will fail for narrow strings containing Unicode.
> dchar[] r = new dchar[s.length]; // creates a new dchar[] with as many
> elements as there are code units in the input string
>
> You can use std.range.walkLength to get the number of code points.
>
> Furthermore, that line mentions the type twice.
>
> auto r = new dchar[s.walkLength()];

Thank you.

---

S rot13(S)(S s) if (isSomeString!S) {
    return rot(s, 13);
}

S rot(S)(S s, int key) if (isSomeString!S) {
    auto r = new dchar[s.walkLength()];

    foreach (i, dchar c; s) {
        if (isLower(c))
            r[i] = ((c - 'a' + key) % 26 + 'a');
        else if (isUpper(c))
            r[i] = ((c - 'A' + key) % 26 + 'A');
    }
    return to!S(r);
}
January 15, 2012
[OT] Re: [your code here]
"Andrei Alexandrescu" <SeeWebsiteForEmail@erdani.org> wrote in message 
news:jeuqua$1gfg$3@digitalmars.com...
>
> Thanks! Well, we don't have yet the javascript that rotates the examples. 
> Would anyone be interested to work on that?
>

Speaking of d-p-l.org contributions, #39 has been merged and could use to be 
put up on the site. Not to nag about it, just a friendly heads-up.
February 11, 2012
Re: [your code here]
> S rot13(S)(S s) if (isSomeString!S) {
> return rot(s, 13);
> }
>
> S rot(S)(S s, int key) if (isSomeString!S) {
> auto r = new dchar[s.walkLength()];
>
> foreach (i, dchar c; s) {
> if (isLower(c))
> r[i] = ((c - 'a' + key) % 26 + 'a');
> else if (isUpper(c))
> r[i] = ((c - 'A' + key) % 26 + 'A');
> }
> return to!S(r);
> }

this is better

S rot13(S)(in S s) if (isSomeString!S) {
    return rot(s, 13);
}

S rot(S)(in S s, in int key) if (isSomeString!S) {
    auto r = new dchar[s.walkLength];

    foreach (i, dchar c; s) {
        if (std.ascii.isLower(c))
            c = ((c - 'a' + key) % 26 + 'a');
        else if (std.ascii.isUpper(c))
            c = ((c - 'A' + key) % 26 + 'A');
        r[i] = c;
    }
    return to!S(r);
}
Top | Discussion index | About this forum | D home