Skip to content

Commit 9e6f7ea

Browse files
authored
Add Dijkstra in Pascal (TheRenegadeCoder#4829)
1 parent c7ed0b1 commit 9e6f7ea

File tree

1 file changed

+169
-0
lines changed

1 file changed

+169
-0
lines changed

archive/p/pascal/dijkstra.pas

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
program Dijkstra;
2+
3+
{$mode objfpc}{$H+}
4+
5+
uses
6+
Classes,
7+
Generics.Collections,
8+
Math,
9+
SysUtils;
10+
11+
type
12+
TIntegerList = specialize TList<integer>;
13+
TBooleanList = specialize TList<boolean>;
14+
15+
procedure ShowUsage;
16+
begin
17+
Writeln('Usage: please provide three inputs: a serialized matrix, a source node and a destination node');
18+
Halt(1);
19+
end;
20+
21+
function ParseIntegerList(const S: string): TIntegerList;
22+
var
23+
Part: string;
24+
Value: integer;
25+
begin
26+
if S.Trim.IsEmpty then ShowUsage;
27+
Result := TIntegerList.Create;
28+
for Part in S.Split([',']) do
29+
begin
30+
if not TryStrToInt(Trim(Part), Value) or (Value < 0) then
31+
begin
32+
Result.Free;
33+
ShowUsage;
34+
end;
35+
Result.Add(Value);
36+
end;
37+
if Result.Count = 0 then
38+
begin
39+
Result.Free;
40+
ShowUsage;
41+
end;
42+
end;
43+
44+
// Checks if the matrix is square, returns dimension or -1 if invalid
45+
function MatrixDimension(const Matrix: TIntegerList): integer; inline;
46+
var
47+
Len: integer;
48+
D: integer;
49+
begin
50+
Len := Matrix.Count;
51+
D := Floor(Sqrt(Len));
52+
if (D * D = Len) and (D > 0) then
53+
Result := D
54+
else
55+
Result := -1;
56+
end;
57+
58+
// Returns distance from src to dst or -1 if unreachable
59+
function Dijkstra(const Matrix: TIntegerList;
60+
Dimension, Source, Destination: integer): integer;
61+
const
62+
INF = $3F3F3F3F;
63+
var
64+
Dist: TIntegerList;
65+
Visited: TBooleanList;
66+
I, J, MinDist, MinIndex, Weight, CurrentDist: integer;
67+
begin
68+
Dist := TIntegerList.Create;
69+
Visited := TBooleanList.Create;
70+
try
71+
Dist.Capacity := Dimension;
72+
Visited.Capacity := Dimension;
73+
74+
for I := 0 to Dimension - 1 do
75+
begin
76+
Dist.Add(INF);
77+
Visited.Add(False);
78+
end;
79+
80+
Dist[Source] := 0;
81+
82+
for I := 0 to Dimension - 1 do
83+
begin
84+
MinDist := INF;
85+
MinIndex := -1;
86+
87+
// Find closest unvisited node
88+
for J := 0 to Dimension - 1 do
89+
if (not Visited[J]) and (Dist[J] < MinDist) then
90+
begin
91+
MinDist := Dist[J];
92+
MinIndex := J;
93+
end;
94+
95+
if MinIndex = -1 then
96+
Break;
97+
98+
Visited[MinIndex] := True;
99+
CurrentDist := Dist[MinIndex];
100+
101+
if MinIndex = Destination then
102+
begin
103+
Result := CurrentDist;
104+
Exit;
105+
end;
106+
107+
for J := 0 to Dimension - 1 do
108+
begin
109+
Weight := Matrix[MinIndex * Dimension + J];
110+
if (not Visited[J]) and (Weight > 0) and
111+
(CurrentDist + Weight < Dist[J]) then
112+
Dist[J] := CurrentDist + Weight;
113+
end;
114+
end;
115+
116+
if Dist[Destination] = INF then
117+
Result := -1
118+
else
119+
Result := Dist[Destination];
120+
121+
finally
122+
Dist.Free;
123+
Visited.Free;
124+
end;
125+
end;
126+
127+
128+
var
129+
MatrixStr, SourceStr, DestinationStr: string;
130+
Matrix: TIntegerList;
131+
Dimension, Source, Destination, ShortestDistance: integer;
132+
begin
133+
if ParamCount <> 3 then
134+
ShowUsage;
135+
136+
MatrixStr := Trim(ParamStr(1));
137+
SourceStr := Trim(ParamStr(2));
138+
DestinationStr := Trim(ParamStr(3));
139+
140+
if (MatrixStr = '') or (SourceStr = '') or (DestinationStr = '') then
141+
ShowUsage;
142+
143+
Matrix := nil;
144+
try
145+
Matrix := ParseIntegerList(MatrixStr);
146+
147+
Dimension := MatrixDimension(Matrix);
148+
149+
// Check if:
150+
// - the matrix represents a valid square adjacency matrix (dimension <> 1)
151+
// - the source and destination nodes are valid integers
152+
// - the nodes are within valid index range [0, Dimension - 1]
153+
if (Dimension = -1) or (not TryStrToInt(SourceStr, Source)) or
154+
(not TryStrToInt(DestinationStr, Destination)) or (Source < 0) or
155+
(Source >= Dimension) or (Destination < 0) or (Destination >= Dimension) then
156+
157+
ShowUsage;
158+
159+
ShortestDistance := Dijkstra(Matrix, Dimension, Source, Destination);
160+
161+
if ShortestDistance = -1 then
162+
ShowUsage
163+
else
164+
Writeln(ShortestDistance);
165+
166+
finally
167+
Matrix.Free;
168+
end;
169+
end.

0 commit comments

Comments
 (0)