├── .babelrc
├── .editorconfig
├── .eslintrc
├── .gitignore
├── README.md
├── gulpfile.babel.js
├── package.json
├── src
├── algorithms
│ ├── arrayUtils.js
│ └── sorting
│ │ ├── bubble
│ │ └── bubble.js
│ │ ├── insertion
│ │ └── insertion.js
│ │ └── selection
│ │ └── selection.js
├── data-structures
│ ├── dictionaries
│ │ └── Dictionary.js
│ ├── linked-lists
│ │ ├── DoublyLinkedList.js
│ │ └── LinkedList.js
│ ├── queues
│ │ ├── HotPotato.js
│ │ ├── PriorityQueue.js
│ │ └── Queue.js
│ ├── sets
│ │ └── Set.js
│ └── stacks
│ │ ├── Dec2Bin.js
│ │ └── Stack.js
└── interview-questions
│ ├── arrays
│ ├── flatten.js
│ ├── question1.js
│ └── reordering.js
│ ├── dom
│ └── nodeX.html
│ ├── events
│ ├── debounce.js
│ ├── emitter.js
│ └── taxing.js
│ └── html-css
│ ├── edit-icon.html
│ └── parent.html
└── test
├── data-structures
├── dictionaries
│ └── dictionaryTest.js
├── linked-lists
│ ├── doublyLinkedListTest.js
│ └── linkedListTest.js
├── queues
│ ├── hotPotatoTest.js
│ ├── priorityQueueTest.js
│ └── queueTest.js
├── sets
│ └── setTest.js
└── stacks
│ ├── dec2BinTest.js
│ └── stackTest.js
└── globalTest.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "stage-0", "stage-1"]
3 | }
4 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | end_of_line = lf
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 |
11 | [*.md]
12 | trim_trailing_whitespace = false
13 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint",
3 | "env": {
4 | "es6": true
5 | },
6 | "parserOptions": {
7 | "sourceType": "module",
8 | "ecmaFeatures": {
9 | "jsx": true,
10 | "experimentalObjectRestSpread": true
11 | }
12 | },
13 | "rules": {
14 | "accessor-pairs": 2,
15 | "array-callback-return": 2,
16 | "block-scoped-var": 2,
17 | "brace-style": [2, 1tbs],
18 | "callback-return": 2,
19 | "comma-dangle": [2, never],
20 | "complexity": [2, 8],
21 | "curly": 2,
22 | "dot-location": [2, property],
23 | "dot-notation": 2,
24 | "default-case": 2,
25 | "eol-last": 2,
26 | "eqeqeq": 2,
27 | "indent": [2, 2, {SwitchCase: 1}],
28 | "keyword-spacing": 2,
29 | "max-depth": [2, 6],
30 | "max-len": [2, 120, 4],
31 | "max-statements": ["error", 40, { "ignoreTopLevelFunctions": true }],
32 | "no-alert": 2,
33 | "no-bitwise": 0,
34 | "no-cond-assign": 2,
35 | "no-console": 0,
36 | "no-dupe-args": 2,
37 | "no-dupe-keys": 2,
38 | "no-duplicate-case": 2,
39 | "no-dupe-class-members": 2,
40 | "no-empty": 2,
41 | "no-empty-function": 2,
42 | "no-eq-null": 2,
43 | "no-eval": 2,
44 | "no-ex-assign": 2,
45 | "no-extend-native": 2,
46 | "no-extra-boolean-cast": 2,
47 | "no-extra-parens": 2,
48 | "no-extra-semi": 2,
49 | "no-fallthrough": 2,
50 | "no-floating-decimal": 2,
51 | "no-func-assign": 2,
52 | "no-implied-eval": 2,
53 | "no-implicit-globals": 2,
54 | "no-inner-declarations": [2, "both"],
55 | "no-invalid-regexp": 2,
56 | "no-irregular-whitespace": 2,
57 | "no-iterator": 2,
58 | "no-lone-blocks": 2,
59 | "no-loop-func": 2,
60 | "no-multi-spaces": 0,
61 | "no-multi-str": 2,
62 | "no-negated-in-lhs": 2,
63 | "no-new": 2,
64 | "no-new-func": 2,
65 | "no-new-wrappers": 2,
66 | "no-obj-calls": 2,
67 | "no-redeclare": 2,
68 | "no-regex-spaces": 2,
69 | "no-restricted-syntax": [2, WithStatement],
70 | "no-sparse-arrays": 2,
71 | "no-unexpected-multiline": 2,
72 | "no-unsafe-finally": 2,
73 | "no-unreachable": 2,
74 | "no-unused-expressions": 0,
75 | "no-unused-vars": [2, {args: none}],
76 | "no-void": 2,
77 | "no-undefined": 2,
78 | "prefer-const": 2,
79 | "prefer-template": 2,
80 | "quotes": [2, single, avoid-escape],
81 | "semi": [2, "always"],
82 | "space-before-blocks": 2,
83 | "strict": [2, global],
84 | "use-isnan": 2,
85 | "valid-jsdoc": 2,
86 | "valid-typeof": 2,
87 | "vars-on-top": 2,
88 | "wrap-iife": 2
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | npm-debug.log
4 | yarn.lock
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Curso: Algoritmos y Estructura de Datos
2 |
3 | ## Estructuras de Datos
4 |
5 | ### Pilas (Stacks)
6 |
7 | Una Pila (Stack) es una colección ordenada de elementos que sigue el principio LIFO (Last In First Out - Último en entrar primero en salir).
8 |
9 | Vídeo: https://www.youtube.com/watch?v=dgZhiYpcbME
10 |
11 | ### Colas (Queues)
12 |
13 | Una Cola (Queue) es una colección ordenada de elementos que sigue el principio FIFO (First In First Out - Primero en entrar primero en salir).
14 |
15 | Vídeo: https://www.youtube.com/watch?v=jWXh_GAEdsU
16 |
17 | ### Listas Enlazadas Simples (Linked Lists)
18 |
19 | Las listas enlazadas (linked lists) son estructuras de datos similares a los Arrays pero con la diferencia que el acceso a un elemento no se hace mediante un índice sino mediante un puntero. La asignación de memoria es hecha durante la ejecución.
20 |
21 | Vídeo: https://www.youtube.com/watch?v=KRtsuoa9AOo
22 |
23 | ### Conjuntos (Sets)
24 |
25 | Un set (colección) es una colección de elementos que no están ordenados y que consta de elementos únicos (no pueden ser repetidos). Esta estructura de datos utiliza el mismo concepto Matemático pero aplicado a las Ciencias de la Computación.
26 |
27 | Operaciones:
28 |
29 | * **Union**: Dados dos sets, retorna un nuevo set con los elementos de ambos.
30 |
31 | * **Intersección**: Dados dos sets, retorna un nuevo set con los elementos existentes en ambos sets.
32 |
33 | * **Diferencia**: Dados dos sets, retorna un nuevo set con todos los elementos que existen en el primer set pero no existen en el segundo.
34 |
35 | * **SubConjunto**: Confirma si un set es subconjunto de otro.
36 |
37 | Vídeo: https://www.youtube.com/watch?v=ZLBUQwqRsd8
38 |
--------------------------------------------------------------------------------
/gulpfile.babel.js:
--------------------------------------------------------------------------------
1 | // NPM Dependencies
2 | import babel from 'gulp-babel';
3 | import eslint from 'gulp-eslint';
4 | import gulp from 'gulp';
5 | import mocha from 'gulp-mocha';
6 |
7 | // Mocha task
8 | gulp.task('test', () => {
9 | return gulp.src([
10 | 'test/**/*Test.js'
11 | ])
12 | .pipe(babel())
13 | .pipe(mocha());
14 | });
15 |
16 | // Linter task
17 | gulp.task('analyze', () => {
18 | return gulp.src([
19 | 'src/**/*.js',
20 | 'test/**/*Test.js'
21 | ])
22 | .pipe(eslint())
23 | .pipe(eslint.format())
24 | .pipe(eslint.failAfterError());
25 | });
26 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "algorithms-and-data-structures",
3 | "version": "0.0.1",
4 | "author": "Carlos Santana",
5 | "license": "MIT",
6 | "repository": {
7 | "type": "git",
8 | "url": "git://github.com/MilkZoft/algorithms-and-data-structures.git"
9 | },
10 | "scripts": {
11 | "precommit": "gulp analyze",
12 | "prepush": "gulp test",
13 | "postmerge": "yarn",
14 | "postrewrite": "yarn"
15 | },
16 | "dependencies": {
17 | "babel-cli": "6.23.0",
18 | "babel-core": "^6.23.1",
19 | "babel-eslint": "^7.1.1",
20 | "babel-preset-es2015": "^6.22.0",
21 | "babel-preset-stage-0": "^6.22.0",
22 | "babel-preset-stage-1": "^6.22.0",
23 | "babel-register": "^6.23.0",
24 | "chai": "^3.5.0",
25 | "eslint": "^3.16.1",
26 | "eslint-plugin-babel": "^4.0.1",
27 | "gulp": "^3.9.1",
28 | "gulp-babel": "^6.1.2",
29 | "gulp-eslint": "^3.0.1",
30 | "gulp-mocha": "^4.0.1",
31 | "husky": "^0.13.1",
32 | "mocha": "^3.2.0"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/algorithms/arrayUtils.js:
--------------------------------------------------------------------------------
1 | let spins = 1;
2 |
3 | export function createArray(size) {
4 | const arr = [];
5 |
6 | for (let i = size; i > 0; i--) {
7 | arr.push(i);
8 | }
9 |
10 | return arr;
11 | }
12 |
13 | export function swap(indexA, indexB, array) {
14 | const tmp = array[indexA];
15 | array[indexA] = array[indexB];
16 | array[indexB] = tmp;
17 |
18 | console.log(spins++, '-', indexA, indexB, 'SWAPPING===', tmp, array[indexA]);
19 |
20 | return array;
21 | }
22 |
--------------------------------------------------------------------------------
/src/algorithms/sorting/bubble/bubble.js:
--------------------------------------------------------------------------------
1 | import { createArray, swap } from '../../arrayUtils';
2 |
3 | let array = createArray(10);
4 |
5 | console.log('UNSORTED', array.toString(), '\n');
6 |
7 | bubleSort();
8 |
9 | console.log('\nSORTED', array.toString());
10 |
11 | function bubleSort() {
12 | for (let i = 0; i < array.length; i++) {
13 | for (let j = 0; j < array.length - 1; j++) {
14 | if (array[j] > array[j + 1]) {
15 | array = swap(j, j + 1, array);
16 | }
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/algorithms/sorting/insertion/insertion.js:
--------------------------------------------------------------------------------
1 | import { createArray } from '../../arrayUtils';
2 |
3 | const array = createArray(5);
4 |
5 | console.log('UNSORTED', array.toString(), '\n');
6 |
7 | insertionSort();
8 |
9 | console.log('\nSORTED', array.toString());
10 |
11 | function insertionSort() {
12 | let j;
13 | let tmp;
14 |
15 | for (let i = 1; i < array.length; i++) {
16 | j = i;
17 | tmp = array[i];
18 |
19 | while (j > 0 && array[j - 1] > tmp) {
20 | array[j] = array[j - 1];
21 | console.log(array[j]);
22 | j--;
23 | }
24 | array[j] = tmp;
25 | console.log(array[j], 'Insertado');
26 | console.log(array);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/algorithms/sorting/selection/selection.js:
--------------------------------------------------------------------------------
1 | import { createArray, swap } from '../../arrayUtils';
2 |
3 | let array = createArray(1000);
4 |
5 | console.log('UNSORTED', array.toString(), '\n');
6 |
7 | selectionSort();
8 |
9 | console.log('\nSORTED', array.toString());
10 |
11 | function selectionSort() {
12 | let indexMin;
13 |
14 | for (let i = 0; i < array.length - 1; i++) {
15 | indexMin = i;
16 |
17 | for (let j = i; j < array.length; j++) {
18 | if (array[indexMin] > array[j]) {
19 | indexMin = j;
20 | }
21 | }
22 |
23 | if (i !== indexMin) {
24 | array = swap(i, indexMin, array);
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/data-structures/dictionaries/Dictionary.js:
--------------------------------------------------------------------------------
1 | export default function Dictionary() {
2 | let items = {};
3 |
4 | this.set = (key, value) => {
5 | items[key] = value;
6 | };
7 |
8 | this.delete = key => {
9 | if (this.has(key)) {
10 | delete items[key];
11 |
12 | return true;
13 | }
14 |
15 | return false;
16 | };
17 |
18 | this.get = key => {
19 | return this.has(key) ? items[key] : false;
20 | };
21 |
22 | this.values = () => {
23 | const values = [];
24 |
25 | for (const key in items) {
26 | if (this.has(key)) {
27 | values.push(items[key]);
28 | }
29 | }
30 |
31 | return values;
32 | };
33 |
34 | this.keys = () => {
35 | return Object.keys(items);
36 | };
37 |
38 | this.size = () => {
39 | return Object.keys(items).length;
40 | };
41 |
42 | this.getItems = () => {
43 | return items;
44 | };
45 |
46 | this.has = key => {
47 | return key in items;
48 | };
49 |
50 | this.clear = () => {
51 | items = {};
52 | };
53 | }
54 |
--------------------------------------------------------------------------------
/src/data-structures/linked-lists/DoublyLinkedList.js:
--------------------------------------------------------------------------------
1 | export default class DoublyLinkedList {
2 | constructor() {
3 | this.head = null;
4 | this.tail = null;
5 | this.listSize = 0;
6 | }
7 |
8 | Node(element) {
9 | return {
10 | element,
11 | next: null,
12 | previous: null
13 | };
14 | }
15 |
16 | append(element) {
17 | const node = this.Node(element);
18 | let current;
19 |
20 | // Si la lista esta vacia (Primer elemento)
21 | if (this.head === null) {
22 | this.head = node;
23 | } else {
24 | // Si ya tiene datos comenzamos a recorrer la lista desde head
25 | current = this.head;
26 |
27 | // Mientras exista un element en el node.next (cuando llegue a null sera el final de la lista)
28 | while (current.next) {
29 | // current tome el valor del proximo elemento (next)
30 | current = current.next;
31 | }
32 |
33 | // Ahora current ya tiene el último elemento y asignamos el nuevo elemento a su next
34 | current.next = node;
35 | }
36 |
37 | // Incrementamos el tamaño de la lista
38 | this.listSize++;
39 | }
40 |
41 | insert(position, element) {
42 | // Validar el rango
43 | if (position >= 0 && position <= this.listSize) {
44 | const node = this.Node(element);
45 | let current = this.head;
46 | let previous;
47 | let index = 0;
48 |
49 | // Agregar un elemento al inicio la lista
50 | if (position === 0) {
51 | if (!this.head) {
52 | this.head = node;
53 | this.tail = node;
54 | } else {
55 | node.next = current;
56 | current.previous = node;
57 | this.head = node;
58 | }
59 | // Último elemento
60 | } else if (position === this.listSize) {
61 | current = tail;
62 | current.next = node;
63 | node.previous = current;
64 | this.tail = node;
65 | } else {
66 | while (index++ < position) {
67 | previous = current;
68 | current = current.next;
69 | }
70 |
71 | node.next = current;
72 | previous.next = node;
73 |
74 | current.previous = node;
75 | node.previous = previous;
76 | }
77 |
78 | // Incrementamos el tamaño de la lista
79 | this.listSize++;
80 |
81 | return true;
82 | }
83 |
84 | return false;
85 | }
86 |
87 | removeAt(position) {
88 | // Validar el rango
89 | if (position > -1 && position < this.listSize) {
90 | let current = this.head;
91 | let previous;
92 | let index = 0;
93 |
94 | // Quitamos el primer elemento
95 | if (position === 0) {
96 | this.head = current.next;
97 |
98 | if (this.listSize === 1) {
99 | this.tail = null;
100 | } else {
101 | this.head.previous = null;
102 | }
103 | } else if (position === this.listSize - 1) {
104 | current = this.tail;
105 | this.tail = current.previous;
106 | this.tail.next = null;
107 | } else {
108 | // Recorremos la lista hasta la posicion indicada
109 | while (index++ < position) {
110 | previous = current;
111 | current = current.next;
112 | }
113 |
114 | // Enlazamos el elemento anterior con el next del current (saltamos el elemento para eliminarlo)
115 | previous.next = current.next;
116 | current.next.previous = previous;
117 | }
118 |
119 | this.listSize--;
120 |
121 | // Retornamos el elemento eliminado
122 | return current.element;
123 | }
124 |
125 | return false;
126 | }
127 |
128 | remove(element) {
129 | const index = this.indexOf(element);
130 |
131 | return this.removeAt(index);
132 | }
133 |
134 | indexOf(element) {
135 | let current = this.head;
136 | let index = 0;
137 |
138 | while (current) {
139 | if (current.element === element) {
140 | return index;
141 | }
142 |
143 | index++;
144 | current = current.next;
145 | }
146 |
147 | return -1;
148 | }
149 |
150 | hasElements() {
151 | return this.listSize > 0;
152 | }
153 |
154 | size() {
155 | return this.listSize;
156 | }
157 |
158 | print() {
159 | let current = this.head;
160 | let string = '';
161 | let index = 0;
162 |
163 | while (current) {
164 | string += `[${index}]${current.element}${current.next ? '=>' : ''}`;
165 | current = current.next;
166 | index++;
167 | }
168 |
169 | return string;
170 | }
171 | }
172 |
--------------------------------------------------------------------------------
/src/data-structures/linked-lists/LinkedList.js:
--------------------------------------------------------------------------------
1 | export default class LinkedList {
2 | constructor() {
3 | this.head = null;
4 | this.listSize = 0;
5 | }
6 |
7 | Node(element) {
8 | return {
9 | element,
10 | next: null
11 | };
12 | }
13 |
14 | append(element) {
15 | const node = this.Node(element);
16 | let current;
17 |
18 | // Si la lista esta vacia (Primer elemento)
19 | if (this.head === null) {
20 | this.head = node;
21 | } else {
22 | // Si ya tiene datos comenzamos a recorrer la lista desde head
23 | current = this.head;
24 |
25 | // Mientras exista un element en el node.next (cuando llegue a null sera el final de la lista)
26 | while (current.next) {
27 | // current tome el valor del proximo elemento (next)
28 | current = current.next;
29 | }
30 |
31 | // Ahora current ya tiene el último elemento y asignamos el nuevo elemento a su next
32 | current.next = node;
33 | }
34 |
35 | // Incrementamos el tamaño de la lista
36 | this.listSize++;
37 | }
38 |
39 | insert(position, element) {
40 | // Validar el rango
41 | if (position >= 0 && position <= this.listSize) {
42 | const node = this.Node(element);
43 | let current = this.head;
44 | let previous;
45 | let index = 0;
46 |
47 | // Agregar un elemento al inicio la lista
48 | if (position === 0) {
49 | node.next = current;
50 | this.head = node;
51 | } else {
52 | // Recorrer la lista hasta la posicion indicada
53 | while (index++ < posicion) {
54 | previous = current;
55 | current = current.next;
56 | }
57 |
58 | node.next = current;
59 | previous.next = node;
60 | }
61 |
62 | // Incrementamos el tamaño de la lista
63 | this.listSize++;
64 |
65 | return true;
66 | }
67 |
68 | return false;
69 | }
70 |
71 | removeAt(position) {
72 | // Validar el rango
73 | if (position > -1 && position < this.listSize) {
74 | let current = this.head;
75 | let previous;
76 | let index = 0;
77 |
78 | // Quitamos el primer elemento
79 | if (position === 0) {
80 | this.head = current.next;
81 | } else {
82 | // Recorremos la lista hasta la posicion indicada
83 | while (index++ < position) {
84 | previous = current;
85 | current = current.next;
86 | }
87 |
88 | // Enlazamos el elemento anterior con el next del current (saltamos el elemento para eliminarlo)
89 | previous.next = current.next;
90 | }
91 |
92 | this.listSize--;
93 |
94 | // Retornamos el elemento eliminado
95 | return current.element;
96 | }
97 |
98 | return false;
99 | }
100 |
101 | remove(element) {
102 | const index = this.indexOf(element);
103 |
104 | return this.removeAt(index);
105 | }
106 |
107 | indexOf(element) {
108 | let current = this.head;
109 | let index = 0;
110 |
111 | while (current) {
112 | if (current.element === element) {
113 | return index;
114 | }
115 |
116 | index++;
117 | current = current.next;
118 | }
119 |
120 | return -1;
121 | }
122 |
123 | hasElements() {
124 | return this.listSize > 0;
125 | }
126 |
127 | size() {
128 | return this.listSize;
129 | }
130 |
131 | print() {
132 | let current = this.head;
133 | let string = '';
134 | let index = 0;
135 |
136 | while (current) {
137 | string += `[${index}]${current.element}${current.next ? '=>' : ''}`;
138 | current = current.next;
139 | index++;
140 | }
141 |
142 | return string;
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/src/data-structures/queues/HotPotato.js:
--------------------------------------------------------------------------------
1 | import Queue from './Queue';
2 |
3 | export default function HotPotato(players, spins) {
4 | const queue = new Queue();
5 |
6 | for (let i = 0; i < players.length; i++) {
7 | queue.enqueue(players[i]);
8 | }
9 |
10 | let eliminated = '';
11 |
12 | while (queue.size() > 1) {
13 | for (let i = 0; i < spins; i++) {
14 | queue.enqueue(queue.dequeue());
15 | }
16 |
17 | eliminated = queue.dequeue();
18 |
19 | console.log(eliminated, 'fue eliminado de la papa caliente');
20 | }
21 |
22 | return queue.dequeue();
23 | }
24 |
--------------------------------------------------------------------------------
/src/data-structures/queues/PriorityQueue.js:
--------------------------------------------------------------------------------
1 | export default function PriorityQueue() {
2 | let items = [];
3 |
4 | function QueueElement(element, priority) {
5 | this.element = element;
6 | this.priority = priority || 1;
7 | }
8 |
9 | this.enqueue = (element, priority) => {
10 | const queueElement = new QueueElement(element, priority);
11 | let added = false;
12 |
13 | for (let i = 0; i < items.length; i++) {
14 | if (queueElement.priority < items[i].priority) {
15 | items.splice(i, 0, queueElement);
16 | added = true;
17 | break;
18 | }
19 | }
20 |
21 | if (!added) {
22 | items.push(queueElement);
23 | }
24 | };
25 |
26 | this.dequeue = () => {
27 | return items.shift();
28 | };
29 |
30 | this.front = () => {
31 | return items[0];
32 | };
33 |
34 | this.hasElements = () => {
35 | return items.length > 0;
36 | };
37 |
38 | this.size = () => {
39 | return items.length;
40 | };
41 |
42 | this.print = () => {
43 | let printStr = '';
44 | let pipe = '|';
45 |
46 | for (let i = 0; i < items.length; i++) {
47 | if (i === items.length - 1) {
48 | pipe = '';
49 | }
50 |
51 | printStr += `${items[i].element}-${items[i].priority}${pipe}`;
52 | }
53 |
54 | return printStr;
55 | };
56 |
57 | this.clear = () => {
58 | items = [];
59 | };
60 | }
61 |
--------------------------------------------------------------------------------
/src/data-structures/queues/Queue.js:
--------------------------------------------------------------------------------
1 | export default function Queue() {
2 | let items = [];
3 |
4 | this.enqueue = element => {
5 | items.push(element);
6 | };
7 |
8 | this.dequeue = () => {
9 | return items.shift();
10 | };
11 |
12 | this.front = () => {
13 | return items[0];
14 | };
15 |
16 | this.hasElements = () => {
17 | return items.length > 0;
18 | };
19 |
20 | this.size = () => {
21 | return items.length;
22 | };
23 |
24 | this.print = () => {
25 | return items.toString();
26 | };
27 |
28 | this.clear = () => {
29 | items = [];
30 | };
31 | }
32 |
--------------------------------------------------------------------------------
/src/data-structures/sets/Set.js:
--------------------------------------------------------------------------------
1 | export default function Set() {
2 | let items = {};
3 |
4 | this.getItems = () => {
5 | return items;
6 | };
7 |
8 | this.add = value => {
9 | if (!this.has(value)) {
10 | items[value] = value;
11 |
12 | return true;
13 | }
14 |
15 | return false;
16 | };
17 |
18 | this.delete = value => {
19 | if (this.has(value)) {
20 | delete items[value];
21 |
22 | return true;
23 | }
24 |
25 | return false;
26 | };
27 |
28 | this.has = value => {
29 | return items.hasOwnProperty(value);
30 | };
31 |
32 | this.clear = () => {
33 | items = {};
34 | };
35 |
36 | this.size = () => {
37 | return Object.keys(items).length;
38 | };
39 |
40 | this.values = () => {
41 | const values = [];
42 | const keys = Object.keys(items);
43 |
44 | for (let i = 0; i < keys.length; i++) {
45 | values.push(items[keys[i]]);
46 | }
47 |
48 | return values;
49 | };
50 |
51 | this.union = otherSet => {
52 | const unionSet = new Set();
53 | let values = this.values();
54 |
55 | for (let i = 0; i < values.length; i++) {
56 | unionSet.add(values[i]);
57 | }
58 |
59 | values = otherSet.values();
60 |
61 | for (let i = 0; i < values.length; i++) {
62 | unionSet.add(values[i]);
63 | }
64 |
65 | return unionSet;
66 | };
67 |
68 | this.intersection = otherSet => {
69 | const intersectionSet = new Set();
70 | const values = this.values();
71 |
72 | for (let i = 0; i < values.length; i++) {
73 | if (otherSet.has(values[i])) {
74 | intersectionSet.add(values[i]);
75 | }
76 | }
77 |
78 | return intersectionSet;
79 | };
80 |
81 | this.difference = otherSet => {
82 | const differenceSet = new Set();
83 | const values = this.values();
84 |
85 | for (let i = 0; i < values.length; i++) {
86 | if (!otherSet.has(values[i])) {
87 | differenceSet.add(values[i]);
88 | }
89 | }
90 |
91 | return differenceSet;
92 | };
93 |
94 | this.subset = otherSet => {
95 | if (this.size() > otherSet.size()) {
96 | return false;
97 | } else {
98 | const values = this.values();
99 |
100 | for (let i = 0; i < values.length; i++) {
101 | if (!otherSet.has(values[i])) {
102 | return false;
103 | }
104 | }
105 |
106 | return true;
107 | }
108 | };
109 | }
110 |
--------------------------------------------------------------------------------
/src/data-structures/stacks/Dec2Bin.js:
--------------------------------------------------------------------------------
1 | import Stack from './Stack';
2 |
3 | export default function dec2Bin(dNumber) {
4 | if (dNumber === 0) {
5 | return '0';
6 | }
7 |
8 | const stack = new Stack();
9 | let rem;
10 | let binaryString = '';
11 |
12 | while (dNumber > 0) {
13 | // Remaining
14 | rem = Math.floor(dNumber % 2);
15 |
16 | // Pushing to the stack
17 | stack.push(rem);
18 |
19 | // Divide by 2
20 | dNumber = Math.floor(dNumber / 2);
21 | }
22 |
23 | // While the stack has elements
24 | while (stack.hasElements()) {
25 | // Concatenate each element.
26 | binaryString += stack.pop().toString();
27 | }
28 |
29 | return binaryString;
30 | }
31 |
--------------------------------------------------------------------------------
/src/data-structures/stacks/Stack.js:
--------------------------------------------------------------------------------
1 | export default function Stack() {
2 | let items = [];
3 |
4 | this.push = element => {
5 | items.push(element);
6 | };
7 |
8 | this.pop = () => {
9 | return this.hasElements() ? items.pop() : false;
10 | };
11 |
12 | this.last = () => {
13 | return items[items.length - 1];
14 | };
15 |
16 | this.hasElements = () => {
17 | return items.length > 0;
18 | };
19 |
20 | this.size = () => {
21 | return items.length;
22 | };
23 |
24 | this.print = () => {
25 | return items.toString();
26 | };
27 |
28 | this.clear = () => {
29 | items = [];
30 | };
31 | }
32 |
--------------------------------------------------------------------------------
/src/interview-questions/arrays/flatten.js:
--------------------------------------------------------------------------------
1 | /*
2 | Write a function that deeply flatten an array
3 | */
4 |
5 | const array = [1, [2, [[3, 4], 5], 6]];
6 |
7 | function flatten(array) {
8 | return array.reduce((acc, value) => {
9 | return acc.concat(value instanceof Array ? flatten(value) : value);
10 | }, []);
11 | }
12 |
13 | console.log(flatten(array));
14 |
--------------------------------------------------------------------------------
/src/interview-questions/arrays/question1.js:
--------------------------------------------------------------------------------
1 | /*
2 | We have an array of objects A and an array of indexes B.
3 | Reorder objects in array A with given indexes in array B. Do not change array A's length.
4 |
5 | Example:
6 | let a = [C, D, E, F, G];
7 | let b = [3, 0, 4, 1, 2];
8 |
9 | sort(a, b);
10 | // a is now [D, F, G, C, E];
11 | // b is now [0, 1, 2, 3, 4]
12 | */
13 |
14 | function swap(array, indexA, indexB) {
15 | const tmp = array[indexA];
16 | array[indexA] = array[indexB];
17 | array[indexB] = tmp;
18 |
19 | return array;
20 | }
21 |
22 | function sort(a, b) {
23 | for (let i = 0; i < b.length; i++) {
24 | if (i !== b[i]) {
25 | a = swap(a, i, b[i]);
26 | b = swap(b, i, b[i]);
27 | }
28 | }
29 |
30 | return a;
31 | }
32 |
33 | sort(['C', 'D', 'E', 'F', 'G'], [3, 0, 4, 1, 2]);
34 |
--------------------------------------------------------------------------------
/src/interview-questions/arrays/reordering.js:
--------------------------------------------------------------------------------
1 | /*
2 | Given an input array and another array that describes a new
3 | index for each element, mutate the input array so that each element ends up
4 | in their new index. Discuss the runtime of the algorithm and how you can be
5 | sure there won't be any infinite loops.
6 | */
7 |
8 | let array = ['A', 'B', 'C', 'D', 'E', 'F'];
9 | const indices = [2, 3, 4, 0, 5, 1];
10 |
11 | array = indices.map((value, index) => {
12 | return array[indices.indexOf(index)];
13 | });
14 |
15 | // returns: ["D", "F", "A", "B", "C", "E"]
16 |
--------------------------------------------------------------------------------
/src/interview-questions/dom/nodeX.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | NodeX
5 |
6 |
7 |
8 |
18 |
19 |
29 |
30 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/src/interview-questions/events/debounce.js:
--------------------------------------------------------------------------------
1 | // Returns a function, that, as long as it continues to be invoked, will not
2 | // be triggered. The function will be called after it stops being called for
3 | // N milliseconds. If `immediate` is passed, trigger the function on the
4 | // leading edge, instead of the trailing.
5 |
6 | function debounce(fn, wait, immediate) {
7 | let timeout;
8 |
9 | return () => {
10 | const args = arguments;
11 | const later = () => {
12 | timeout = null;
13 |
14 | if (!immediate) {
15 | fn.apply(null, args);
16 | }
17 | };
18 |
19 | const callNow = immediate && !timeout;
20 |
21 | clearTimeout(timeout);
22 |
23 | timeout = setTimeout(later, wait);
24 |
25 | if (callNow) {
26 | fn.apply(null, args);
27 | }
28 | };
29 | }
30 |
31 | const myEfficientFn = debounce(() => {
32 | // All the taxing stuff you do
33 | }, 200);
34 |
35 | window.addEventListener('scroll', myEfficientFn);
36 |
--------------------------------------------------------------------------------
/src/interview-questions/events/emitter.js:
--------------------------------------------------------------------------------
1 | class EventEmitter {
2 | constructor() {
3 | this.events = {};
4 | }
5 |
6 | emit(eventName, data) {
7 | const event = this.events[eventName];
8 |
9 | if (event) {
10 | event.forEach(fn => {
11 | fn.call(null, data);
12 | });
13 | }
14 | }
15 |
16 | subscribe(eventName, fn) {
17 | if (!this.events[eventName]) {
18 | this.events[eventName] = [];
19 | }
20 |
21 | this.events[eventName].push(fn);
22 | }
23 |
24 | unsubscribe(eventName) {
25 | if (this.events[eventName]) {
26 | delete this.events[eventName];
27 | }
28 | }
29 | }
30 |
31 | document.addEventListener('DOMContentLoaded', event => {
32 | const input = document.querySelector('input[type="text"]');
33 | const button = document.querySelector('button');
34 | const h1 = document.querySelector('h1');
35 | const emitter = new EventEmitter();
36 |
37 | emitter.subscribe('event:name-changed', data => {
38 | h1.innerHTML = `Your name is: ${data.name}`;
39 | });
40 |
41 | emitter.subscribe('event:name-changed', data => {
42 | console.log(`Your name 2 is: ${data.name}`);
43 | });
44 |
45 | // emitter.unsubscribe('event:name-changed');
46 |
47 | button.addEventListener('click', () => {
48 | emitter.emit('event:name-changed', {
49 | name: input.value
50 | });
51 | });
52 | });
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/src/interview-questions/events/taxing.js:
--------------------------------------------------------------------------------
1 | /*
2 | If you were building a search tool and wanted search
3 | results to pop up as you typed but the server call was taxing,
4 | write a function that gets called on every key down but calls the server
5 | when the user stops typing for 400ms.
6 | */
7 |
8 | const searchField = document.getElementById('searchField');
9 | let lastTimeId;
10 |
11 | searchField.addEventListener('keydown', (e) => {
12 | if (typeof lastTimeId !== 'undefined') {
13 | clearTimeout(lastTimeId);
14 | }
15 |
16 | lastTimeId = setTimeout(() => {
17 | // Do search stuff
18 | console.log(`Do search for ${searchField.value}`);
19 | }, 400);
20 | });
21 |
--------------------------------------------------------------------------------
/src/interview-questions/html-css/edit-icon.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 | Parent
8 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/src/interview-questions/html-css/parent.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 | Parent
8 |
26 |
27 |
28 |
29 |

30 |
31 |

32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/test/data-structures/dictionaries/dictionaryTest.js:
--------------------------------------------------------------------------------
1 | import '../../globalTest';
2 | import Dictionary from '../../../src/data-structures/dictionaries/Dictionary';
3 |
4 | const dictionary = new Dictionary();
5 |
6 | describe('@Dictionary', () => {
7 | describe('#set', () => {
8 | it('should be a function', () => {
9 | assert.typeOf(dictionary.set, 'function', 'set should be a function');
10 | });
11 |
12 | it('should set new element(s)', () => {
13 | dictionary.set('Carlos', 'carlos@gmail.com');
14 | dictionary.set('Cristina', 'cristina@gmail.com');
15 | dictionary.set('Javier', 'javier@gmail.com');
16 |
17 | console.log(cyan, 'Current Dictionary ========> ', green, dictionary.getItems());
18 |
19 | // The set should have 3 elements (length)
20 | const actualResult = dictionary.size();
21 | const expectedResult = 3;
22 |
23 | assert.isTrue(expectedResult === actualResult);
24 | });
25 | });
26 |
27 | describe('#delete', () => {
28 | it('should be a function', () => {
29 | assert.typeOf(dictionary.delete, 'function', 'delete should be a function');
30 | });
31 |
32 | it('should delete an element', () => {
33 | const actualResult = dictionary.delete('Cristina');
34 | const expectedResult = true;
35 |
36 | console.log(cyan, 'Current Dictionary ========> ', green, dictionary.getItems());
37 |
38 | assert.isTrue(expectedResult === actualResult);
39 | });
40 | });
41 |
42 | describe('#has', () => {
43 | it('should be a function', () => {
44 | assert.typeOf(dictionary.has, 'function', 'has should be a function');
45 | });
46 |
47 | it('should validate if a set has an element', () => {
48 | // Getting the first element
49 | const actualResult = dictionary.has('Carlos');
50 | const expectedResult = true;
51 |
52 | assert.isTrue(expectedResult === actualResult);
53 | });
54 | });
55 |
56 | describe('#size', () => {
57 | it('should be a function', () => {
58 | assert.typeOf(dictionary.size, 'function', 'size should be a function');
59 | });
60 |
61 | it('should return the current size of the queue', () => {
62 | // Getting the size of the actual list
63 | const actualResult = dictionary.size();
64 | const expectedResult = 2;
65 |
66 | assert.isTrue(expectedResult === actualResult);
67 | });
68 | });
69 |
70 | describe('#get', () => {
71 | it('should be a function', () => {
72 | assert.typeOf(dictionary.get, 'function', 'get should be a function');
73 | });
74 |
75 | it('should return the selected element', () => {
76 | const actualResult = dictionary.get('Javier');
77 | const expectedResult = 'javier@gmail.com';
78 |
79 | console.log(cyan, 'Get ========> ', green, actualResult);
80 |
81 | assert.isTrue(expectedResult === actualResult);
82 | });
83 | });
84 |
85 | describe('#values', () => {
86 | it('should be a function', () => {
87 | assert.typeOf(dictionary.values, 'function', 'values should be a function');
88 | });
89 |
90 | it('should return the current values in array', () => {
91 | const actualResult = dictionary.values();
92 | const expectedResult = ['carlos@gmail.com', 'javier@gmail.com'];
93 |
94 | console.log(cyan, 'Values ========> ', green, actualResult);
95 |
96 | assert.deepEqual(expectedResult, actualResult, 'expectedResult should match actualResult');
97 | });
98 | });
99 |
100 | describe('#keys', () => {
101 | it('should be a function', () => {
102 | assert.typeOf(dictionary.keys, 'function', 'keys should be a function');
103 | });
104 |
105 | it('should return the current keys in array', () => {
106 | const actualResult = dictionary.keys();
107 | const expectedResult = ['Carlos', 'Javier'];
108 |
109 | console.log(cyan, 'Keys ========> ', green, actualResult);
110 |
111 | assert.deepEqual(expectedResult, actualResult, 'expectedResult should match actualResult');
112 | });
113 | });
114 |
115 | describe('#clear', () => {
116 | it('should be a function', () => {
117 | assert.typeOf(dictionary.clear, 'function', 'clear should be a function');
118 | });
119 |
120 | it('should clear the dictionary', () => {
121 | dictionary.clear();
122 |
123 | const actualResult = dictionary.size();
124 | const expectedResult = 0;
125 |
126 | assert.isTrue(expectedResult === actualResult);
127 | });
128 | });
129 | });
130 |
--------------------------------------------------------------------------------
/test/data-structures/linked-lists/doublyLinkedListTest.js:
--------------------------------------------------------------------------------
1 | import '../../globalTest';
2 | import DoublyLinkedList from '../../../src/data-structures/linked-Lists/DoublyLinkedList';
3 |
4 | const List = new DoublyLinkedList();
5 |
6 | describe('@DoublyLinkedList', () => {
7 | describe('#append', () => {
8 | it('should be a function', () => {
9 | assert.typeOf(List.append, 'function', 'append should be a function');
10 | });
11 |
12 | it('should add new element(s)', () => {
13 | List.append(15);
14 | List.append(10);
15 | List.append(13);
16 | List.append(11);
17 | List.append(12);
18 |
19 | console.log(cyan, 'Current List ========> ', green, List.print());
20 |
21 | // The queue should have 5 elements (length)
22 | const actualResult = List.size();
23 | const expectedResult = 5;
24 |
25 | assert.isTrue(expectedResult === actualResult);
26 | });
27 | });
28 |
29 | describe('#insert', () => {
30 | it('should be a function', () => {
31 | assert.typeOf(List.insert, 'function', 'insert should be a function');
32 | });
33 |
34 | it('should insert at the beginning of the list', () => {
35 | // Inserting in position 0
36 | List.insert(0, 20);
37 |
38 | const actualResult = List.indexOf(20);
39 | const expectedResult = 0;
40 |
41 | console.log(cyan, 'Current List ========> ', green, List.print());
42 |
43 | assert.isTrue(expectedResult === actualResult);
44 | });
45 | });
46 |
47 | describe('#removeAt', () => {
48 | it('should be a function', () => {
49 | assert.typeOf(List.removeAt, 'function', 'removeAt should be a function');
50 | });
51 |
52 | it('should remove the element in position 4', () => {
53 | // Getting the first element
54 | const actualResult = List.removeAt(4);
55 | const expectedResult = 11;
56 |
57 | console.log(cyan, 'Current List ========> ', red, List.print());
58 |
59 | assert.isTrue(expectedResult === actualResult);
60 | });
61 | });
62 |
63 | describe('#remove', () => {
64 | it('should be a function', () => {
65 | assert.typeOf(List.remove, 'function', 'remove should be a function');
66 | });
67 |
68 | it('should remove a specific element', () => {
69 | // The queue has elements?
70 | const actualResult = List.remove(10);
71 | const expectedResult = 10;
72 |
73 | console.log(cyan, 'Current List ========> ', red, List.print());
74 |
75 | assert.isTrue(expectedResult === actualResult);
76 | });
77 | });
78 |
79 | describe('#indexOf', () => {
80 | it('should be a function', () => {
81 | assert.typeOf(List.indexOf, 'function', 'indexOf should be a function');
82 | });
83 |
84 | it('should return the position of the element', () => {
85 | // Getting the size of the actual queue
86 | const actualResult = List.indexOf(12);
87 | const expectedResult = 3;
88 |
89 | assert.isTrue(expectedResult === actualResult);
90 | });
91 | });
92 |
93 | describe('#hasElements', () => {
94 | it('should be a function', () => {
95 | assert.typeOf(List.hasElements, 'function', 'hasElements should be a function');
96 | });
97 |
98 | it('should return true if the list has elements', () => {
99 | const actualResult = List.hasElements();
100 | const expectedResult = true;
101 |
102 | assert.isTrue(expectedResult === actualResult);
103 | });
104 | });
105 |
106 | describe('#size', () => {
107 | it('should be a function', () => {
108 | assert.typeOf(List.size, 'function', 'size should be a function');
109 | });
110 |
111 | it('should return the current size of the queue', () => {
112 | // Getting the size of the actual list
113 | const actualResult = List.size();
114 | const expectedResult = 4;
115 |
116 | assert.isTrue(expectedResult === actualResult);
117 | });
118 | });
119 |
120 | describe('#print', () => {
121 | it('should be a function', () => {
122 | assert.typeOf(List.print, 'function', 'print should be a function');
123 | });
124 |
125 | it('should print the current list', () => {
126 | const actualResult = List.print();
127 | const expectedResult = '[0]20=>[1]15=>[2]13=>[3]12';
128 |
129 | assert.isTrue(expectedResult === actualResult);
130 | });
131 | });
132 | });
133 |
--------------------------------------------------------------------------------
/test/data-structures/linked-lists/linkedListTest.js:
--------------------------------------------------------------------------------
1 | import '../../globalTest';
2 | import LinkedList from '../../../src/data-structures/linked-Lists/LinkedList';
3 |
4 | const List = new LinkedList();
5 |
6 | describe('@LinkedList', () => {
7 | describe('#append', () => {
8 | it('should be a function', () => {
9 | assert.typeOf(List.append, 'function', 'append should be a function');
10 | });
11 |
12 | it('should add new element(s)', () => {
13 | List.append(15);
14 | List.append(10);
15 | List.append(13);
16 | List.append(11);
17 | List.append(12);
18 |
19 | console.log(cyan, 'Current List ========> ', green, List.print());
20 |
21 | // The queue should have 5 elements (length)
22 | const actualResult = List.size();
23 | const expectedResult = 5;
24 |
25 | assert.isTrue(expectedResult === actualResult);
26 | });
27 | });
28 |
29 | describe('#insert', () => {
30 | it('should be a function', () => {
31 | assert.typeOf(List.insert, 'function', 'insert should be a function');
32 | });
33 |
34 | it('should insert at the beginning of the list', () => {
35 | // Inserting in position 0
36 | List.insert(0, 20);
37 |
38 | const actualResult = List.indexOf(20);
39 | const expectedResult = 0;
40 |
41 | console.log(cyan, 'Current List ========> ', green, List.print());
42 |
43 | assert.isTrue(expectedResult === actualResult);
44 | });
45 | });
46 |
47 | describe('#removeAt', () => {
48 | it('should be a function', () => {
49 | assert.typeOf(List.removeAt, 'function', 'removeAt should be a function');
50 | });
51 |
52 | it('should remove the element in position 4', () => {
53 | // Getting the first element
54 | const actualResult = List.removeAt(4);
55 | const expectedResult = 11;
56 |
57 | console.log(cyan, 'Current List ========> ', red, List.print());
58 |
59 | assert.isTrue(expectedResult === actualResult);
60 | });
61 | });
62 |
63 | describe('#remove', () => {
64 | it('should be a function', () => {
65 | assert.typeOf(List.remove, 'function', 'remove should be a function');
66 | });
67 |
68 | it('should remove a specific element', () => {
69 | // The queue has elements?
70 | const actualResult = List.remove(10);
71 | const expectedResult = 10;
72 |
73 | console.log(cyan, 'Current List ========> ', red, List.print());
74 |
75 | assert.isTrue(expectedResult === actualResult);
76 | });
77 | });
78 |
79 | describe('#indexOf', () => {
80 | it('should be a function', () => {
81 | assert.typeOf(List.indexOf, 'function', 'indexOf should be a function');
82 | });
83 |
84 | it('should return the position of the element', () => {
85 | // Getting the size of the actual queue
86 | const actualResult = List.indexOf(12);
87 | const expectedResult = 3;
88 |
89 | assert.isTrue(expectedResult === actualResult);
90 | });
91 | });
92 |
93 | describe('#hasElements', () => {
94 | it('should be a function', () => {
95 | assert.typeOf(List.hasElements, 'function', 'hasElements should be a function');
96 | });
97 |
98 | it('should return true if the list has elements', () => {
99 | const actualResult = List.hasElements();
100 | const expectedResult = true;
101 |
102 | assert.isTrue(expectedResult === actualResult);
103 | });
104 | });
105 |
106 | describe('#size', () => {
107 | it('should be a function', () => {
108 | assert.typeOf(List.size, 'function', 'size should be a function');
109 | });
110 |
111 | it('should return the current size of the queue', () => {
112 | // Getting the size of the actual list
113 | const actualResult = List.size();
114 | const expectedResult = 4;
115 |
116 | assert.isTrue(expectedResult === actualResult);
117 | });
118 | });
119 |
120 | describe('#print', () => {
121 | it('should be a function', () => {
122 | assert.typeOf(List.print, 'function', 'print should be a function');
123 | });
124 |
125 | it('should print the current list', () => {
126 | const actualResult = List.print();
127 | const expectedResult = '[0]20=>[1]15=>[2]13=>[3]12';
128 |
129 | assert.isTrue(expectedResult === actualResult);
130 | });
131 | });
132 | });
133 |
--------------------------------------------------------------------------------
/test/data-structures/queues/hotPotatoTest.js:
--------------------------------------------------------------------------------
1 | import '../../globalTest';
2 | import HotPotato from '../../../src/data-structures/queues/HotPotato';
3 |
4 | describe('@HotPotato', () => {
5 | describe('#HotPotato', () => {
6 | it('should be a function', () => {
7 | assert.typeOf(HotPotato, 'function', 'HotPotato should be a function');
8 | });
9 |
10 | it('should get a winner from the hot potato game', () => {
11 | // HotPotato Players
12 | const players = ['Carlos', 'Cristina', 'Javier', 'Jona', 'Sam'];
13 |
14 | // The winner is...
15 | const actualResult = HotPotato(players, 7);
16 | const expectedResult = 'Carlos';
17 |
18 | assert.isTrue(expectedResult === actualResult);
19 | });
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/test/data-structures/queues/priorityQueueTest.js:
--------------------------------------------------------------------------------
1 | import '../../globalTest';
2 | import PriorityQueue from '../../../src/data-structures/queues/PriorityQueue';
3 |
4 | const {
5 | enqueue,
6 | dequeue,
7 | front,
8 | hasElements,
9 | size,
10 | clear,
11 | print
12 | } = new PriorityQueue();
13 |
14 | describe('@PriorityQueue', () => {
15 | describe('#enqueue', () => {
16 | it('should be a function', () => {
17 | assert.typeOf(enqueue, 'function', 'enqueue should be a function');
18 | });
19 |
20 | it('should add new element(s) with priority', () => {
21 | // Adding new people
22 | enqueue('Carlos', 3); // [2]
23 | enqueue('Cristina', 1); // [0]
24 | enqueue('Jona', 5); // [4]
25 | enqueue('Javier', 2); // [1]
26 | enqueue('Sam', 4); // [3]
27 |
28 | /*
29 | [
30 | QueueElement { element: 'Cristina', priority: 1 }, [0]
31 | QueueElement { element: 'Javier', priority: 2 }, [1]
32 | QueueElement { element: 'Carlos', priority: 3 }, [2]
33 | QueueElement { element: 'Sam', priority: 4 }, [3]
34 | QueueElement { element: 'Jona', priority: 5 } [4]
35 | ]
36 | */
37 |
38 | // The queue should have 5 elements (length)
39 | const actualResult = size();
40 | const expectedResult = 5;
41 |
42 | assert.isTrue(expectedResult === actualResult);
43 | });
44 | });
45 |
46 | describe('#dequeue', () => {
47 | it('should be a function', () => {
48 | assert.typeOf(dequeue, 'function', 'dequeue should be a function');
49 | });
50 |
51 | it('should remove and return the first element', () => {
52 | // Removing the first element
53 | const actualResult = dequeue();
54 | const expectedResult = {
55 | element: 'Cristina',
56 | priority: 1
57 | };
58 |
59 | assert.isTrue(size() === 4); // The size now should be 4
60 | assert.deepEqual(expectedResult, actualResult, 'expectedResult should match actualResult');
61 | });
62 | });
63 |
64 | describe('#front', () => {
65 | it('should be a function', () => {
66 | assert.typeOf(front, 'function', 'front should be a function');
67 | });
68 |
69 | it('should return the first element', () => {
70 | // Getting the first element
71 | const actualResult = front();
72 | const expectedResult = {
73 | element: 'Javier',
74 | priority: 2
75 | };
76 |
77 | assert.deepEqual(expectedResult, actualResult, 'expectedResult should match actualResult');
78 | });
79 | });
80 |
81 | describe('#hasElements', () => {
82 | it('should be a function', () => {
83 | assert.typeOf(hasElements, 'function', 'hasElements should be a function');
84 | });
85 |
86 | it('should return true if the queue has elements', () => {
87 | // The queue has elements?
88 | const actualResult = hasElements();
89 | const expectedResult = true;
90 |
91 | assert.isTrue(expectedResult === actualResult); // The queue has elements!
92 | });
93 | });
94 |
95 | describe('#size', () => {
96 | it('should be a function', () => {
97 | assert.typeOf(size, 'function', 'size should be a function');
98 | });
99 |
100 | it('should return the current size of the queue', () => {
101 | // Getting the size of the actual queue
102 | const actualResult = size();
103 | const expectedResult = 4;
104 |
105 | assert.isTrue(expectedResult === actualResult); // The queue has 4 elements!
106 | });
107 | });
108 |
109 | describe('#clear', () => {
110 | it('should be a function', () => {
111 | assert.typeOf(clear, 'function', 'clear should be a function');
112 | });
113 |
114 | it('should clear the queue', () => {
115 | // Clear queue
116 | clear();
117 |
118 | const actualResult = size();
119 | const expectedResult = 0;
120 |
121 | assert.isTrue(expectedResult === actualResult); // The queue has 0 elements!
122 | });
123 | });
124 |
125 | describe('#print', () => {
126 | it('should be a function', () => {
127 | assert.typeOf(print, 'function', 'print should be a function');
128 | });
129 |
130 | it('should print the current queue', () => {
131 | // Adding new elements
132 | enqueue(10, 2);
133 | enqueue(20);
134 | enqueue(30);
135 |
136 | const actualResult = print();
137 | const expectedResult = '20-1|30-1|10-2';
138 |
139 | assert.isTrue(expectedResult === actualResult); // The new queue is [10, 20, 30]
140 | });
141 | });
142 | });
143 |
--------------------------------------------------------------------------------
/test/data-structures/queues/queueTest.js:
--------------------------------------------------------------------------------
1 | import '../../globalTest';
2 | import Queue from '../../../src/data-structures/queues/Queue';
3 |
4 | const {
5 | enqueue,
6 | dequeue,
7 | front,
8 | hasElements,
9 | size,
10 | clear,
11 | print
12 | } = new Queue();
13 |
14 | describe('@Queue', () => {
15 | describe('#enqueue', () => {
16 | it('should be a function', () => {
17 | assert.typeOf(enqueue, 'function', 'enqueue should be a function');
18 | });
19 |
20 | it('should add new element(s)', () => {
21 | // Adding new people
22 | enqueue('Carlos'); // [0]
23 | enqueue('Cristina'); // [1]
24 | enqueue('Javier'); // [2]
25 | enqueue('Jona'); // [3]
26 | enqueue('Sam'); // [4]
27 |
28 | // The queue should have 5 elements (length)
29 | const actualResult = size();
30 | const expectedResult = 5;
31 |
32 | assert.isTrue(expectedResult === actualResult);
33 | });
34 | });
35 |
36 | describe('#dequeue', () => {
37 | it('should be a function', () => {
38 | assert.typeOf(dequeue, 'function', 'dequeue should be a function');
39 | });
40 |
41 | it('should remove and return the first element', () => {
42 | // Removing the first element
43 | const actualResult = dequeue();
44 | const expectedResult = 'Carlos';
45 |
46 | assert.isTrue(size() === 4); // The size now should be 4
47 | assert.isTrue(expectedResult === actualResult); // The first element removed is 'Carlos'
48 | });
49 | });
50 |
51 | describe('#front', () => {
52 | it('should be a function', () => {
53 | assert.typeOf(front, 'function', 'front should be a function');
54 | });
55 |
56 | it('should return the first element', () => {
57 | // Getting the first element
58 | const actualResult = front();
59 | const expectedResult = 'Cristina';
60 |
61 | assert.isTrue(expectedResult === actualResult); // The first element is 'Cristina'
62 | });
63 | });
64 |
65 | describe('#hasElements', () => {
66 | it('should be a function', () => {
67 | assert.typeOf(hasElements, 'function', 'hasElements should be a function');
68 | });
69 |
70 | it('should return true if the queue has elements', () => {
71 | // The queue has elements?
72 | const actualResult = hasElements();
73 | const expectedResult = true;
74 |
75 | assert.isTrue(expectedResult === actualResult); // The queue has elements!
76 | });
77 | });
78 |
79 | describe('#size', () => {
80 | it('should be a function', () => {
81 | assert.typeOf(size, 'function', 'size should be a function');
82 | });
83 |
84 | it('should return the current size of the queue', () => {
85 | // Getting the size of the actual queue
86 | const actualResult = size();
87 | const expectedResult = 4;
88 |
89 | assert.isTrue(expectedResult === actualResult); // The queue has 4 elements!
90 | });
91 | });
92 |
93 | describe('#clear', () => {
94 | it('should be a function', () => {
95 | assert.typeOf(clear, 'function', 'clear should be a function');
96 | });
97 |
98 | it('should clear the queue', () => {
99 | // Clear queue
100 | clear();
101 |
102 | const actualResult = size();
103 | const expectedResult = 0;
104 |
105 | assert.isTrue(expectedResult === actualResult); // The queue has 0 elements!
106 | });
107 | });
108 |
109 | describe('#print', () => {
110 | it('should be a function', () => {
111 | assert.typeOf(print, 'function', 'print should be a function');
112 | });
113 |
114 | it('should print the current queue', () => {
115 | // Adding new elements
116 | enqueue(10);
117 | enqueue(20);
118 | enqueue(30);
119 |
120 | const actualResult = print();
121 | const expectedResult = '10,20,30';
122 |
123 | assert.isTrue(expectedResult === actualResult); // The new queue is [10, 20, 30]
124 | });
125 | });
126 | });
127 |
--------------------------------------------------------------------------------
/test/data-structures/sets/setTest.js:
--------------------------------------------------------------------------------
1 | import '../../globalTest';
2 | import Set from '../../../src/data-structures/sets/Set';
3 |
4 | const set = new Set();
5 |
6 | describe('@Set', () => {
7 | describe('#add', () => {
8 | it('should be a function', () => {
9 | assert.typeOf(set.add, 'function', 'add should be a function');
10 | });
11 |
12 | it('should add new element(s)', () => {
13 | set.add(1);
14 | set.add(2);
15 | set.add(3);
16 | set.add(4);
17 | set.add(5);
18 |
19 | console.log(cyan, 'Current Set ========> ', green, set.getItems());
20 |
21 | // The set should have 5 elements (length)
22 | const actualResult = set.size();
23 | const expectedResult = 5;
24 |
25 | assert.isTrue(expectedResult === actualResult);
26 | });
27 | });
28 |
29 | describe('#delete', () => {
30 | it('should be a function', () => {
31 | assert.typeOf(set.delete, 'function', 'delete should be a function');
32 | });
33 |
34 | it('should delete an element', () => {
35 | const actualResult = set.delete(4);
36 | const expectedResult = true;
37 |
38 | console.log(cyan, 'Current Set ========> ', green, set.getItems());
39 |
40 | assert.isTrue(expectedResult === actualResult);
41 | });
42 | });
43 |
44 | describe('#has', () => {
45 | it('should be a function', () => {
46 | assert.typeOf(set.has, 'function', 'has should be a function');
47 | });
48 |
49 | it('should validate if a set has an element', () => {
50 | // Getting the first element
51 | const actualResult = set.has(2);
52 | const expectedResult = true;
53 |
54 | assert.isTrue(expectedResult === actualResult);
55 | });
56 | });
57 |
58 | describe('#size', () => {
59 | it('should be a function', () => {
60 | assert.typeOf(set.size, 'function', 'size should be a function');
61 | });
62 |
63 | it('should return the current size of the queue', () => {
64 | // Getting the size of the actual list
65 | const actualResult = set.size();
66 | const expectedResult = 4;
67 |
68 | assert.isTrue(expectedResult === actualResult);
69 | });
70 | });
71 |
72 | describe('#values', () => {
73 | it('should be a function', () => {
74 | assert.typeOf(set.values, 'function', 'values should be a function');
75 | });
76 |
77 | it('should return the current values in array', () => {
78 | const actualResult = set.values();
79 | const expectedResult = [1, 2, 3, 5];
80 |
81 | assert.deepEqual(expectedResult, actualResult, 'expectedResult should match actualResult');
82 | });
83 | });
84 |
85 | describe('#clear', () => {
86 | it('should be a function', () => {
87 | assert.typeOf(set.clear, 'function', 'clear should be a function');
88 | });
89 |
90 | it('should clear the set', () => {
91 | set.clear();
92 |
93 | const actualResult = set.size();
94 | const expectedResult = 0;
95 |
96 | assert.isTrue(expectedResult === actualResult);
97 | });
98 | });
99 |
100 | describe('#union', () => {
101 | it('should be a function', () => {
102 | assert.typeOf(set.union, 'function', 'union should be a function');
103 | });
104 |
105 | it('should return the union of two sets', () => {
106 | const setA = new Set();
107 |
108 | setA.add(1);
109 | setA.add(2);
110 | setA.add(3);
111 |
112 | const setB = new Set();
113 |
114 | setB.add(4);
115 | setB.add(5);
116 | setB.add(6);
117 |
118 | const unionAB = setA.union(setB);
119 |
120 | console.log(cyan, 'Current Set ========> ', green, unionAB.getItems());
121 |
122 | // The union set should have [1, 2, 3, 4, 5, 6]
123 | const actualResult = unionAB.values();
124 | const expectedResult = [1, 2, 3, 4, 5, 6];
125 |
126 | assert.deepEqual(expectedResult, actualResult, 'expectedResult should match actualResult');
127 | });
128 | });
129 |
130 | describe('#intersection', () => {
131 | it('should be a function', () => {
132 | assert.typeOf(set.union, 'function', 'intersection should be a function');
133 | });
134 |
135 | it('should return the intersection of two sets', () => {
136 | const setA = new Set();
137 |
138 | setA.add(1);
139 | setA.add(2);
140 | setA.add(3);
141 |
142 | const setB = new Set();
143 |
144 | setB.add(2);
145 | setB.add(3);
146 | setB.add(4);
147 |
148 | const intersectionAB = setA.intersection(setB);
149 |
150 | console.log(cyan, 'Current Set ========> ', green, intersectionAB.getItems());
151 |
152 | // The intersection set should have [2, 3]
153 | const actualResult = intersectionAB.values();
154 | const expectedResult = [2, 3];
155 |
156 | assert.deepEqual(expectedResult, actualResult, 'expectedResult should match actualResult');
157 | });
158 | });
159 |
160 | describe('#difference', () => {
161 | it('should be a function', () => {
162 | assert.typeOf(set.union, 'function', 'difference should be a function');
163 | });
164 |
165 | it('should return the difference of two sets', () => {
166 | const setA = new Set();
167 |
168 | setA.add(1);
169 | setA.add(2);
170 | setA.add(3);
171 |
172 | const setB = new Set();
173 |
174 | setB.add(2);
175 | setB.add(3);
176 | setB.add(4);
177 |
178 | const differenceAB = setA.difference(setB);
179 |
180 | console.log(cyan, 'Current Set ========> ', green, differenceAB.getItems());
181 |
182 | // The difference set should have [1]
183 | const actualResult = differenceAB.values();
184 | const expectedResult = [1];
185 |
186 | assert.deepEqual(expectedResult, actualResult, 'expectedResult should match actualResult');
187 | });
188 | });
189 |
190 | describe('#subset', () => {
191 | it('should be a function', () => {
192 | assert.typeOf(set.union, 'function', 'subset should be a function');
193 | });
194 |
195 | it('should return the subset of two sets', () => {
196 | const setA = new Set();
197 |
198 | setA.add(1);
199 | setA.add(2);
200 |
201 | const setB = new Set();
202 |
203 | setB.add(1);
204 | setB.add(2);
205 | setB.add(3);
206 |
207 | const setC = new Set();
208 |
209 | setB.add(2);
210 | setB.add(3);
211 | setB.add(4);
212 |
213 | assert.isTrue(setA.subset(setB)); // Set A is subset of Set B (contains both values)
214 | assert.isFalse(setA.subset(setC)); // Set A is not subset of Set C (just contains 2)
215 | });
216 | });
217 | });
218 |
--------------------------------------------------------------------------------
/test/data-structures/stacks/dec2BinTest.js:
--------------------------------------------------------------------------------
1 | import '../../globalTest';
2 | import dec2Bin from '../../../src/data-structures/stacks/dec2Bin';
3 |
4 | describe('@Dec2Bin', () => {
5 | describe('#dec2Bin', () => {
6 | it('should be a function', () => {
7 | assert.typeOf(dec2Bin, 'function', 'dec2Bin should be a function');
8 | });
9 |
10 | it('should convert decimal number to binary', () => {
11 | assert.isTrue(dec2Bin(0) === '0');
12 | assert.isTrue(dec2Bin(1) === '1');
13 | assert.isTrue(dec2Bin(2) === '10');
14 | assert.isTrue(dec2Bin(3) === '11');
15 | assert.isTrue(dec2Bin(4) === '100');
16 | assert.isTrue(dec2Bin(5) === '101');
17 | assert.isTrue(dec2Bin(6) === '110');
18 | assert.isTrue(dec2Bin(7) === '111');
19 | assert.isTrue(dec2Bin(8) === '1000');
20 | assert.isTrue(dec2Bin(9) === '1001');
21 | assert.isTrue(dec2Bin(10) === '1010');
22 | assert.isTrue(dec2Bin(11) === '1011');
23 | assert.isTrue(dec2Bin(12) === '1100');
24 | assert.isTrue(dec2Bin(13) === '1101');
25 | assert.isTrue(dec2Bin(14) === '1110');
26 | assert.isTrue(dec2Bin(15) === '1111');
27 | });
28 | });
29 | });
30 |
--------------------------------------------------------------------------------
/test/data-structures/stacks/stackTest.js:
--------------------------------------------------------------------------------
1 | import '../../globalTest';
2 | import Stack from '../../../src/data-structures/stacks/Stack';
3 |
4 | const {
5 | push,
6 | pop,
7 | last,
8 | hasElements,
9 | size,
10 | clear,
11 | print
12 | } = new Stack();
13 |
14 | describe('@Stack', () => {
15 | describe('#push', () => {
16 | it('should be a function', () => {
17 | assert.typeOf(push, 'function', 'push should be a function');
18 | });
19 |
20 | it('should add new element(s)', () => {
21 | // Adding new books to the stack
22 | push('El Señor de los Anillos'); // [0]
23 | push('El Código da Vinci'); // [1]
24 | push('Kain y Abel'); // [2]
25 | push('El Alquimista'); // [3]
26 | push('El Hobbit'); // [4]
27 |
28 | // The stack should have 5 elements (length)
29 | const actualResult = size();
30 | const expectedResult = 5;
31 |
32 | assert.isTrue(expectedResult === actualResult);
33 | });
34 | });
35 |
36 | describe('#pop', () => {
37 | it('should be a function', () => {
38 | assert.typeOf(pop, 'function', 'pop should be a function');
39 | });
40 |
41 | it('should remove and return the last element', () => {
42 | // Removing the last element
43 | const actualResult = pop();
44 | const expectedResult = 'El Hobbit';
45 |
46 | assert.isTrue(size() === 4); // The size now should be 4
47 | assert.isTrue(expectedResult === actualResult); // The last element removed is 'El Hobbit'
48 | });
49 | });
50 |
51 | describe('#last', () => {
52 | it('should be a function', () => {
53 | assert.typeOf(last, 'function', 'last should be a function');
54 | });
55 |
56 | it('should return the last element', () => {
57 | // Getting the last element
58 | const actualResult = last();
59 | const expectedResult = 'El Alquimista';
60 |
61 | assert.isTrue(expectedResult === actualResult); // The last element is 'El Alquimista'
62 | });
63 | });
64 |
65 | describe('#hasElements', () => {
66 | it('should be a function', () => {
67 | assert.typeOf(hasElements, 'function', 'hasElements should be a function');
68 | });
69 |
70 | it('should return true if the stack has elements', () => {
71 | // The stack has elements?
72 | const actualResult = hasElements();
73 | const expectedResult = true;
74 |
75 | assert.isTrue(expectedResult === actualResult); // The sack has elements!
76 | });
77 | });
78 |
79 | describe('#size', () => {
80 | it('should be a function', () => {
81 | assert.typeOf(size, 'function', 'size should be a function');
82 | });
83 |
84 | it('should return the current size of the stack', () => {
85 | // Getting the size of the actual stack
86 | const actualResult = size();
87 | const expectedResult = 4;
88 |
89 | assert.isTrue(expectedResult === actualResult); // The sack has 4 elements!
90 | });
91 | });
92 |
93 | describe('#clear', () => {
94 | it('should be a function', () => {
95 | assert.typeOf(clear, 'function', 'clear should be a function');
96 | });
97 |
98 | it('should clear the stack', () => {
99 | // Clear stack
100 | clear();
101 |
102 | const actualResult = size();
103 | const expectedResult = 0;
104 |
105 | assert.isTrue(expectedResult === actualResult); // The sack has 0 elements!
106 | });
107 | });
108 |
109 | describe('#print', () => {
110 | it('should be a function', () => {
111 | assert.typeOf(print, 'function', 'print should be a function');
112 | });
113 |
114 | it('should print the current stack', () => {
115 | // Adding new elements
116 | push(10);
117 | push(20);
118 | push(30);
119 |
120 | const actualResult = print();
121 | const expectedResult = '10,20,30';
122 |
123 | assert.isTrue(expectedResult === actualResult); // The new stack is [10, 20, 30]
124 | });
125 | });
126 | });
127 |
--------------------------------------------------------------------------------
/test/globalTest.js:
--------------------------------------------------------------------------------
1 | // Adding babel support
2 | require('babel-register');
3 |
4 | // Global methods
5 | global.assert = require('chai').assert;
6 |
7 | // Console.log colors
8 | global.cyan = '\x1b[36m%s\x1b[0m';
9 | global.yellow = '\x1b[33m';
10 | global.blue = '\x1b[34m';
11 | global.green = '\x1b[32m';
12 | global.red = '\x1b[31m';
13 | global.magenta = '\x1b[35m';
14 |
--------------------------------------------------------------------------------