Skip to content

Commit 5eabb7b

Browse files
committedOct 8, 2017
chapter 04: [Queues and Deques]
1 parent ea30d2c commit 5eabb7b

32 files changed

+1468
-45
lines changed
 

‎README.md

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Work in Progress.
1313
* 01: [JavaScript, ECMAScript and TypeScript: a quick overview](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter01)
1414
* 02: [Arrays](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter02)
1515
* 03: [Stacks](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter03)
16+
* 04: [Queues and Deques](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter04)
1617

1718
## Thrid Edition Updates
1819

‎examples/PacktDataStructuresAlgorithms.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎examples/chapter04/01-Queue.html

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8">
5+
<title></title>
6+
</head>
7+
<body>
8+
<script src="./../PacktDataStructuresAlgorithms.min.js"></script>
9+
<script src="01-Queue.js"></script>
10+
</body>
11+
</html>

‎examples/chapter04/01-Queue.js

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
const { Queue } = PacktDataStructuresAlgorithms;
2+
3+
const queue = new Queue();
4+
console.log(queue.isEmpty()); // outputs true
5+
queue.enqueue('John');
6+
queue.enqueue('Jack');
7+
console.log(queue.toString()); // John,Jack
8+
queue.enqueue('Camila');
9+
console.log(queue.toString()); // John,Jack,Camila
10+
console.log(queue.size()); // outputs 3
11+
console.log(queue.isEmpty()); // outputs false
12+
queue.dequeue();
13+
queue.dequeue();
14+
console.log(queue.toString()); // Camila

‎examples/chapter04/02-Deque.html

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8">
5+
<title></title>
6+
</head>
7+
<body>
8+
<script src="./../PacktDataStructuresAlgorithms.min.js"></script>
9+
<script src="02-Deque.js"></script>
10+
</body>
11+
</html>

‎examples/chapter04/02-Deque.js

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const { Deque } = PacktDataStructuresAlgorithms;
2+
3+
const deque = new Deque();
4+
console.log(deque.isEmpty()); // outputs true
5+
deque.addBack('John');
6+
deque.addBack('Jack');
7+
console.log(deque.toString()); // John,Jack
8+
deque.addBack('Camila');
9+
console.log(deque.toString()); // John,Jack,Camila
10+
console.log(deque.size()); // outputs 3
11+
console.log(deque.isEmpty()); // outputs false
12+
deque.removeFront();
13+
console.log(deque.toString()); // Jack,Camila
14+
deque.removeBack(); // Camila decides to leave
15+
console.log(deque.toString()); // Jack
16+
deque.addFront('John');
17+
console.log(deque.toString()); // John,Jack

‎examples/chapter04/03-HotPotato.html

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8">
5+
<title></title>
6+
</head>
7+
<body>
8+
<script src="./../PacktDataStructuresAlgorithms.min.js"></script>
9+
<script src="03-HotPotato.js"></script>
10+
</body>
11+
</html>

‎examples/chapter04/03-HotPotato.js

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
const { hotPotato } = PacktDataStructuresAlgorithms;
2+
3+
const names = ['John', 'Jack', 'Camila', 'Ingrid', 'Carl'];
4+
const result = hotPotato(names, 7);
5+
6+
result.eliminated.forEach(name => {
7+
console.log(`${name} was eliminated from the Hot Potato game.`);
8+
});
9+
10+
console.log(`The winner is: ${result.winner}`);
11+
12+
// Camila was eliminated from the Hot Potato game.
13+
// Jack was eliminated from the Hot Potato game.
14+
// Carl was eliminated from the Hot Potato game.
15+
// Ingrid was eliminated from the Hot Potato game.
16+
// The winner is: John
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8">
5+
<title></title>
6+
</head>
7+
<body>
8+
<script src="./../PacktDataStructuresAlgorithms.min.js"></script>
9+
<script src="04-PalindromeChecker.js"></script>
10+
</body>
11+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
const { palindromeChecker } = PacktDataStructuresAlgorithms;
2+
3+
console.log('a', palindromeChecker('a'));
4+
console.log('aa', palindromeChecker('aa'));
5+
console.log('kayak', palindromeChecker('kayak'));
6+
console.log('level', palindromeChecker('level'));
7+
console.log('Was it a car or a cat I saw', palindromeChecker('Was it a car or a cat I saw'));
8+
console.log('Step on no pets', palindromeChecker('Step on no pets'));

‎examples/index.html

