How to resolve the algorithm Iterated digits squaring step by step in the D programming language

Published on 12 May 2024 09:40 PM
#D

How to resolve the algorithm Iterated digits squaring step by step in the D programming language

Table of Contents

Problem Statement

If you add the square of the digits of a Natural number (an integer bigger than zero), you always end with either 1 or 89: An example in Python:

Or, for much less credit - (showing that your algorithm and/or language is slow): This problem derives from the Project Euler problem 92. For a quick algorithm for this task see the talk page

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Iterated digits squaring step by step in the D programming language

Source code in the d programming language

import std.stdio, std.algorithm, std.range, std.functional;

uint step(uint x) pure nothrow @safe @nogc {
    uint total = 0;
    while (x) {
        total += (x % 10) ^^ 2;
        x /= 10;
    }
    return total;
}

uint iterate(in uint x) nothrow @safe {
    return (x == 89 || x == 1) ? x : x.step.memoize!iterate;
}

void main() {
    iota(1, 100_000_000).filter!(x => x.iterate == 89).count.writeln;
}


void main() nothrow @nogc {
    import core.stdc.stdio: printf;

    enum uint magic = 89;
    enum uint limit = 100_000_000;
    uint[(9 ^^ 2) * 8 + 1] lookup = void;

    uint[10] squares;
    foreach (immutable i, ref x; squares)
        x = i ^^ 2;

    foreach (immutable uint i; 1 .. lookup.length) {
        uint x = i;

        while (x != magic && x != 1) {
            uint total = 0;
            while (x) {
                total += squares[(x % 10)];
                x /= 10;
            }
            x = total;
        }

        lookup[i] = x == magic;
    }

    uint magicCount = 0;
    foreach (immutable uint i; 1 .. limit) {
        uint x = i;
        uint total = 0;

        while (x) {
            total += squares[(x % 10)];
            x /= 10;
        }

        magicCount += lookup[total];
    }

    printf("%u\n", magicCount);
}


import core.stdc.stdio, std.algorithm, std.range;

enum factorial = (in uint n) pure nothrow @safe @nogc
    => reduce!q{a * b}(1u, iota(1u, n + 1));

uint iLog10(in uint x) pure nothrow @safe @nogc
in {
    assert(x > 0);
} body {
    return (x >= 1_000_000_000) ? 9 :
           (x >=   100_000_000) ? 8 :
           (x >=    10_000_000) ? 7 :
           (x >=     1_000_000) ? 6 :
           (x >=       100_000) ? 5 :
           (x >=        10_000) ? 4 :
           (x >=         1_000) ? 3 :
           (x >=           100) ? 2 :
           (x >=            10) ? 1 : 0;
}

uint nextStep(uint x) pure nothrow @safe @nogc {
    typeof(return) result = 0;

    while (x > 0) {
        result += (x % 10) ^^ 2;
        x /= 10;
    }
    return result;
}

uint check(in uint[] number) pure nothrow @safe @nogc {
    uint candidate = reduce!((tot, n) => tot * 10 + n)(0, number);

    while (candidate != 89 && candidate != 1)
        candidate = candidate.nextStep;

    if (candidate == 89) {
        uint[10] digitsCount;
        foreach (immutable d; number)
            digitsCount[d]++;

        return reduce!((r, c) => r / c.factorial)
                      (number.length.factorial, digitsCount);
    }

    return 0;
}

void main() nothrow @nogc {
    enum uint limit = 100_000_000;
    immutable uint cacheSize = limit.iLog10;

    uint[cacheSize] number;
    uint result = 0;
    uint i = cacheSize - 1;

    while (true) {
        if (i == 0 && number[i] == 9)
            break;
        if (i == cacheSize - 1 && number[i] < 9) {
            number[i]++;
            result += number.check;
        } else if (number[i] == 9) {
            i--;
        } else {
            number[i]++;
            number[i + 1 .. $] = number[i];
            i = cacheSize - 1;
            result += number.check;
        }
    }

    printf("%u\n", result);
}


import std.stdio, std.typecons, std.traits, std.typetuple, std.range, std.algorithm;

auto divMod(T)(T x, T y) pure nothrow @safe @nogc {
    return tuple(x / y, x % y);
}

auto expand(alias F, B)(B x) pure nothrow @safe @nogc
if (isCallable!F &&
    is(ParameterTypeTuple!F == TypeTuple!B)
    && __traits(isSame, TemplateOf!(ReturnType!F), Nullable)
    && isTuple!(TemplateArgsOf!(ReturnType!F)[0])
    && is(TemplateArgsOf!(TemplateArgsOf!(ReturnType!F)[0])[1] == B)) {

    alias NAB = ReturnType!F;
    alias AB = TemplateArgsOf!NAB[0];
    alias A = AB.Types[0];

    struct Expand {
        bool first;
        NAB last;

        @property bool empty() pure nothrow @safe @nogc {
            if (first) {
                first = false;
                popFront;
            }
            return last.isNull;
        }

        @property A front() pure nothrow @safe @nogc {
            if (first) {
                first = false;
                popFront;
            }
            return last.get[0];
        }

        void popFront() pure nothrow @safe @nogc { last = F(last.get[1]); }
    }

    return Expand(true, NAB(AB(A.init, x)));
}

//------------------------------------------------

uint step(uint x) pure nothrow @safe @nogc {
    Nullable!(Tuple!(uint, uint)) f(uint n) pure nothrow @safe @nogc {
        return (n == 0) ? typeof(return)() : typeof(return)(divMod(n, 10u).reverse);
    }

    return expand!f(x).map!(x => x ^^ 2).sum;
}

uint iter(uint x) pure nothrow @nogc {
    return x.recurrence!((a, n) => step(a[n - 1])).filter!(y => y.among!(1, 89)).front;
}

void main() {
    iota(1u, 100_000u).filter!(n => n.iter == 89).count.writeln;
}


  

You may also check:How to resolve the algorithm Loops/Nested step by step in the OCaml programming language
You may also check:How to resolve the algorithm Conway's Game of Life step by step in the Rust programming language
You may also check:How to resolve the algorithm Dinesman's multiple-dwelling problem step by step in the Picat programming language
You may also check:How to resolve the algorithm Quine step by step in the PowerBASIC programming language
You may also check:How to resolve the algorithm Binary digits step by step in the PowerShell programming language