-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathjosephus.pas
More file actions
167 lines (145 loc) · 3.53 KB
/
josephus.pas
File metadata and controls
167 lines (145 loc) · 3.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
program JosephusProblem;
uses
webCRT;
type
ArrayOfInteger = array of integer; // 0-based array
function FontColor(const s,c: string): string;
begin
FontColor := '<font color="'+c+'">'+s+'</font> ';
end;
function FmtStr(const s: string; w: integer = 2): string;
var
i,l: integer;
r: string;
begin
r := s;
l := Length(r);
if l > w then w := l;
for i := 1 to w-l do r := ' '+r;
FmtStr := r
end;
function Joseph(const men, int: integer): ArrayOfInteger;
// count survivor
function life(a: array of integer): integer;
var
i,l: integer;
begin
l := 0;
for i := 0 to High(a) do
if a[i] <> 0 then l := l+1;
life := l;
end;
var
a,m: ArrayOfInteger;
c,i,j,k,l,x: integer;
r: boolean;
s: string;
begin
// initialize array
x := men-1;
SetLength(a, men);
SetLength(m, men);
for i := 0 to x do m[i] := i+1;
r := false;
s := '';
i := -1;
j := 0;
k := 0;
c := 0;
repeat
// iterate victim
i := i + 1;
if i > x then
begin
i := 0;
r := true;
end;
if m[i] <> 0 then j := j+1; // stepping
// execute on interval
if j = int then
begin
a[i] := k+1; // save step in 1-based
k := k + 1;
m[i] := 0; // BANG!
j := 0;
// execution sequence
s := s+FmtStr(Int2Str(i+1))+'| ';
for l := 0 to x do
// alive
if m[l] <> 0 then
s := s+FmtStr(Int2Str(m[l]))+' '
else
// mark the dead
begin
if l <> i then
s := s+FontColor(FmtStr('x'),'red')
else
begin
// last executed
c := c + 1;
if c = men then
s := s+FontColor(FmtStr(' ♥︎'),'blue')
else
s := s+FontColor(FmtStr('x'),'blue');
end;
end;
// mark on rotation
if r then
begin
if c <> men then
s := s + '↩︎';
r := false;
end;
s := s+LineEnding;
end;
until life(m) = 0; // until all dead
// victim sequence
s := s + ' ';
for l := 0 to x do
s := s + FmtStr('__ ');
s := s+LineEnding;
s := s + ' ';
for l := 0 to x do
s := s + FmtStr(Int2Str(a[l])) + ' ';
// print sequence
webWrite('<pre>'+s+'</pre>');
Joseph := a;
end;
(***** main program *****)
var
s: string;
i: integer;
nov: integer = 0;
iod: integer = 0;
jos: ArrayOfInteger; // 0-based array
begin
ClrScr;
webWriteln('<big><b>Josephus Problem</b></big>');
webWriteln('<span style="font-size:0.8em">Note: Number must not be zero.</span>');
webWrite('<p>');
webWrite('Input number of victim: ',160); webReadln(nov);
webWrite('Input interval of dead: ',160); webReadln(iod);
if (nov > 0) and (iod > 0) then
begin
if iod > nov then
webWriteln(FontColor('<p>Error:','red')+
'The interval can <b>not</b> be larger than the victims.')
else
begin
webWriteln('<p>Execution sequence:');
jos := Joseph(nov,iod);
// print function result
s := '';
webWrite('Josephus('+Int2Str(nov)+','+Int2Str(iod)+') = [');
for i := 0 to High(jos) do
s := s + Int2Str(jos[i]) + ',';
s := Copy(s,1,Length(s)-1);
webWriteln(s+']');
// select from sequence
webWrite('ex: Victim number '+Int2Str(nov div 2)+' is ');
webWriteln('executed in step '+Int2Str(jos[(nov div 2)-1])+'.');
//webWriteln('The last man standing is number '+Int2Str(last)+'.');
end;
end;
webReadln;
end.