+60-41
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,15 @@
1313
.mdl-layout__content {
1414
padding: 10px;
1515
}
16+
1617
.mdl-layout__drawer {
1718
width: 290px;
1819
}
20+
1921
.iframe-padding {
2022
padding-left: 295px;
2123
}
24+
2225
.mdl-layout__drawer .mdl-navigation .mdl-navigation__link {
2326
color: rgb(103, 58, 183);
2427
}
@@ -39,37 +42,39 @@
3942
<a href="#scroll-tab-2" class="mdl-layout__tab">02</a>
4043
<a href="#scroll-tab-3" class="mdl-layout__tab">03</a>
4144
<a href="#scroll-tab-4" class="mdl-layout__tab">04</a>
42-
<a href="#scroll-tab-4" class="mdl-layout__tab">05</a>
43-
<a href="#scroll-tab-4" class="mdl-layout__tab">06</a>
45+
<a href="#scroll-tab-5" class="mdl-layout__tab">05</a>
46+
<a href="#scroll-tab-5" class="mdl-layout__tab">06</a>
4447
</div>
4548
</header>
4649
<main class="mdl-layout__content">
4750
<span class="iframe-padding">Please open the Developer Tools Console to see the output</span>
4851
<!-- Where the examples will be displayed -->
49-
<div id="myFrame" class="iframe-padding"><iframe name="myFrame" src=""></iframe></div>
52+
<div id="myFrame" class="iframe-padding">
53+
<iframe name="myFrame" src=""></iframe>
54+
</div>
5055
<!-- Where the examples will be displayed - end -->
5156
<section class="mdl-layout__tab-panel is-active" id="scroll-tab-1">
5257
<div class="page-content mdl-layout--fixed-drawer">
5358
<div class="mdl-layout__drawer is-visible">
5459
<nav class="mdl-navigation">
5560
<a class="mdl-navigation__link" href="chapter01/01-HelloWorld.html">01-HelloWorld</a>
56-
<a class="mdl-navigation__link" href="chapter01/02-Variables.html" >02-Variables</a>
57-
<a class="mdl-navigation__link" href="chapter01/03-Operators.html" >03-Operators</a>
58-
<a class="mdl-navigation__link" href="chapter01/04-TruthyFalsy.html" >04-Truthy Falsy</a>
59-
<a class="mdl-navigation__link" href="chapter01/05-EqualsOperators.html" >05-Equals Operators</a>
60-
<a class="mdl-navigation__link" href="chapter01/06-ConditionalStatements.html" >06-Conditional Statements</a>
61-
<a class="mdl-navigation__link" href="chapter01/07-Loops.html" >07-Loops</a>
62-
<a class="mdl-navigation__link" href="chapter01/08-Functions.html" >08-Functions</a>
63-
<a class="mdl-navigation__link" href="chapter01/09-ObjectOrientedJS.html" >09-Object Oriented JS</a>
64-
<a class="mdl-navigation__link" href="chapter01/10-ES2015-ES6-letconst.html" >10-ES2015-letconst</a>
65-
<a class="mdl-navigation__link" href="chapter01/11-ES2015-ES6-variableScope.html" >11-ES2015-variableScope</a>
66-
<a class="mdl-navigation__link" href="chapter01/12-ES2015-ES6-StringTemplates.html" >12-ES2015-String Templates</a>
67-
<a class="mdl-navigation__link" href="chapter01/13-ES2015-ES6-ArrowFunctions.html" >13-ES2015-Arrow Functions</a>
68-
<a class="mdl-navigation__link" href="chapter01/14-ES2015-ES6-ParameterHandling.html" >14-ES2015-Parameter Handling</a>
69-
<a class="mdl-navigation__link" href="chapter01/15-ES2015-ES6-EnhancedObjectProperties.html" >15-ES2015-EnhancedObject Properties</a>
70-
<a class="mdl-navigation__link" href="chapter01/16-ES2015-ES6-Classes.html" >16-ES2015-Classes</a>
71-
<a class="mdl-navigation__link" href="chapter01/17-ES2015-ES6-Modules.html" >17-ES2015-Modules</a>
72-
<a class="mdl-navigation__link" href="chapter01/18-ES2016-ES7-ExponentiationOperator.html" >18-ES2016-ExponentiationOperator</a>
61+
<a class="mdl-navigation__link" href="chapter01/02-Variables.html">02-Variables</a>
62+
<a class="mdl-navigation__link" href="chapter01/03-Operators.html">03-Operators</a>
63+
<a class="mdl-navigation__link" href="chapter01/04-TruthyFalsy.html">04-Truthy Falsy</a>
64+
<a class="mdl-navigation__link" href="chapter01/05-EqualsOperators.html">05-Equals Operators</a>
65+
<a class="mdl-navigation__link" href="chapter01/06-ConditionalStatements.html">06-Conditional Statements</a>
66+
<a class="mdl-navigation__link" href="chapter01/07-Loops.html">07-Loops</a>
67+
<a class="mdl-navigation__link" href="chapter01/08-Functions.html">08-Functions</a>
68+
<a class="mdl-navigation__link" href="chapter01/09-ObjectOrientedJS.html">09-Object Oriented JS</a>
69+
<a class="mdl-navigation__link" href="chapter01/10-ES2015-ES6-letconst.html">10-ES2015-letconst</a>
70+
<a class="mdl-navigation__link" href="chapter01/11-ES2015-ES6-variableScope.html">11-ES2015-variableScope</a>
71+
<a class="mdl-navigation__link" href="chapter01/12-ES2015-ES6-StringTemplates.html">12-ES2015-String Templates</a>
72+
<a class="mdl-navigation__link" href="chapter01/13-ES2015-ES6-ArrowFunctions.html">13-ES2015-Arrow Functions</a>
73+
<a class="mdl-navigation__link" href="chapter01/14-ES2015-ES6-ParameterHandling.html">14-ES2015-Parameter Handling</a>
74+
<a class="mdl-navigation__link" href="chapter01/15-ES2015-ES6-EnhancedObjectProperties.html">15-ES2015-EnhancedObject Properties</a>
75+
<a class="mdl-navigation__link" href="chapter01/16-ES2015-ES6-Classes.html">16-ES2015-Classes</a>
76+
<a class="mdl-navigation__link" href="chapter01/17-ES2015-ES6-Modules.html">17-ES2015-Modules</a>
77+
<a class="mdl-navigation__link" href="chapter01/18-ES2016-ES7-ExponentiationOperator.html">18-ES2016-ExponentiationOperator</a>
7378
</nav>
7479
</div>
7580
</div>
@@ -80,38 +85,52 @@
8085
<div class="mdl-layout__drawer is-visible">
8186
<nav class="mdl-navigation">
8287
<a class="mdl-navigation__link" href="chapter02/01-Introduction.html">01-Introduction</a>
83-
<a class="mdl-navigation__link" href="chapter02/02-CreatingAndInitialingArrays.html" >02-Creating Initialing Arrays</a>
84-
<a class="mdl-navigation__link" href="chapter02/03-AddingRemovingElements.html" >03-Adding Removing Elements</a>
85-
<a class="mdl-navigation__link" href="chapter02/04-TwoDimensionalMultiDimensional.html" >04-Two Dimensional - MultiDimensional</a>
86-
<a class="mdl-navigation__link" href="chapter02/05-ArrayMethods.html" >05-ArrayMethods</a>
87-
<a class="mdl-navigation__link" href="chapter02/06-ES6Methods.html" >06-ES2015+ Methods</a>
88-
<a class="mdl-navigation__link" href="chapter02/07-Sorting.html" >07-Sorting</a>
89-
<a class="mdl-navigation__link" href="chapter02/08-Searching.html" >08-Searching</a>
90-
<a class="mdl-navigation__link" href="chapter02/09-TypedArrays.html" >09-TypedArrays</a>
88+
<a class="mdl-navigation__link" href="chapter02/02-CreatingAndInitialingArrays.html">02-Creating Initialing Arrays</a>
89+
<a class="mdl-navigation__link" href="chapter02/03-AddingRemovingElements.html">03-Adding Removing Elements</a>
90+
<a class="mdl-navigation__link" href="chapter02/04-TwoDimensionalMultiDimensional.html">04-Two Dimensional - MultiDimensional</a>
91+
<a class="mdl-navigation__link" href="chapter02/05-ArrayMethods.html">05-ArrayMethods</a>
92+
<a class="mdl-navigation__link" href="chapter02/06-ES6Methods.html">06-ES2015+ Methods</a>
93+
<a class="mdl-navigation__link" href="chapter02/07-Sorting.html">07-Sorting</a>
94+
<a class="mdl-navigation__link" href="chapter02/08-Searching.html">08-Searching</a>
95+
<a class="mdl-navigation__link" href="chapter02/09-TypedArrays.html">09-TypedArrays</a>
9196
</nav>
9297
</div>
9398
</div>
9499
</div>
95100
</section>
96101
<section class="mdl-layout__tab-panel" id="scroll-tab-3">
97102
<div class="page-content">
98-
<div class="page-content mdl-layout--fixed-drawer">
99-
<div class="mdl-layout__drawer is-visible">
100-
<nav class="mdl-navigation">
101-
<a class="mdl-navigation__link" href="chapter03/01-Stack.html">01-Stack</a>
102-
<a class="mdl-navigation__link" href="chapter03/02-BalancedSymbols.html">02-BalancedSymbols</a>
103-
<a class="mdl-navigation__link" href="chapter03/03-DecimalToBinary.html">03-DecimalToBinary</a>
104-
<a class="mdl-navigation__link" href="chapter03/04-TowerOfHanoi.html">04-TowerOfHanoi</a>
105-
</nav>
106-
</div>
107-
</div>
103+
<div class="page-content mdl-layout--fixed-drawer">
104+
<div class="mdl-layout__drawer is-visible">
105+
<nav class="mdl-navigation">
106+
<a class="mdl-navigation__link" href="chapter03/01-Stack.html">01-Stack</a>
107+
<a class="mdl-navigation__link" href="chapter03/02-BalancedSymbols.html">02-BalancedSymbols</a>
108+
<a class="mdl-navigation__link" href="chapter03/03-DecimalToBinary.html">03-DecimalToBinary</a>
109+
<a class="mdl-navigation__link" href="chapter03/04-TowerOfHanoi.html">04-TowerOfHanoi</a>
110+
</nav>
111+
</div>
112+
</div>
108113
</div>
109114
</section>
110115
<section class="mdl-layout__tab-panel" id="scroll-tab-4">
111-
<div class="page-content">
112-
Soon.
116+
<div class="page-content">
117+
<div class="page-content mdl-layout--fixed-drawer">
118+
<div class="mdl-layout__drawer is-visible">
119+
<nav class="mdl-navigation">
120+
<a class="mdl-navigation__link" href="chapter04/01-Queue.html">01-Queue</a>
121+
<a class="mdl-navigation__link" href="chapter04/02-Deque.html">02-Deque</a>
122+
<a class="mdl-navigation__link" href="chapter04/03-HotPotato.html">03-HotPotato</a>
123+
<a class="mdl-navigation__link" href="chapter04/04-PalindromeChecker.html">04-PalindromeChecker</a>
124+
</nav>
125+
</div>
113126
</div>
114-
</section>
127+
</div>
128+
</section>
129+
<section class="mdl-layout__tab-panel" id="scroll-tab-5">
130+
<div class="page-content">
131+
Soon.
132+
</div>
133+
</section>
115134
</main>
116135
</div>
117136
</body>

