The challenge

As the submarine drops below the surface of the ocean, it automatically performs a sonar sweep of the nearby sea floor. On a small screen, the sonar sweep report (your puzzle input) appears: each line is a measurement of the sea floor depth as the sweep looks further and further away from the submarine.

[…]

The first order of business is to figure out how quickly the depth increases, just so you know what you’re dealing with - you never know if the keys will get carried into deeper water by an ocean current or a fish or something.

To do this, count the number of times a depth measurement increases from the previous measurement. (There is no measurement before the first measurement.)

[…]

You can read the challenge more in depth, here.

Part 1

The idea here is to create duplicate version of the values array but shifted, to zip and compare those two value groups afterwards:

auto a = [199, 200, 208, 210, 200, 207, 240, 269, 260, 263]; // initial array
[0, 199, 200, 208, 210, 200, 207, 240, 269, 260] // shifted by one

zip(a, 0 ~ a[0 .. $ - 1]) // zipped ranges

But we now trim the first value of each zipped group. To do this efficiently, without any reallocation, we can offset on of the arrays by one and slice the other one with the right length:

auto a = [ 199, 200, 208, 210, 200, 207, 240, 269, 260, 263]; // initial array
a[1 .. $] // array slice with an offset
a[0 .. $ - 1] // slice without the last element

zip(a[1 .. $], a[0 .. $ - 1]) // zipped ranges wo/ the 1st element

Finally we can calculate the difference between the zipped values by mapping them:

auto z = zip(a[1 .. $], a[0 .. $ - 1]);
auto diff = z.map!"a[0] - a[1]"; // mapped difference

diff.writeln; // [1, 8, 2, -10, 7, 33, 29, -9, 3]

Now that have an array with the calculated differences, we just need to count the positive values:

auto diff = z.map!"a[0] - a[1]"; // mapped difference
auto p = diff.count!"a > 0"; // count positives

p.writeln; // 7

Full solution

[stdin.byLine().map!(to!long).array]        // input
    .map!(r => zip(r[1 .. $], r[0 .. $-1])) // zip w/ shifted range
    .front.map!(z => z[0] - z[1])           // calculate diffs
    .count!"a > 0".writeln;                 // count positives

Part 2

Considering every single measurement isn’t as useful as you expected: there’s just too much noise in the data. Instead, consider sums of a three-measurement sliding window.

[…]

Your goal now is to count the number of times the sum of measurements in this sliding window increases from the previous sum.

The second part is slightly different, as we need to group the values in groups of three. Taking the same principle of the first part, we can shift and offset the initial array to create the groups:

auto g = zip(r[0 .. $ - 2], r[1 .. $ - 1], r[2 .. $]); // zip three slices

Now we just sum the values of each group, by mapping them and sum the expanded version of the group:

auto g = zip(r[0 .. $ - 2], r[1 .. $ - 1], r[2 .. $]); // zip three slices
auto s = g.map!(e => sum([e.expand])); // sum the values

s.writeln; // [607, 618, 618, 617, 647, 716, 769, 792]

With those values summed up, we replicate the same exact thing from the first part.

Full solution

[[stdin.byLine().map!(to!long).array]                        // input
    .map!(r => zip(r[0 .. $ - 2], r[1 .. $ - 1], r[2 .. $])) // group values
    .front.map!(e => sum([e.expand])).array]                 // sum each group
    .map!(r => zip(r[1 .. $], r[0 .. $-1]))                  // zip w/ shifted range
    .front.map!"a[0] - a[1]"                                 // calculate diffs
    .count!"a > 0".writeln;                                  // count positives

Clever solution

Thanks to u/Jlobblet on Reddit, this is also a possible solution in D:

auto data = stdin.byLine().map!(to!long).array;
StoppingPolicy.shortest.zip(data, data[3..$]) // change 3 to 1 for part one
    .count!"a[1] > a[0]".writeln;