我有以下函数 findFirstDuplicateFrequency ,它实现(正确)编程puzzle的算法 .

而不是命令性循环我认为我可以将reduce应用于问题 .

我遇到了一个问题,我需要能够迭代多个(但未知)的输入序列,并在满足退出条件时退出处理 .

AFAICS标准reduce在处理过程中不能退出,我也在努力如何进行用于计算退出条件的额外累加器信息 .

那么以(更多)功能方式解决问题的正确(?)惯用D方法是什么?

这是我有史以来的第一个D程序,所以欢迎所有其他评论!

import std.conv: to;

/**
From: https://adventofcode.com/2018/day/1

You notice that the device repeats the same frequency change list over and
over. To calibrate the device, you need to find the first frequency it reaches
twice.

For example, using the same list of changes above, the device would loop as
follows:

    Current frequency  0, change of +1; resulting frequency  1.
    Current frequency  1, change of -2; resulting frequency -1.
    Current frequency -1, change of +3; resulting frequency  2.
    Current frequency  2, change of +1; resulting frequency  3.
    (At this point, the device continues from the start of the list.)
    Current frequency  3, change of +1; resulting frequency  4.
    Current frequency  4, change of -2; resulting frequency  2, which has already been seen.

In this example, the first frequency reached twice is 2. Note that your device
might need to repeat its list of frequency changes many times before a
duplicate frequency is found, and that duplicates might be found while in the
middle of processing the list.

Here are other examples:

    +1, -1 first reaches 0 twice.
    +3, +3, +4, -2, -4 first reaches 10 twice.
    -6, +3, +8, +5, -6 first reaches 5 twice.
    +7, +7, -2, -7, -4 first reaches 14 twice.

What is the first frequency your device reaches twice?
*/
int findFirstDuplicateFrequency(int[] frequencyChanges)
pure
{
  int[int] alreadySeen = [0:1];
  int frequency = 0;

 out_: while(true) {
    foreach(change; frequencyChanges) {
      frequency += change;
      if (int* _ = frequency in alreadySeen) {
        break out_;
      } else {
        alreadySeen[frequency] = 1;
      }
    }
  }

  return frequency;
} unittest {
  int answer = 0;

  answer = findFirstDuplicateFrequency([1, -2, 3, 1]);
  assert(answer == 2, "Got: " ~ to!string(answer));

  answer = findFirstDuplicateFrequency([1, -1]);
  assert(answer == 0, "Got: " ~ to!string(answer));

  answer = findFirstDuplicateFrequency([3, 3, 4, -2, -4]);
  assert(answer == 10, "Got: " ~ to!string(answer));

  answer = findFirstDuplicateFrequency([-6, 3, 8, 5, -6]);
  assert(answer == 5, "Got: " ~ to!string(answer));

  answer = findFirstDuplicateFrequency([7, 7, -2, -7, -4]);
  assert(answer == 14, "Got: " ~ to!string(answer));
}

void main() {}