1
+ export default class Josephus {
2
+ private numberOfSoldiers : number ;
3
+ private circleOfSoldiers : Array < boolean > ;
4
+ private livingCount : number ;
5
+
6
+ constructor ( numSoldiers : number ) {
7
+ this . numberOfSoldiers = numSoldiers > 1 ? numSoldiers : 2 ;
8
+ this . circleOfSoldiers = new Array ( this . numberOfSoldiers ) . fill ( true ) ;
9
+ this . livingCount = this . numberOfSoldiers ;
10
+ }
11
+
12
+ public setNumSoldiers ( numSoldiers : number ) {
13
+ this . numberOfSoldiers = numSoldiers ;
14
+ this . reset ( ) ;
15
+ }
16
+
17
+ public getNumSoldiers ( ) : number {
18
+ return this . numberOfSoldiers ;
19
+ }
20
+
21
+ public reset ( ) : void {
22
+ this . circleOfSoldiers = new Array ( this . numberOfSoldiers ) . fill ( true ) ;
23
+ this . livingCount = this . numberOfSoldiers ;
24
+ }
25
+
26
+ public solveBF ( ) : number {
27
+ if ( this . numberOfSoldiers < 2 ) return 0 ;
28
+
29
+ let lastKnight : number = - 1 ;
30
+ let dead = Array < number > ( ) ;
31
+
32
+ for ( let i = this . _findThirdLiving ( 0 ) ; this . livingCount > 1 ; i = this . _findThirdLiving ( i ) ) {
33
+
34
+ this . _markDead ( i )
35
+ dead . push ( i + 1 ) ;
36
+ i = this . _findNextLiving ( i ) ;
37
+
38
+ if ( this . livingCount === 1 ) lastKnight = i ;
39
+ }
40
+ this . reset ( ) ;
41
+ return lastKnight ;
42
+ }
43
+
44
+ public solveVisual ( ) : number {
45
+ if ( this . numberOfSoldiers < 2 ) return 0 ;
46
+
47
+ let lastKnight : number = - 1 ;
48
+
49
+ console . log ( '\nThe Romans prepare to clear the caves.\n' ) ;
50
+
51
+ let dead = Array < number > ( ) ;
52
+
53
+ for ( let i = this . _findThirdLiving ( 0 ) ; this . livingCount > 1 ; i = this . _findThirdLiving ( i ) ) {
54
+
55
+ this . _markDead ( i )
56
+ dead . push ( i + 1 ) ;
57
+ console . log ( '\tKnight' , i + 1 , 'is slain.' ) ;
58
+ i = this . _findNextLiving ( i ) ;
59
+ console . log ( 'Knight' , i + 1 , 'prepares to strike the next blow.' )
60
+
61
+ if ( this . livingCount === 1 ) {
62
+ console . log ( 'But sees no one meet his gaze...' ) ;
63
+ lastKnight = i ;
64
+ }
65
+ }
66
+
67
+ console . log ( '\nK' + ( lastKnight + 1 ) , 'is the last knight standing.' ) ;
68
+
69
+ console . log ( '\nSlain knights:' , dead . toString ( ) ) ;
70
+
71
+ this . reset ( ) ;
72
+
73
+ return lastKnight ;
74
+ }
75
+
76
+ private _findNextLiving ( index : number ) : number {
77
+ for ( let i = ( index + 1 ) % this . numberOfSoldiers ; this . livingCount > 0 ; i = ( i + 1 ) % this . numberOfSoldiers ) {
78
+ if ( this . circleOfSoldiers [ i ] === true ) return i ;
79
+ }
80
+
81
+ return - 1 ;
82
+ }
83
+
84
+ private _findThirdLiving ( index : number ) : number {
85
+ let counter = 0 ;
86
+
87
+ for ( let i = ( index + 1 ) % this . numberOfSoldiers ; this . livingCount > 1 ; i = ( i + 1 ) % this . numberOfSoldiers ) {
88
+
89
+ if ( this . circleOfSoldiers [ i ] === true ) {
90
+ if ( counter < 3 ) ++ counter ;
91
+ }
92
+
93
+ if ( counter === 3 ) return i ;
94
+ }
95
+
96
+ return - 1 ;
97
+ }
98
+
99
+ private _markDead ( index :number ) : number {
100
+ this . circleOfSoldiers [ index ] = false ;
101
+ -- this . livingCount ;
102
+ return index ;
103
+ }
104
+ }
105
+
106
+ function printJosephusSolution ( circleOfKnights : Josephus ) {
107
+ console . log ( '\nSolution for Circle of' , circleOfKnights . getNumSoldiers ( ) , '\n– Last Knight at Index:' , circleOfKnights . solveBF ( ) ) ;
108
+ }
109
+
110
+ //---------------------------------------------------------------------
111
+ // ---------- MAIN PROGRAM ----------
112
+ //---------------------------------------------------------------------
113
+ if ( import . meta. main ) {
114
+
115
+ const knights1 = new Josephus ( - 1 ) ;
116
+ knights1 . solveVisual ( ) ;
117
+
118
+ const knights2 = new Josephus ( 6 ) ;
119
+ knights2 . solveVisual ( ) ;
120
+
121
+ const knights3 = new Josephus ( 8 ) ;
122
+ knights3 . solveVisual ( ) ;
123
+ printJosephusSolution ( knights3 ) ;
124
+
125
+ // RUN: deno run Playground/Challenges/Josephus.ts
126
+ }
127
+
128
+ // --------------------------- Terminal Output: ---------------------------
129
+ // The Romans prepare to clear the caves.
130
+ //
131
+ // Knight 2 is slain.
132
+ // Knight 1 prepares to strike the next blow.
133
+ // But sees no one meet his gaze...
134
+ //
135
+ // K1 is the last knight standing.
136
+ //
137
+ // Slain knights: 2
138
+ //
139
+ // The Romans prepare to clear the caves.
140
+ //
141
+ // Knight 4 is slain.
142
+ // Knight 5 prepares to strike the next blow.
143
+ // Knight 2 is slain.
144
+ // Knight 3 prepares to strike the next blow.
145
+ // Knight 1 is slain.
146
+ // Knight 3 prepares to strike the next blow.
147
+ // Knight 3 is slain.
148
+ // Knight 5 prepares to strike the next blow.
149
+ // Knight 6 is slain.
150
+ // Knight 5 prepares to strike the next blow.
151
+ // But sees no one meet his gaze...
152
+ //
153
+ // K5 is the last knight standing.
154
+ //
155
+ // Slain knights: 4,2,1,3,6
156
+ //
157
+ // The Romans prepare to clear the caves.
158
+ //
159
+ // Knight 4 is slain.
160
+ // Knight 5 prepares to strike the next blow.
161
+ // Knight 8 is slain.
162
+ // Knight 1 prepares to strike the next blow.
163
+ // Knight 5 is slain.
164
+ // Knight 6 prepares to strike the next blow.
165
+ // Knight 2 is slain.
166
+ // Knight 3 prepares to strike the next blow.
167
+ // Knight 1 is slain.
168
+ // Knight 3 prepares to strike the next blow.
169
+ // Knight 3 is slain.
170
+ // Knight 6 prepares to strike the next blow.
171
+ // Knight 7 is slain.
172
+ // Knight 6 prepares to strike the next blow.
173
+ // But sees no one meet his gaze...
174
+ //
175
+ // K6 is the last knight standing.
176
+ //
177
+ // Slain knights: 4,8,5,2,1,3,7
178
+ //
179
+ // Solution for Circle of 8
180
+ // – Last Knight at Index: 5
0 commit comments