‎src/js/data-structures/deque.js

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// @ts-check
2+
3+
export default class Deque {
4+
constructor() {
5+
this.count = 0;
6+
this.lowestCount = 0;
7+
this.items = {};
8+
}
9+
10+
addFront(element) {
11+
if (this.isEmpty()) {
12+
this.addBack(element);
13+
} else if (this.lowestCount > 0) {
14+
this.lowestCount--;
15+
this.items[this.lowestCount] = element;
16+
} else {
17+
for (let i = this.count; i > 0; i--) {
18+
this.items[i] = this.items[i - 1];
19+
}
20+
this.count++;
21+
this.items[0] = element;
22+
}
23+
}
24+
25+
addBack(element) {
26+
this.items[this.count] = element;
27+
this.count++;
28+
}
29+
30+
removeFront() {
31+
if (this.isEmpty()) {
32+
return undefined;
33+
}
34+
const result = this.items[this.lowestCount];
35+
delete this.items[this.lowestCount];
36+
this.lowestCount++;
37+
return result;
38+
}
39+
40+
removeBack() {
41+
if (this.isEmpty()) {
42+
return undefined;
43+
}
44+
this.count--;
45+
const result = this.items[this.count];
46+
delete this.items[this.count];
47+
return result;
48+
}
49+
50+
peekFront() {
51+
if (this.isEmpty()) {
52+
return undefined;
53+
}
54+
return this.items[this.lowestCount];
55+
}
56+
57+
peekBack() {
58+
if (this.isEmpty()) {
59+
return undefined;
60+
}
61+
return this.items[this.count - 1];
62+
}
63+
64+
isEmpty() {
65+
return this.size() === 0;
66+
}
67+
68+
clear() {
69+
this.items = {};
70+
this.count = 0;
71+
this.lowestCount = 0;
72+
}
73+
74+
size() {
75+
return this.count - this.lowestCount;
76+
}
77+
78+
toString() {
79+
if (this.isEmpty()) {
80+
return '';
81+
}
82+
let objString = `${this.items[this.lowestCount]}`;
83+
for (let i = this.lowestCount + 1; i < this.count; i++) {
84+
objString = `${objString},${this.items[i]}`;
85+
}
86+
return objString;
87+
}
88+
}

‎src/js/data-structures/queue.js

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// @ts-check
2+
3+
export default class Queue {
4+
constructor() {
5+
this.count = 0;
6+
this.lowestCount = 0;
7+
this.items = {};
8+
}
9+
10+
enqueue(element) {
11+
this.items[this.count] = element;
12+
this.count++;
13+
}
14+
15+
dequeue() {
16+
if (this.isEmpty()) {
17+
return undefined;
18+
}
19+
const result = this.items[this.lowestCount];
20+
delete this.items[this.lowestCount];
21+
this.lowestCount++;
22+
return result;
23+
}
24+
25+
peek() {
26+
if (this.isEmpty()) {
27+
return undefined;
28+
}
29+
return this.items[this.lowestCount];
30+
}
31+
32+
isEmpty() {
33+
return this.count - this.lowestCount === 0;
34+
}
35+
36+
clear() {
37+
this.items = {};
38+
this.count = 0;
39+
this.lowestCount = 0;
40+
}
41+
42+
size() {
43+
return this.count - this.lowestCount;
44+
}
45+
46+
toString() {
47+
if (this.isEmpty()) {
48+
return '';
49+
}
50+
let objString = `${this.items[this.lowestCount]}`;
51+
for (let i = this.lowestCount + 1; i < this.count; i++) {
52+
objString = `${objString},${this.items[i]}`;
53+
}
54+
return objString;
55+
}
56+
}

‎src/js/index.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import { hotPotato } from './others/hot-potato';
2+
import { palindromeChecker } from './others/palindrome-checker';
3+
import Deque from './data-structures/deque';
4+
import Queue from './data-structures/queue';
15
import { hanoi, hanoiStack } from './others/hanoi';
26
import { baseConverter, decimalToBinary } from './others/base-converter';
37
import StackArray from './data-structures/stack-array';
@@ -11,5 +15,9 @@ export {
1115
baseConverter,
1216
decimalToBinary,
1317
hanoi,
14-
hanoiStack
18+
hanoiStack,
19+
Queue,
20+
Deque,
21+
hotPotato,
22+
palindromeChecker
1523
};

‎src/js/others/hot-potato.js

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import Queue from '../data-structures/queue';
2+
3+
export function hotPotato(elementsList, num) {
4+
const queue = new Queue();
5+
const elimitatedList = [];
6+
7+
for (let i = 0; i < elementsList.length; i++) {
8+
queue.enqueue(elementsList[i]);
9+
}
10+
11+
while (queue.size() > 1) {
12+
for (let i = 0; i < num; i++) {
13+
queue.enqueue(queue.dequeue());
14+
}
15+
elimitatedList.push(queue.dequeue());
16+
}
17+
18+
return {
19+
eliminated: elimitatedList,
20+
winner: queue.dequeue()
21+
};
22+
}

‎src/js/others/palindrome-checker.js

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import Deque from '../data-structures/deque';
2+
3+
export function palindromeChecker(aString) {
4+
if (
5+
aString === undefined ||
6+
aString === null ||
7+
(aString !== null && aString.length === 0)
8+
) {
9+
return false;
10+
}
11+
const deque = new Deque();
12+
const lowerString = aString.toLocaleLowerCase().split(' ').join('');
13+
let isEqual = true;
14+
let firstChar;
15+
let lastChar;
16+
17+
for (let i = 0; i < lowerString.length; i++) {
18+
deque.addBack(lowerString.charAt(i));
19+
}
20+
21+
while (deque.size() > 1 && isEqual) {
22+
firstChar = deque.removeFront();
23+
lastChar = deque.removeBack();
24+
if (firstChar !== lastChar) {
25+
isEqual = false;
26+
}
27+
}
28+
29+
return isEqual;
30+
}

