My AoC program in D is just as fast as in Python

Jabba Laci jabba.laci at gmail.com
Mon Nov 24 14:37:22 UTC 2025


I implemented [Advent of Code 2015, Day 6, Part 
1](https://adventofcode.com/2015/day/6) in D. The code is here: 
https://github.com/jabbalaci/AdventOfCode2015/tree/main/day06/d/part1 . It runs for 3 seconds. I found it a bit much, so I also wrote it in Python. To my surprise, the Python program also ran for 3 seconds. I expected that the D program should be much faster.

I used a dictionary, where the key is a `Tuple!(int, int)`. Maybe 
its hashing is too slow? How could it be sped up?

Another question: for `process_line()`, I pass the dictioary by 
reference, since I want to modify the dictionary inside this 
procedure. Without `ref`, the original `d` in `main()` remained 
empty. However, I've already written programs when I passed a 
dictionary without `ref` and the changes to the dictionary were 
visible outside of the procedure. What's the rule here?

The D code is here:

```d
#!/usr/bin/env rdmd

import std.algorithm;
import std.conv;
import std.file;
import std.stdio;
import std.string;
import std.typecons;

alias Pair = Tuple!(int, int);

enum Option
{
     off = 0,
     on = 1,
     toggle = 2
}

Pair extract_pair(const string s)
{
     auto parts = s.split(",");
     return tuple(parts[0].to!int, parts[1].to!int);
}

void process_line(ref int[Pair] d, const string line)
{
     auto parts = line.split();
     Option option;
     // dfmt off
     if (parts[1] == "on") {
         option = Option.on;
     } else if (parts[1] == "off") {
         option = Option.off;
     } else if (parts[0] == "toggle") {
         option = Option.toggle;
     } else {
         assert(0);
     }
     // dfmt on

     if (option == Option.on || option == Option.off)
     {
         auto pair1 = extract_pair(parts[2]);
         auto pair2 = extract_pair(parts[$ - 1]);
         int x1 = pair1[0], y1 = pair1[1];
         int x2 = pair2[0], y2 = pair2[1];
         for (int i = x1; i <= x2; ++i)
         {
             for (int j = y1; j <= y2; ++j)
             {
                 d[tuple(i, j)] = int(option); // off: 0, on: 1
             }
         }
     }
     else if (option == Option.toggle)
     {
         auto pair1 = extract_pair(parts[1]);
         auto pair2 = extract_pair(parts[$ - 1]);
         int x1 = pair1[0], y1 = pair1[1];
         int x2 = pair2[0], y2 = pair2[1];
         for (int i = x1; i <= x2; ++i)
         {
             for (int j = y1; j <= y2; ++j)
             {
                 d[tuple(i, j)] = 1 - d.get(tuple(i, j), 0);
             }
         }
     }
     else
     {
         assert(0);
     }
}

int get_result(const int[Pair] d)
{
     // if value is 0: off, 1: on
     return d.byValue.sum;
}

void main()
{
     // const fname = "example1.txt";
     // const fname = "example2.txt";
     // const fname = "example3.txt";
     const fname = "input.txt";

     const lines = readText(fname).splitLines;
     int[Pair] d;

     foreach (line; lines)
     {
         process_line(d, line);
     }
     int result = get_result(d);
     writeln(result);
}
```


More information about the Digitalmars-d-learn mailing list