On Tuesday, 12 March 2024 at 06:38:28 UTC, Richard (Rikki) Andrew Cattermole wrote:
By taking advantage of integer wrapping and a bitwise and, its quite a simple problem to solve!

Challenge for the reader: add support for binary operations and toString support.

https://dlang.org/spec/operatoroverloading.html

```d
struct Direction {
    private int value;

    Direction opUnary(string op:"++")() {
        value++;
        value &= 7;
        return this;
    }

    Direction opUnary(string op:"--")() {
        value--;
        value &= 7;
        return this;
    }

    void opOpAssign(string op:"+")(int amount) {
        value += amount;
        value &= 7;
    }

    void opOpAssign(string op:"-")(int amount) {
        value -= amount;
        value &= 7;
    }

    enum Direction N = Direction(0);
    enum Direction NE = Direction(1);
    enum Direction E = Direction(2);
    enum Direction SE = Direction(3);
    enum Direction S = Direction(4);
    enum Direction SW = Direction(5);
    enum Direction W = Direction(6);
    enum Direction NW = Direction(7);
}

unittest {
     Direction direction = Direction.N;
     direction++;
     assert(direction == Direction.NE);
     direction+=3;
     assert(direction == Direction.S);
     direction--;
     assert(direction == Direction.SE);
     direction-=4;
     assert(direction == Direction.NW);
}
```

Interesting. I didn't know that an enum can be defined inside a struct like that. I had used functions to get around it.

Here is what I had already mostly written, using help from ChatGPT (but only for the opUnary syntax, not the algorithm):
```
struct Direction //One of 8 directions stored in 3 bits
{
    bool[3] d;

static Direction N() { return Direction(d:[false,false,false]); } static Direction NE() { return Direction(d:[false,false,true]); } static Direction E() { return Direction(d:[false,true,false]); } static Direction SE() { return Direction(d:[false,true,true]); } static Direction S() { return Direction(d:[true,false,false]); } static Direction SW() { return Direction(d:[true,false,true]); } static Direction W() { return Direction(d:[true,true,false]); } static Direction NW() { return Direction(d:[true,true,true]); }

ref Direction opUnary(string op)() if (op == "++" || op == "--") {
        if (op == "++") const bool up = true;
        else const bool up = false;

        if (d[0]) {
            if (d[1]) d[2] = !d[2];
            d[1] = !d[1];
        }
        d[0] = !d[0];
        return this;
    }

    auto to(T)() const {
        return cast(T)(d[0] + 2*d[1] + 4*d[2]);
    }
}
```

I am not entirely sure how well it works. I will come back later with an updated version with more functions.

I'm not familiar with the syntax of the line `value &= 7;`. Is it equivalent to writing `value = value % 7;`?

Anyway, you used an int, but I used an array of 3 bools. I'm guessing that mine uses less memory, but I'm not sure how memory it adds when it's a struct with functions.
  • Challenge: Make ... Liam McGillivray via Digitalmars-d-learn
    • Re: Challen... Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn
      • Re: Cha... Liam McGillivray via Digitalmars-d-learn
        • Re:... Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn
      • Re: Cha... Liam McGillivray via Digitalmars-d-learn
        • Re:... Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn
          • ... Liam McGillivray via Digitalmars-d-learn
            • ... Basile B. via Digitalmars-d-learn
              • ... Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn
                • ... Basile B. via Digitalmars-d-learn
            • ... H. S. Teoh via Digitalmars-d-learn
            • ... Liam McGillivray via Digitalmars-d-learn
              • ... H. S. Teoh via Digitalmars-d-learn

Reply via email to