‎src/ts/data-structures/deque.ts

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
export default class Deque<T> {
2+
private count: number;
3+
private lowestCount: number;
4+
private items: any;
5+
6+
constructor() {
7+
this.count = 0;
8+
this.lowestCount = 0;
9+
this.items = {};
10+
}
11+
12+
addFront(element: T) {
13+
if (this.isEmpty()) {
14+
this.addBack(element);
15+
} else if (this.lowestCount > 0) {
16+
this.lowestCount--;
17+
this.items[this.lowestCount] = element;
18+
} else {
19+
for (let i = this.count; i > 0; i--) {
20+
this.items[i] = this.items[i - 1];
21+
}
22+
this.count++;
23+
this.items[0] = element;
24+
}
25+
}
26+
27+
addBack(element: T) {
28+
this.items[this.count] = element;
29+
this.count++;
30+
}
31+
32+
removeFront() {
33+
if (this.isEmpty()) {
34+
return undefined;
35+
}
36+
const result = this.items[this.lowestCount];
37+
delete this.items[this.lowestCount];
38+
this.lowestCount++;
39+
return result;
40+
}
41+
42+
removeBack() {
43+
if (this.isEmpty()) {
44+
return undefined;
45+
}
46+
this.count--;
47+
const result = this.items[this.count];
48+
delete this.items[this.count];
49+
return result;
50+
}
51+
52+
peekFront() {
53+
if (this.isEmpty()) {
54+
return undefined;
55+
}
56+
return this.items[this.lowestCount];
57+
}
58+
59+
peekBack() {
60+
if (this.isEmpty()) {
61+
return undefined;
62+
}
63+
return this.items[this.count - 1];
64+
}
65+
66+
isEmpty() {
67+
return this.size() === 0;
68+
}
69+
70+
clear() {
71+
this.items = {};
72+
this.count = 0;
73+
this.lowestCount = 0;
74+
}
75+
76+
size() {
77+
return this.count - this.lowestCount;
78+
}
79+
80+
toString() {
81+
if (this.isEmpty()) {
82+
return '';
83+
}
84+
let objString = `${this.items[this.lowestCount]}`;
85+
for (let i = this.lowestCount + 1; i < this.count; i++) {
86+
objString = `${objString},${this.items[i]}`;
87+
}
88+
return objString;
89+
}
90+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { Compare, defaultCompare, ICompareFunction } from '../util';
2+
3+
export default class PriorityQueue<T> {
4+
private items: T[];
5+
6+
constructor(
7+
private compareFn: ICompareFunction<T> = defaultCompare,
8+
private compare: Compare = Compare.LESS_THAN
9+
) {
10+
this.items = [];
11+
}
12+
13+
enqueue(element: T) {
14+
let added = false;
15+
16+
for (let i = 0; i < this.items.length; i++) {
17+
if (this.compareFn(element, this.items[i]) === this.compare) {
18+
this.items.splice(i, 0, element);
19+
added = true;
20+
break;
21+
}
22+
}
23+
24+
if (!added) {
25+
this.items.push(element);
26+
}
27+
}
28+
29+
dequeue() {
30+
return this.items.shift();
31+
}
32+
33+
peek() {
34+
if (this.isEmpty()) {
35+
return undefined;
36+
}
37+
return this.items[0];
38+
}
39+
40+
isEmpty() {
41+
return this.items.length === 0;
42+
}
43+
44+
clear() {
45+
this.items = [];
46+
}
47+
48+
size() {
49+
return this.items.length;
50+
}
51+
52+
toString() {
53+
if (this.isEmpty()) {
54+
return '';
55+
}
56+
return this.items;
57+
}
58+
}

‎src/ts/data-structures/queue.ts

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
export default class Queue<T> {
2+
private count: number;
3+
private lowestCount: number;
4+
private items: any;
5+
6+
constructor() {
7+
this.count = 0;
8+
this.lowestCount = 0;
9+
this.items = {};
10+
}
11+
12+
enqueue(element: T) {
13+
this.items[this.count] = element;
14+
this.count++;
15+
}
16+
17+
dequeue() {
18+
if (this.isEmpty()) {
19+
return undefined;
20+
}
21+
const result = this.items[this.lowestCount];
22+
delete this.items[this.lowestCount];
23+
this.lowestCount++;
24+
return result;
25+
}
26+
27+
peek() {
28+
if (this.isEmpty()) {
29+
return undefined;
30+
}
31+
return this.items[this.lowestCount];
32+
}
33+
34+
isEmpty() {
35+
return this.count - this.lowestCount === 0;
36+
}
37+
38+
clear() {
39+
this.items = {};
40+
this.count = 0;
41+
this.lowestCount = 0;
42+
}
43+
44+
size() {
45+
return this.count - this.lowestCount;
46+
}
47+
48+
toString() {
49+
if (this.isEmpty()) {
50+
return '';
51+
}
52+
let objString = `${this.items[this.lowestCount]}`;
53+
for (let i = this.lowestCount + 1; i < this.count; i++) {
54+
objString = `${objString},${this.items[i]}`;
55+
}
56+
return objString;
57+
}
58+
}

‎src/ts/index.ts

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1+
import { hotPotato } from './others/hot-potato';
2+
import { palindromeChecker } from './others/palindrome-checker';
3+
import Deque from './data-structures/deque';
4+
import Queue from './data-structures/queue';
15
import { hanoi, hanoiStack } from './others/hanoi';
26
import { baseConverter, decimalToBinary } from './others/base-converter';
37
import StackArray from './data-structures/stack-array';
48
import Stack from './data-structures/stack';
59
import { parenthesesChecker } from './others/balanced-symbols';
10+
import { Compare, defaultCompare, ICompareFunction } from './util';
611

712
export {
813
Stack,
@@ -11,5 +16,12 @@ export {
1116
baseConverter,
1217
decimalToBinary,
1318
hanoi,
14-
hanoiStack
19+
hanoiStack,
20+
ICompareFunction,
21+
defaultCompare,
22+
Compare,
23+
Queue,
24+
Deque,
25+
hotPotato,
26+
palindromeChecker
1527
};

‎src/ts/others/hot-potato.ts

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import Queue from '../data-structures/queue';
2+
3+
export function hotPotato(elementsList: any[], num: number) {
4+
const queue = new Queue();
5+
const elimitatedList = [];
6+
7+
for (let i = 0; i < elementsList.length; i++) {
8+
queue.enqueue(elementsList[i]);
9+
}
10+
11+
while (queue.size() > 1) {
12+
for (let i = 0; i < num; i++) {
13+
queue.enqueue(queue.dequeue());
14+
}
15+
elimitatedList.push(queue.dequeue());
16+
}
17+
18+
return {
19+
elimitated: elimitatedList,
20+
winner: queue.dequeue()
21+
};
22+
}

‎src/ts/others/palindrome-checker.ts

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import Deque from '../data-structures/deque';
2+
3+
export function palindromeChecker(aString: string) {
4+
5+
if (aString === undefined || aString === null ||
6+
(aString !== null && aString.length === 0)) {
7+
return false;
8+
}
9+
10+
const deque = new Deque<string>();
11+
const lowerString = aString.toLocaleLowerCase().split(' ').join('');
12+
let isEqual = true;
13+
let firstChar: string, lastChar: string;
14+
15+
for (let i = 0; i < lowerString.length; i++) {
16+
deque.addBack(lowerString.charAt(i));
17+
}
18+
19+
while (deque.size() > 1 && isEqual) {
20+
firstChar = deque.removeFront();
21+
lastChar = deque.removeBack();
22+
if (firstChar !== lastChar) {
23+
isEqual = false;
24+
}
25+
}
26+
27+
return isEqual;
28+
}

‎src/ts/util.ts

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export type ICompareFunction<T> = (a: T, b: T) => number;
2+
3+
export enum Compare {
4+
LESS_THAN = -1,
5+
BIGGER_THAN = 1
6+
}
7+
8+
export function defaultCompare<T>(a: T, b: T): number {
9+
if (a === b) {
10+
return 0;
11+
}
12+
return a < b ? Compare.LESS_THAN : Compare.BIGGER_THAN;
13+
}

‎test/js/data-structures/deque.spec.js

+207
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
import 'mocha';
2+
import { expect } from 'chai';
3+
import Deque from '../../../src/js/data-structures/deque';
4+
5+
describe('Deque', () => {
6+
let deque;
7+
8+
beforeEach(() => {
9+
deque = new Deque();
10+
});
11+
12+
it('starts empty', () => {
13+
expect(deque.size()).to.equal(0);
14+
expect(deque.isEmpty()).to.equal(true);
15+
});
16+
17+
it('add elements in the back', () => {
18+
deque.addBack(1);
19+
expect(deque.size()).to.equal(1);
20+
21+
deque.addBack(2);
22+
expect(deque.size()).to.equal(2);
23+
24+
deque.addBack(3);
25+
expect(deque.size()).to.equal(3);
26+
});
27+
28+
it('add elements in the front', () => {
29+
deque.addFront(1);
30+
expect(deque.size()).to.equal(1);
31+
32+
deque.addFront(2);
33+
expect(deque.size()).to.equal(2);
34+
35+
deque.addFront(3);
36+
expect(deque.size()).to.equal(3);
37+
38+
deque.removeFront();
39+
deque.addFront(4);
40+
expect(deque.size()).to.equal(3);
41+
});
42+
43+
it('remove elements from the back', () => {
44+
deque.addBack(1);
45+
deque.addBack(2);
46+
deque.addBack(3);
47+
deque.addFront(0);
48+
49+
expect(deque.removeBack()).to.equal(3);
50+
expect(deque.removeBack()).to.equal(2);
51+
expect(deque.removeBack()).to.equal(1);
52+
expect(deque.removeBack()).to.equal(0);
53+
expect(deque.removeBack()).to.equal(undefined);
54+
});
55+
56+
it('remove elements from the front', () => {
57+
deque.addFront(1);
58+
deque.addBack(2);
59+
deque.addBack(3);
60+
deque.addFront(0);
61+
deque.addFront(-1);
62+
deque.addFront(-2);
63+
64+
expect(deque.removeFront()).to.equal(-2);
65+
expect(deque.removeFront()).to.equal(-1);
66+
expect(deque.removeFront()).to.equal(0);
67+
expect(deque.removeFront()).to.equal(1);
68+
expect(deque.removeFront()).to.equal(2);
69+
expect(deque.removeFront()).to.equal(3);
70+
expect(deque.removeFront()).to.equal(undefined);
71+
});
72+
73+
it('allows to peek at the front element in the deque without removing it', () => {
74+
expect(deque.peekFront()).to.equal(undefined);
75+
76+
deque.addFront(1);
77+
expect(deque.peekFront()).to.equal(1);
78+
deque.addBack(2);
79+
expect(deque.peekFront()).to.equal(1);
80+
deque.addBack(3);
81+
expect(deque.peekFront()).to.equal(1);
82+
deque.addFront(0);
83+
expect(deque.peekFront()).to.equal(0);
84+
deque.addFront(-1);
85+
expect(deque.peekFront()).to.equal(-1);
86+
deque.addFront(-2);
87+
expect(deque.peekFront()).to.equal(-2);
88+
});
89+
90+
it('allows to peek at the last element in the deque without removing it', () => {
91+
expect(deque.peekBack()).to.equal(undefined);
92+
93+
deque.addFront(1);
94+
expect(deque.peekBack()).to.equal(1);
95+
deque.addBack(2);
96+
expect(deque.peekBack()).to.equal(2);
97+
deque.addBack(3);
98+
expect(deque.peekBack()).to.equal(3);
99+
deque.addFront(0);
100+
expect(deque.peekBack()).to.equal(3);
101+
deque.addFront(-1);
102+
expect(deque.peekBack()).to.equal(3);
103+
deque.addFront(-2);
104+
expect(deque.peekBack()).to.equal(3);
105+
});
106+
107+
it('returns the correct size', () => {
108+
expect(deque.size()).to.equal(0);
109+
110+
deque.addFront(1);
111+
expect(deque.size()).to.equal(1);
112+
deque.addBack(2);
113+
expect(deque.size()).to.equal(2);
114+
deque.addBack(3);
115+
expect(deque.size()).to.equal(3);
116+
deque.addFront(0);
117+
expect(deque.size()).to.equal(4);
118+
deque.addFront(-1);
119+
expect(deque.size()).to.equal(5);
120+
deque.addFront(-2);
121+
expect(deque.size()).to.equal(6);
122+
123+
deque.clear();
124+
expect(deque.size()).to.equal(0);
125+
126+
deque.addFront(1);
127+
deque.addBack(2);
128+
expect(deque.size()).to.equal(2);
129+
130+
deque.removeFront();
131+
deque.removeBack();
132+
expect(deque.size()).to.equal(0);
133+
});
134+
135+
it('returns if it is empty', () => {
136+
expect(deque.isEmpty()).to.equal(true);
137+
138+
deque.addFront(1);
139+
expect(deque.isEmpty()).to.equal(false);
140+
deque.addBack(2);
141+
expect(deque.isEmpty()).to.equal(false);
142+
143+
deque.clear();
144+
expect(deque.isEmpty()).to.equal(true);
145+
146+
deque.addFront(1);
147+
deque.addBack(2);
148+
expect(deque.isEmpty()).to.equal(false);
149+
150+
deque.removeFront();
151+
expect(deque.isEmpty()).to.equal(false);
152+
deque.removeBack();
153+
expect(deque.isEmpty()).to.equal(true);
154+
});
155+
156+
it('clears the queue', () => {
157+
deque.clear();
158+
expect(deque.isEmpty()).to.equal(true);
159+
160+
deque.addFront(1);
161+
deque.addBack(2);
162+
expect(deque.isEmpty()).to.equal(false);
163+
164+
deque.clear();
165+
expect(deque.isEmpty()).to.equal(true);
166+
});
167+
168+
it('returns toString primitive types', () => {
169+
expect(deque.toString()).to.equal('');
170+
171+
deque.addFront(1);
172+
expect(deque.toString()).to.equal('1');
173+
174+
deque.addBack(2);
175+
expect(deque.toString()).to.equal('1,2');
176+
177+
deque.clear();
178+
expect(deque.toString()).to.equal('');
179+
180+
const queueString = new Deque();
181+
queueString.addFront('el1');
182+
expect(queueString.toString()).to.equal('el1');
183+
184+
queueString.addBack('el2');
185+
expect(queueString.toString()).to.equal('el1,el2');
186+
});
187+
188+
it('returns toString objects', () => {
189+
class MyObj {
190+
constructor(el1, el2) {
191+
this.el1 = el1;
192+
this.el2 = el2;
193+
}
194+
toString() {
195+
return `${this.el1.toString()}|${this.el2.toString()}`;
196+
}
197+
}
198+
const dequeMyObj = new Deque();
199+
expect(dequeMyObj.toString()).to.equal('');
200+
201+
dequeMyObj.addFront(new MyObj(1, 2));
202+
expect(dequeMyObj.toString()).to.equal('1|2');
203+
204+
dequeMyObj.addBack(new MyObj(3, 4));
205+
expect(dequeMyObj.toString()).to.equal('1|2,3|4');
206+
});
207+
});

‎test/js/data-structures/queue.spec.js

+171
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
import 'mocha';
2+
import { expect } from 'chai';
3+
import Queue from '../../../src/js/data-structures/queue';
4+
5+
describe('Queue', () => {
6+
let queue;
7+
8+
beforeEach(() => {
9+
queue = new Queue();
10+
});
11+
12+
it('starts empty', () => {
13+
expect(queue.size()).to.equal(0);
14+
expect(queue.isEmpty()).to.equal(true);
15+
});
16+
17+
it('enqueues elements', () => {
18+
queue.enqueue(1);
19+
expect(queue.size()).to.equal(1);
20+
queue.enqueue(2);
21+
expect(queue.size()).to.equal(2);
22+
queue.enqueue(3);
23+
expect(queue.size()).to.equal(3);
24+
25+
expect(queue.isEmpty()).to.equal(false);
26+
});
27+
28+
it('dequeue elements', () => {
29+
queue.enqueue(1);
30+
queue.enqueue(2);
31+
queue.enqueue(3);
32+
33+
expect(queue.dequeue()).to.equal(1);
34+
expect(queue.dequeue()).to.equal(2);
35+
expect(queue.dequeue()).to.equal(3);
36+
expect(queue.dequeue()).to.equal(undefined);
37+
});
38+
39+
it('implements FIFO logic', () => {
40+
queue.enqueue(1);
41+
expect(queue.peek()).to.equal(1);
42+
queue.enqueue(2);
43+
expect(queue.peek()).to.equal(1);
44+
queue.enqueue(3);
45+
expect(queue.peek()).to.equal(1);
46+
47+
expect(queue.dequeue()).to.equal(1);
48+
expect(queue.dequeue()).to.equal(2);
49+
expect(queue.dequeue()).to.equal(3);
50+
expect(queue.dequeue()).to.equal(undefined);
51+
});
52+
53+
it('allows to peek at the front element in the queue without dequeuing it', () => {
54+
expect(queue.peek()).to.equal(undefined);
55+
56+
queue.enqueue(1);
57+
expect(queue.peek()).to.equal(1);
58+
59+
queue.enqueue(2);
60+
expect(queue.peek()).to.equal(1);
61+
62+
queue.dequeue();
63+
expect(queue.peek()).to.equal(2);
64+
});
65+
66+
it('returns the correct size', () => {
67+
expect(queue.size()).to.equal(0);
68+
queue.enqueue(1);
69+
expect(queue.size()).to.equal(1);
70+
queue.enqueue(2);
71+
expect(queue.size()).to.equal(2);
72+
queue.enqueue(3);
73+
expect(queue.size()).to.equal(3);
74+
75+
queue.clear();
76+
expect(queue.isEmpty()).to.equal(true);
77+
78+
queue.enqueue(1);
79+
queue.enqueue(2);
80+
queue.enqueue(3);
81+
expect(queue.size()).to.equal(3);
82+
83+
queue.dequeue();
84+
expect(queue.size()).to.equal(2);
85+
queue.dequeue();
86+
expect(queue.size()).to.equal(1);
87+
queue.dequeue();
88+
expect(queue.size()).to.equal(0);
89+
queue.dequeue();
90+
expect(queue.size()).to.equal(0);
91+
});
92+
93+
it('returns if it is empty', () => {
94+
expect(queue.isEmpty()).to.equal(true);
95+
queue.enqueue(1);
96+
expect(queue.isEmpty()).to.equal(false);
97+
queue.enqueue(2);
98+
expect(queue.isEmpty()).to.equal(false);
99+
queue.enqueue(3);
100+
expect(queue.isEmpty()).to.equal(false);
101+
102+
queue.clear();
103+
expect(queue.isEmpty()).to.equal(true);
104+
105+
queue.enqueue(1);
106+
queue.enqueue(2);
107+
queue.enqueue(3);
108+
expect(queue.isEmpty()).to.equal(false);
109+
110+
queue.dequeue();
111+
expect(queue.isEmpty()).to.equal(false);
112+
queue.dequeue();
113+
expect(queue.isEmpty()).to.equal(false);
114+
queue.dequeue();
115+
expect(queue.isEmpty()).to.equal(true);
116+
queue.dequeue();
117+
expect(queue.isEmpty()).to.equal(true);
118+
});
119+
120+
it('clears the queue', () => {
121+
queue.clear();
122+
expect(queue.isEmpty()).to.equal(true);
123+
124+
queue.enqueue(1);
125+
queue.enqueue(2);
126+
expect(queue.isEmpty()).to.equal(false);
127+
128+
queue.clear();
129+
expect(queue.isEmpty()).to.equal(true);
130+
});
131+
132+
it('returns toString primitive types', () => {
133+
expect(queue.toString()).to.equal('');
134+
135+
queue.enqueue(1);
136+
expect(queue.toString()).to.equal('1');
137+
138+
queue.enqueue(2);
139+
expect(queue.toString()).to.equal('1,2');
140+
141+
queue.clear();
142+
expect(queue.toString()).to.equal('');
143+
144+
const queueString = new Queue();
145+
queueString.enqueue('el1');
146+
expect(queueString.toString()).to.equal('el1');
147+
148+
queueString.enqueue('el2');
149+
expect(queueString.toString()).to.equal('el1,el2');
150+
});
151+
152+
it('returns toString objects', () => {
153+
class MyObj {
154+
constructor(el1, el2) {
155+
this.el1 = el1;
156+
this.el2 = el2;
157+
}
158+
toString() {
159+
return `${this.el1.toString()}|${this.el2.toString()}`;
160+
}
161+
}
162+
const queueMyObj = new Queue();
163+
expect(queueMyObj.toString()).to.equal('');
164+
165+
queueMyObj.enqueue(new MyObj(1, 2));
166+
expect(queueMyObj.toString()).to.equal('1|2');
167+
168+
queueMyObj.enqueue(new MyObj(3, 4));
169+
expect(queueMyObj.toString()).to.equal('1|2,3|4');
170+
});
171+
});

‎test/js/others/hot-potato.spec.js

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import 'mocha';
2+
import { expect } from 'chai';
3+
import { hotPotato } from '../../../src/js/others/hot-potato';
4+
5+
describe('Hot Potato with Queue', () => {
6+
it('Hot potato game', () => {
7+
const names = ['John', 'Jack', 'Camila', 'Ingrid', 'Carl'];
8+
expect(hotPotato(names, 6).winner).to.equal('Ingrid');
9+
expect(hotPotato(names, 7).winner).to.equal('John');
10+
expect(hotPotato(names, 8).winner).to.equal('Jack');
11+
expect(hotPotato(names, 9).winner).to.equal('Ingrid');
12+
expect(hotPotato(names, 10).winner).to.equal('Carl');
13+
});
14+
});
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import 'mocha';
2+
import { expect } from 'chai';
3+
import { palindromeChecker } from '../../../src/js/others/palindrome-checker';
4+
5+
describe('Palindrome', () => {
6+
it('Palindrome Checker', () => {
7+
expect(palindromeChecker('')).to.equal(false);
8+
expect(palindromeChecker('a')).to.equal(true);
9+
expect(palindromeChecker('aa')).to.equal(true);
10+
expect(palindromeChecker('aba')).to.equal(true);
11+
expect(palindromeChecker('ab')).to.equal(false);
12+
expect(palindromeChecker('kayak')).to.equal(true);
13+
expect(palindromeChecker('radar')).to.equal(true);
14+
expect(palindromeChecker('level')).to.equal(true);
15+
expect(palindromeChecker('Was it a car or a cat I saw')).to.equal(true);
16+
expect(palindromeChecker('Step on no pets')).to.equal(true);
17+
expect(palindromeChecker('Able was I ere I saw Elba')).to.equal(true);
18+
});
19+
});

‎test/ts/data-structures/deque.spec.ts

+204
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
import 'mocha';
2+
import { expect } from 'chai';
3+
import Deque from '../../../src/ts/data-structures/deque';
4+
5+
describe('Deque', () => {
6+
let deque: Deque<number>;
7+
8+
beforeEach(() => {
9+
deque = new Deque<number>();
10+
});
11+
12+
it('starts empty', () => {
13+
expect(deque.size()).to.equal(0);
14+
expect(deque.isEmpty()).to.equal(true);
15+
});
16+
17+
it('add elements in the back', () => {
18+
deque.addBack(1);
19+
expect(deque.size()).to.equal(1);
20+
21+
deque.addBack(2);
22+
expect(deque.size()).to.equal(2);
23+
24+
deque.addBack(3);
25+
expect(deque.size()).to.equal(3);
26+
});
27+
28+
it('add elements in the front', () => {
29+
deque.addFront(1);
30+
expect(deque.size()).to.equal(1);
31+
32+
deque.addFront(2);
33+
expect(deque.size()).to.equal(2);
34+
35+
deque.addFront(3);
36+
expect(deque.size()).to.equal(3);
37+
38+
deque.removeFront();
39+
deque.addFront(4);
40+
expect(deque.size()).to.equal(3);
41+
});
42+
43+
it('remove elements from the back', () => {
44+
deque.addBack(1);
45+
deque.addBack(2);
46+
deque.addBack(3);
47+
deque.addFront(0);
48+
49+
expect(deque.removeBack()).to.equal(3);
50+
expect(deque.removeBack()).to.equal(2);
51+
expect(deque.removeBack()).to.equal(1);
52+
expect(deque.removeBack()).to.equal(0);
53+
expect(deque.removeBack()).to.equal(undefined);
54+
});
55+
56+
it('remove elements from the front', () => {
57+
deque.addFront(1);
58+
deque.addBack(2);
59+
deque.addBack(3);
60+
deque.addFront(0);
61+
deque.addFront(-1);
62+
deque.addFront(-2);
63+
64+
expect(deque.removeFront()).to.equal(-2);
65+
expect(deque.removeFront()).to.equal(-1);
66+
expect(deque.removeFront()).to.equal(0);
67+
expect(deque.removeFront()).to.equal(1);
68+
expect(deque.removeFront()).to.equal(2);
69+
expect(deque.removeFront()).to.equal(3);
70+
expect(deque.removeFront()).to.equal(undefined);
71+
});
72+
73+
it('allows to peek at the front element in the deque without removing it', () => {
74+
expect(deque.peekFront()).to.equal(undefined);
75+
76+
deque.addFront(1);
77+
expect(deque.peekFront()).to.equal(1);
78+
deque.addBack(2);
79+
expect(deque.peekFront()).to.equal(1);
80+
deque.addBack(3);
81+
expect(deque.peekFront()).to.equal(1);
82+
deque.addFront(0);
83+
expect(deque.peekFront()).to.equal(0);
84+
deque.addFront(-1);
85+
expect(deque.peekFront()).to.equal(-1);
86+
deque.addFront(-2);
87+
expect(deque.peekFront()).to.equal(-2);
88+
});
89+
90+
it('allows to peek at the last element in the deque without removing it', () => {
91+
expect(deque.peekBack()).to.equal(undefined);
92+
93+
deque.addFront(1);
94+
expect(deque.peekBack()).to.equal(1);
95+
deque.addBack(2);
96+
expect(deque.peekBack()).to.equal(2);
97+
deque.addBack(3);
98+
expect(deque.peekBack()).to.equal(3);
99+
deque.addFront(0);
100+
expect(deque.peekBack()).to.equal(3);
101+
deque.addFront(-1);
102+
expect(deque.peekBack()).to.equal(3);
103+
deque.addFront(-2);
104+
expect(deque.peekBack()).to.equal(3);
105+
});
106+
107+
it('returns the correct size', () => {
108+
expect(deque.size()).to.equal(0);
109+
110+
deque.addFront(1);
111+
expect(deque.size()).to.equal(1);
112+
deque.addBack(2);
113+
expect(deque.size()).to.equal(2);
114+
deque.addBack(3);
115+
expect(deque.size()).to.equal(3);
116+
deque.addFront(0);
117+
expect(deque.size()).to.equal(4);
118+
deque.addFront(-1);
119+
expect(deque.size()).to.equal(5);
120+
deque.addFront(-2);
121+
expect(deque.size()).to.equal(6);
122+
123+
deque.clear();
124+
expect(deque.size()).to.equal(0);
125+
126+
deque.addFront(1);
127+
deque.addBack(2);
128+
expect(deque.size()).to.equal(2);
129+
130+
deque.removeFront();
131+
deque.removeBack();
132+
expect(deque.size()).to.equal(0);
133+
});
134+
135+
it('returns if it is empty', () => {
136+
expect(deque.isEmpty()).to.equal(true);
137+
138+
deque.addFront(1);
139+
expect(deque.isEmpty()).to.equal(false);
140+
deque.addBack(2);
141+
expect(deque.isEmpty()).to.equal(false);
142+
143+
deque.clear();
144+
expect(deque.isEmpty()).to.equal(true);
145+
146+
deque.addFront(1);
147+
deque.addBack(2);
148+
expect(deque.isEmpty()).to.equal(false);
149+
150+
deque.removeFront();
151+
expect(deque.isEmpty()).to.equal(false);
152+
deque.removeBack();
153+
expect(deque.isEmpty()).to.equal(true);
154+
});
155+
156+
it('clears the queue', () => {
157+
deque.clear();
158+
expect(deque.isEmpty()).to.equal(true);
159+
160+
deque.addFront(1);
161+
deque.addBack(2);
162+
expect(deque.isEmpty()).to.equal(false);
163+
164+
deque.clear();
165+
expect(deque.isEmpty()).to.equal(true);
166+
});
167+
168+
it('returns toString primitive types', () => {
169+
expect(deque.toString()).to.equal('');
170+
171+
deque.addFront(1);
172+
expect(deque.toString()).to.equal('1');
173+
174+
deque.addBack(2);
175+
expect(deque.toString()).to.equal('1,2');
176+
177+
deque.clear();
178+
expect(deque.toString()).to.equal('');
179+
180+
const queueString = new Deque<string>();
181+
queueString.addFront('el1');
182+
expect(queueString.toString()).to.equal('el1');
183+
184+
queueString.addBack('el2');
185+
expect(queueString.toString()).to.equal('el1,el2');
186+
});
187+
188+
it('returns toString objects', () => {
189+
class MyObj {
190+
constructor(public el1: any, public el2: any) {}
191+
toString() {
192+
return `${this.el1.toString()}|${this.el2.toString()}`;
193+
}
194+
}
195+
const dequeMyObj = new Deque<MyObj>();
196+
expect(dequeMyObj.toString()).to.equal('');
197+
198+
dequeMyObj.addFront(new MyObj(1, 2));
199+
expect(dequeMyObj.toString()).to.equal('1|2');
200+
201+
dequeMyObj.addBack(new MyObj(3, 4));
202+
expect(dequeMyObj.toString()).to.equal('1|2,3|4');
203+
});
204+
});

‎test/ts/data-structures/queue.spec.ts

+168
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
import 'mocha';
2+
import { expect } from 'chai';
3+
import Queue from '../../../src/ts/data-structures/queue';
4+
5+
describe('Queue', () => {
6+
let queue: Queue<number>;
7+
8+
beforeEach(() => {
9+
queue = new Queue<number>();
10+
});
11+
12+
it('starts empty', () => {
13+
expect(queue.size()).to.equal(0);
14+
expect(queue.isEmpty()).to.equal(true);
15+
});
16+
17+
it('enqueues elements', () => {
18+
queue.enqueue(1);
19+
expect(queue.size()).to.equal(1);
20+
queue.enqueue(2);
21+
expect(queue.size()).to.equal(2);
22+
queue.enqueue(3);
23+
expect(queue.size()).to.equal(3);
24+
25+
expect(queue.isEmpty()).to.equal(false);
26+
});
27+
28+
it('dequeue elements', () => {
29+
queue.enqueue(1);
30+
queue.enqueue(2);
31+
queue.enqueue(3);
32+
33+
expect(queue.dequeue()).to.equal(1);
34+
expect(queue.dequeue()).to.equal(2);
35+
expect(queue.dequeue()).to.equal(3);
36+
expect(queue.dequeue()).to.equal(undefined);
37+
});
38+
39+
it('implements FIFO logic', () => {
40+
queue.enqueue(1);
41+
expect(queue.peek()).to.equal(1);
42+
queue.enqueue(2);
43+
expect(queue.peek()).to.equal(1);
44+
queue.enqueue(3);
45+
expect(queue.peek()).to.equal(1);
46+
47+
expect(queue.dequeue()).to.equal(1);
48+
expect(queue.dequeue()).to.equal(2);
49+
expect(queue.dequeue()).to.equal(3);
50+
expect(queue.dequeue()).to.equal(undefined);
51+
});
52+
53+
it('allows to peek at the front element in the queue without dequeuing it', () => {
54+
expect(queue.peek()).to.equal(undefined);
55+
56+
queue.enqueue(1);
57+
expect(queue.peek()).to.equal(1);
58+
59+
queue.enqueue(2);
60+
expect(queue.peek()).to.equal(1);
61+
62+
queue.dequeue();
63+
expect(queue.peek()).to.equal(2);
64+
});
65+
66+
it('returns the correct size', () => {
67+
expect(queue.size()).to.equal(0);
68+
queue.enqueue(1);
69+
expect(queue.size()).to.equal(1);
70+
queue.enqueue(2);
71+
expect(queue.size()).to.equal(2);
72+
queue.enqueue(3);
73+
expect(queue.size()).to.equal(3);
74+
75+
queue.clear();
76+
expect(queue.isEmpty()).to.equal(true);
77+
78+
queue.enqueue(1);
79+
queue.enqueue(2);
80+
queue.enqueue(3);
81+
expect(queue.size()).to.equal(3);
82+
83+
queue.dequeue();
84+
expect(queue.size()).to.equal(2);
85+
queue.dequeue();
86+
expect(queue.size()).to.equal(1);
87+
queue.dequeue();
88+
expect(queue.size()).to.equal(0);
89+
queue.dequeue();
90+
expect(queue.size()).to.equal(0);
91+
});
92+
93+
it('returns if it is empty', () => {
94+
expect(queue.isEmpty()).to.equal(true);
95+
queue.enqueue(1);
96+
expect(queue.isEmpty()).to.equal(false);
97+
queue.enqueue(2);
98+
expect(queue.isEmpty()).to.equal(false);
99+
queue.enqueue(3);
100+
expect(queue.isEmpty()).to.equal(false);
101+
102+
queue.clear();
103+
expect(queue.isEmpty()).to.equal(true);
104+
105+
queue.enqueue(1);
106+
queue.enqueue(2);
107+
queue.enqueue(3);
108+
expect(queue.isEmpty()).to.equal(false);
109+
110+
queue.dequeue();
111+
expect(queue.isEmpty()).to.equal(false);
112+
queue.dequeue();
113+
expect(queue.isEmpty()).to.equal(false);
114+
queue.dequeue();
115+
expect(queue.isEmpty()).to.equal(true);
116+
queue.dequeue();
117+
expect(queue.isEmpty()).to.equal(true);
118+
});
119+
120+
it('clears the queue', () => {
121+
queue.clear();
122+
expect(queue.isEmpty()).to.equal(true);
123+
124+
queue.enqueue(1);
125+
queue.enqueue(2);
126+
expect(queue.isEmpty()).to.equal(false);
127+
128+
queue.clear();
129+
expect(queue.isEmpty()).to.equal(true);
130+
});
131+
132+
it('returns toString primitive types', () => {
133+
expect(queue.toString()).to.equal('');
134+
135+
queue.enqueue(1);
136+
expect(queue.toString()).to.equal('1');
137+
138+
queue.enqueue(2);
139+
expect(queue.toString()).to.equal('1,2');
140+
141+
queue.clear();
142+
expect(queue.toString()).to.equal('');
143+
144+
const queueString = new Queue<string>();
145+
queueString.enqueue('el1');
146+
expect(queueString.toString()).to.equal('el1');
147+
148+
queueString.enqueue('el2');
149+
expect(queueString.toString()).to.equal('el1,el2');
150+
});
151+
152+
it('returns toString objects', () => {
153+
class MyObj {
154+
constructor(public el1: any, public el2: any) {}
155+
toString() {
156+
return `${this.el1.toString()}|${this.el2.toString()}`;
157+
}
158+
}
159+
const queueMyObj = new Queue<MyObj>();
160+
expect(queueMyObj.toString()).to.equal('');
161+
162+
queueMyObj.enqueue(new MyObj(1, 2));
163+
expect(queueMyObj.toString()).to.equal('1|2');
164+
165+
queueMyObj.enqueue(new MyObj(3, 4));
166+
expect(queueMyObj.toString()).to.equal('1|2,3|4');
167+
});
168+
});

‎test/ts/data-structures/stack.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ describe('Stack', () => {
4747
expect(stack.pop()).to.equal(undefined);
4848
});
4949

50-
it('allows to peek at the top element in he stack without popping it', () => {
50+
it('allows to peek at the top element in the stack without popping it', () => {
5151
expect(stack.peek()).to.equal(undefined);
5252

5353
stack.push(1);

‎test/ts/others/hot-potato.spec.ts

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { hotPotato } from '../../../src/ts/others/hot-potato';
2+
import 'mocha';
3+
import { expect } from 'chai';
4+
5+
describe('Hot Potato with Queue', () => {
6+
7+
it('Hot potato game', () => {
8+
const names = ['John', 'Jack', 'Camila', 'Ingrid', 'Carl'];
9+
expect(hotPotato(names, 6).winner).to.equal('Ingrid');
10+
expect(hotPotato(names, 7).winner).to.equal('John');
11+
expect(hotPotato(names, 8).winner).to.equal('Jack');
12+
expect(hotPotato(names, 9).winner).to.equal('Ingrid');
13+
expect(hotPotato(names, 10).winner).to.equal('Carl');
14+
});
15+
16+
});
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import 'mocha';
2+
import { expect } from 'chai';
3+
import { palindromeChecker } from '../../../src/ts/others/palindrome-checker';
4+
5+
describe('Palindrome', () => {
6+
7+
it('Palindrome Checker', () => {
8+
expect(palindromeChecker('')).to.equal(false);
9+
expect(palindromeChecker('a')).to.equal(true);
10+
expect(palindromeChecker('aa')).to.equal(true);
11+
expect(palindromeChecker('aba')).to.equal(true);
12+
expect(palindromeChecker('ab')).to.equal(false);
13+
expect(palindromeChecker('kayak')).to.equal(true);
14+
expect(palindromeChecker('radar')).to.equal(true);
15+
expect(palindromeChecker('level')).to.equal(true);
16+
expect(palindromeChecker('Was it a car or a cat I saw')).to.equal(true);
17+
expect(palindromeChecker('Step on no pets')).to.equal(true);
18+
expect(palindromeChecker('Able was I ere I saw Elba')).to.equal(true);
19+
});
20+
});

0 commit comments

Comments
 (0)
Please sign in to comment.