Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit fc173fb

Browse files
Solved Josephus algorithm. Documented MyArray.
1 parent 5249e9a commit fc173fb

File tree

3 files changed

+212
-7
lines changed

3 files changed

+212
-7
lines changed

‎Data-Structures/Arrays/Implementation.ts renamed to ‎Data-Structures/Arrays/MyArray.ts

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
type NumIndexedObject = { [index: number]: any };
22

3-
export class MyArray<T> {
3+
export defaultclass MyArray<T> {
44

55
public length: number;
66
private data: NumIndexedObject;
@@ -10,6 +10,11 @@ export class MyArray<T> {
1010
this.data = Object.create({});
1111
}
1212

13+
/**
14+
* Get element at given index.
15+
* @param index Index of value to return
16+
* @returns Value, or null if non-existant
17+
*/
1318
public get(index: number): T | null {
1419
if(index > 0 && index < this.length) {
1520
return this.data[index];
@@ -18,13 +23,22 @@ export class MyArray<T> {
1823
return null;
1924
}
2025

26+
/**
27+
* Add element to end of array,i.e. at index Array.length.
28+
* @param item Value/object to push
29+
* @returns Length of array after push
30+
*/
2131
public push(item: T): number {
2232
this.data[this.length] = item; // Add item to end of array
2333
++this.length; // Add 1 to array length
2434

2535
return this.length;
2636
}
2737

38+
/**
39+
* Remove the last element of array.
40+
* @returns Value/object at last index, or null if empty array
41+
*/
2842
public pop(): T | null {
2943
if(this.length > 0) {
3044
const lastItem = this.data[this.length-1]; // Retrieve last item
@@ -37,29 +51,40 @@ export class MyArray<T> {
3751
return null;
3852
}
3953

54+
/**
55+
* Delete item at given index.
56+
* @param index Numerical position to delete
57+
* @returns Value/object at index, or null if empty array
58+
*/
4059
public deleteIndex(index: number): T | null {
41-
if(index > 0 && index < this.length) {
60+
if(index >= 0 && index < this.length) {
4261

4362
const requestedItem = this.data[index];
44-
this.shiftItemsLeftAfterIndex(index);
63+
this._shiftItemsLeftAfterIndex(index);
4564

4665
return requestedItem;
4766
}
4867

4968
return null;
5069
}
5170

71+
/**
72+
* Insert a given value (item) at specified index
73+
* @param index Numerical position to insert at
74+
* @param item Value/object to insert
75+
* @returns Length of array after insertion, or null if failed insertion
76+
*/
5277
public insertItemAtIndex(index: number, item: T): number | null {
53-
if(index > 0 && index < this.length) {
54-
this.shiftItemsRightAtIndex(index);
78+
if(index >= 0 && index < this.length) {
79+
this._shiftItemsRightAtIndex(index);
5580
this.data[index] = item;
5681
return this.length;
5782
}
5883

5984
return null;
6085
}
6186

62-
private shiftItemsLeftAfterIndex(index: number): void {
87+
private _shiftItemsLeftAfterIndex(index: number): void {
6388
for (let i=index; i < this.length-1; ++i) {
6489
this.data[i] = this.data[i+1];
6590
}
@@ -68,7 +93,7 @@ export class MyArray<T> {
6893
delete this.data[this.length];
6994
}
7095

71-
private shiftItemsRightAtIndex(index: number): void {
96+
private _shiftItemsRightAtIndex(index: number): void {
7297
++this.length;
7398

7499
for (let i=this.length-1; i > index; --i) {
File renamed without changes.

‎Playground/Challenges/Josephus.ts

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
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

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /