Skip to content

Commit 022d334

Browse files
authored
Add Job Sequencing in Pascal (TheRenegadeCoder#4834)
1 parent f053333 commit 022d334

File tree

1 file changed

+150
-0
lines changed

1 file changed

+150
-0
lines changed
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
program JobSequencing;
2+
3+
{$mode objfpc}{$H+}
4+
5+
uses
6+
Classes,
7+
Generics.Collections,
8+
Generics.Defaults,
9+
Math,
10+
StrUtils,
11+
SysUtils;
12+
13+
type
14+
TJobInfo = record
15+
JobId: integer;
16+
Profit: integer;
17+
Deadline: integer;
18+
end;
19+
TJobInfoList = specialize TList<TJobInfo>;
20+
TIntegerList = specialize TList<integer>;
21+
22+
procedure ShowUsage;
23+
begin
24+
Writeln('Usage: please provide a list of profits and a list of deadlines');
25+
Halt(1);
26+
end;
27+
28+
function ParseIntegerList(const S: string): TIntegerList;
29+
var
30+
Tokens: TStringArray;
31+
Token: string;
32+
Value: integer;
33+
begin
34+
if S.Trim = '' then
35+
ShowUsage;
36+
37+
Tokens := S.Split([',']);
38+
if Length(Tokens) = 0 then
39+
ShowUsage;
40+
41+
Result := TIntegerList.Create;
42+
for Token in Tokens do
43+
begin
44+
if not TryStrToInt(Trim(Token), Value) then
45+
begin
46+
Result.Free;
47+
ShowUsage;
48+
end;
49+
Result.Add(Value);
50+
end;
51+
end;
52+
53+
function CompareJobs(constref Left, Right: TJobInfo): integer;
54+
begin
55+
// Compare profit descending
56+
if Left.Profit > Right.Profit then
57+
Exit(-1) // Left should come before Right
58+
else if Left.Profit < Right.Profit then
59+
Exit(1);
60+
61+
// If profit equal, compare deadline descending
62+
if Left.Deadline > Right.Deadline then
63+
Exit(-1)
64+
else if Left.Deadline < Right.Deadline then
65+
Exit(1);
66+
67+
Exit(0);
68+
end;
69+
70+
71+
function JobSequencing(const Profits, Deadlines: TIntegerList): integer;
72+
type
73+
TJobComparer = specialize TComparer<TJobInfo>;
74+
TBooleanArray = specialize TArray<boolean>;
75+
var
76+
Jobs: TJobInfoList;
77+
Job: TJobInfo;
78+
79+
Slots: TBooleanArray;
80+
81+
i, MaxDeadline: integer;
82+
TotalProfit, SlotIndex: integer;
83+
begin
84+
Jobs := TJobInfoList.Create;
85+
try
86+
// Build job list
87+
Jobs.Capacity := Profits.Count;
88+
for i := 0 to Profits.Count - 1 do
89+
begin
90+
Job.JobID := i + 1;
91+
Job.Profit := Profits[i];
92+
Job.Deadline := Deadlines[i];
93+
Jobs.Add(Job);
94+
end;
95+
96+
// Sort jobs by profit desc, deadline desc using a comparer
97+
Jobs.Sort(TJobComparer.Construct(@CompareJobs));
98+
99+
// Find maximum deadline
100+
MaxDeadline := MaxValue(Deadlines.ToArray);
101+
102+
// Initialize slots list with False (free)
103+
SetLength(Slots, MaxDeadline);
104+
for i := 0 to MaxDeadline - 1 do
105+
Slots[i] := False;
106+
107+
TotalProfit := 0;
108+
for Job in Jobs do
109+
begin
110+
// Find free slot at or before deadline
111+
SlotIndex := Job.Deadline - 1;
112+
while (SlotIndex >= 0) and Slots[SlotIndex] do
113+
Dec(SlotIndex);
114+
115+
if SlotIndex >= 0 then
116+
begin
117+
Slots[SlotIndex] := True;
118+
Inc(TotalProfit, Job.Profit);
119+
end;
120+
end;
121+
122+
Result := TotalProfit;
123+
124+
finally
125+
Jobs.Free;
126+
end;
127+
end;
128+
129+
var
130+
Profits, Deadlines: TIntegerList;
131+
132+
begin
133+
if ParamCount <> 2 then
134+
ShowUsage;
135+
136+
Profits := nil;
137+
Deadlines := nil;
138+
try
139+
Profits := ParseIntegerList(ParamStr(1));
140+
Deadlines := ParseIntegerList(ParamStr(2));
141+
142+
if Profits.Count <> Deadlines.Count then
143+
ShowUsage;
144+
145+
Writeln(JobSequencing(Profits, Deadlines));
146+
finally
147+
Profits.Free;
148+
Deadlines.Free;
149+
end;
150+
end.

0 commit comments

Comments
 (0)