Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
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] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jos van Uden | 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] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jos van Uden | 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] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | 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] | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | 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] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jos van Uden | 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] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | 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] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | "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] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jos van Uden | > 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);
}
|
Copyright © 1999-2021 by the D Language Foundation