Can this implementation of Damm algorithm be optimized?
Daniel Kozak via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Thu Feb 9 12:46:06 PST 2017
Dne 9.2.2017 v 20:39 Nestor via Digitalmars-d-learn napsal(a):
> On Thursday, 9 February 2017 at 18:34:30 UTC, Era Scarecrow wrote:
>> On Thursday, 9 February 2017 at 17:36:11 UTC, Nestor wrote:
>>> I was trying to port C code from the article in Wikiversity [1] to
>>> D, but I'm not sure this implementation is the most efficient way to
>>> do it in D, so suggestions to optimize it are welcome:
>>>
>>> import std.stdio;
>>>
>>> static immutable char[] QG10Matrix =
>>> "03175986427092154863420687135917509834266123045978" ~
>>> "36742095815869720134894536201794386172052581436790";
>>>
>>> char checkDigit(string str) {
>>> char tmpdigit = '0';
>>> foreach(chr; str) tmpdigit = QG10Matrix[(chr - '0') + (tmpdigit -
>>> '0') * 10];
>>> return tmpdigit;
>>> }
>>
>> Well one thing is you can probably reduce them from chars to just
>> bytes, instead of having to subtract you can instead add at the end.
>> Although unless you're working with a VERY large input you won't see
>> a difference.
>>
>> Actually since you're also multiplying by 10, you can incorporate
>> that in the table too... (although a mixin might be better for the
>> conversion than by hand)
>>
>>
>> static immutable char[] QG10Matrix = [
>> 00,30,10,70,50,90,80,60,40,20,
>> 70,00,90,20,10,50,40,80,60,30,
>> 40,20,00,60,80,70,10,30,50,90,
>> 10,70,50,00,90,80,30,40,20,60,
>> 60,10,20,30,00,40,50,90,70,80,
>> 30,60,70,40,20,00,90,50,80,10,
>> 50,80,60,90,70,20,00,10,30,40,
>> 80,90,40,50,30,60,20,00,10,70,
>> 90,40,30,80,60,10,70,20,00,50,
>> 20,50,80,10,40,30,60,70,90,00];
>>
>> char checkDigit(string str) {
>> char tmpdigit = 0;
>> foreach(chr; str) tmpdigit = QG10Matrix[(chr - '0') +
>> tmpdigit];
>> return (tmpdigit/10) + '0';
>> }
>
>
>
> OK I changed the approach using a multidimensional array for the
> matrix so I could ditch arithmetic operations altogether, but
> curiously after measuring a few thousand runs of both implementations
> through avgtime, I see no noticeable difference. Why?
>
> import std.stdio;
>
> static immutable ubyte[][] QG10Matrix = [
> [0,3,1,7,5,9,8,6,4,2],[7,0,9,2,1,5,4,8,6,3],
> [4,2,0,6,8,7,1,3,5,9],[1,7,5,0,9,8,3,4,2,6],
> [6,1,2,3,0,4,5,9,7,8],[3,6,7,4,2,0,9,5,8,1],
> [5,8,6,9,7,2,0,1,3,4],[8,9,4,5,3,6,2,0,1,7],
> [9,4,3,8,6,1,7,2,0,5],[2,5,8,1,4,3,6,7,9,0],
> ];
>
> static int charToInt(char chr) {
> scope(failure) return -1;
> return cast(int)(chr - '0');
> }
>
> ubyte checkDigit(string str) {
> ubyte tmpdigit;
> foreach(chr; str) tmpdigit = QG10Matrix[tmpdigit][charToInt(chr)];
> return tmpdigit;
> }
>
> enum {
> EXIT_SUCCESS = 0,
> EXIT_FAILURE = 1,
> }
>
> int main(string[] args) {
> scope(failure) {
> writeln("Invalid arguments. You must pass a number.");
> return EXIT_FAILURE;
> }
> assert(args.length == 2);
> ubyte digit = checkDigit(args[1]);
> if(digit == 0) writefln("%s is a valid number.", args[1]);
> else {
> writefln("%s is not a valid number (but it would be, appending
> digit %s).",
> args[1], digit);
> }
>
> return EXIT_SUCCESS;
> }
>
Maybe you can try use static array instead of dynamic
static immutable ubyte[10][10] QG10Matrix = ...
More information about the Digitalmars-d-learn
mailing list