📈
ユークリッド距離計算(D言語)
- D言語はC言語に似たシンプルかつ高機能で可読性が高い言語です。
- 触れることがあったので、プログラミングの基礎が詰まった「ユークリッド距離計算(2点間の距離の計算)」を実装することで理解を深めていくことにします。。
環境
- macOS 13.7.3
- DMD64 D Compiler v2.110.0
- DUB version 1.39.0
手順
プロジェクト初期化
- パッケージマネージャのdubを利用してプロジェクトを初期化します。
$ mkdir sample
$ cd sample
$ dub init
$ ls
dub.json source
コード記述
-
source/app.d
に以下のコードを記述します。
import std.stdio;
import std.math.algebraic : hypot;
import std.random : Random, uniform;
/**
* 点
*/
struct Point
{
double x;
double y;
}
/**
* ユークリッド距離計算
* Params:
* p1 = 始点
* p2 = 終点
* Returns: ユークリッド距離
*/
pure nothrow @nogc double distance(Point p1, Point p2)
{
return hypot(p2.x - p1.x, p2.y - p1.y);
}
void main()
{
// テストデータ作成
immutable int numPoint = 10;
Point[] points = new Point[numPoint];
for (int i = 0; i < numPoint; i++)
{
// 0.0から10.0までの範囲でランダム座標を生成
points[i] = Point(uniform(0.0, numPoint), uniform(0.0, numPoint));
}
// 10回distance関数を実施
for (int i = 0; i < numPoint; i++)
{
int idx1 = cast(int) uniform(0, numPoint);
int idx2 = cast(int) uniform(0, numPoint);
// 同じ点はNG
while (idx1 == idx2)
{
idx2 = cast(int) uniform(0, numPoint);
}
// 距離計算
double dist = distance(points[idx1], points[idx2]);
// 結果表示
writefln("[%.4f, %.4f]から[%.5f, %.5f]の距離: %.4f",
points[idx1].x, points[idx1].y,
points[idx2].x, points[idx2].y,
dist);
}
}
// ユニットテスト
unittest
{
Point point1 = Point(2.0, 1.0);
Point point2 = Point(4.0, 1.0);
assert(distance(point1, point2) == 2.0);
}
解説
- まず点の表現には構造体を定義します。C同様にstructを利用します。
- 次に座標計算関数の実装に必要なhypot関数ですが、D言語にもstd.mathに定義されていますので、そちらを利用します。
- その実装の際に以下を指定することで、「コンパイラの最適化」に加えて「関数特性の明示的表現による可読性の向上」につながります。
- メイン関数でランダムデータの作成をして、複数回実施をして実際の計算結果を確認します。
- D言語にはユニットテスト機能も標準でついており、コード内のどこでも埋め込むことが可能です。
実行
- コード記述後、まず以下でビルドおよびテストを実行します。
$ dub test
- エラーなく通ったら、以下でビルドおよび実行します。
$ dub run
[9.0373, 2.5852]から[0.05691, 0.55945]の距離: 9.2060
[9.2209, 0.7538]から[0.05691, 0.55945]の距離: 9.1660
[9.1896, 0.6472]から[9.03729, 2.58521]の距離: 1.9440
[1.3550, 8.2721]から[0.05691, 0.55945]の距離: 7.8211
まとめ
- 今回の実装を通じて、D言語のシンプルかつ美しい表現力かつ可読性の高さは非常に魅力あると感じました。
Discussion