Last active
June 6, 2017 18:00
-
-
Save soundyogi/fdfb3bee2d0746ed64f029defd259ca7 to your computer and use it in GitHub Desktop.
Stack,Queue
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Stacks are LIFO , Last In First Out | |
// | |
class Stack { | |
constructor(){ | |
this.size = 0 | |
this.store = {} // array or object does not matter | |
} | |
push(item){ | |
this.store[this.size++] = item | |
return true | |
} | |
pop(){ | |
if(this.size === 0){ return 'stack is empty'} | |
let value = this.store[this.size-1] | |
delete this.store[--this.size] | |
return value | |
} | |
} | |
// Queues are FIFO = First In First Out | |
// | |
class Queue { | |
constructor(initVal){ | |
this.size = 0 | |
this.store = [] | |
if(initVal){ | |
this.enqueue(initVal) | |
} | |
} | |
enqueue(value){ | |
if(!value){ return 'you cannot queue nothing' } | |
this.store[this.size] = value | |
this.size++ | |
return true | |
} | |
dequeue(){ | |
if(this.isEmpty()){ return } | |
const returnValue = this.store[0] | |
// now shift everything to the left | |
this.store.map( (val,id) => { | |
this.store[id] = this.store[id+1] | |
}) | |
delete this.store[this.size] | |
this.size-- | |
return returnValue | |
} | |
print(){ | |
let out = '' | |
this.store.map( val => out+=JSON.stringify(val)+' ' ) | |
return out.trimRight() | |
} | |
isEmpty(){ | |
return this.length() === 0 | |
} | |
length(){ | |
return this.size | |
} | |
} | |
// | |
// TESTING | |
// | |
// super simple harness | |
const passColor = 'color:green' | |
const failColor = 'color:red' | |
const log = (...msg) => console.log(...msg) | |
// super micro nano test harness for the console | |
// | |
const test = function t(expr, msg){ | |
expr ? log('%c!pass:'+msg, passColor) : log('%c?fail:'+msg, failColor) | |
} | |
test(true, 'selftest pass') | |
test(false, 'selftest fail') | |
// mocks for BDD style tests copied from elsewhere | |
// | |
function toBeTruthy(){ test(this.value, this.value+' true') } | |
function toEqual(expect){ test(this.value === expect, this.value+' equal to '+expect) } | |
function beforeEach(f){ window.beforeEach = f } | |
function it(msg, f){ | |
log(msg) | |
if(window.beforeEach) window.beforeEach() | |
f() | |
} | |
function expect(val){ | |
var k = {value: val} | |
var host = { | |
toBeTruthy: toBeTruthy.bind(k), | |
toEqual: toEqual.bind(k) | |
} | |
return host | |
} | |
// UNIT TESTS | |
// | |
// these where created while TDD | |
const Q = new Queue() | |
test(Q.size === 0, 'init, size is 0') | |
test(Q.enqueue() === 'you cannot queue nothing', 'you cannot enqueue nothing') | |
test(Q.enqueue(4) === true, "enqueueing works") | |
Q.enqueue("slow") | |
Q.enqueue('7') | |
test(Q.store[0] === 4, 'it really works') | |
test(Q.dequeue() === 4, 'dequeue works') | |
test(Q.size === 2, 'size correct after dequeue') | |
test(Q.dequeue() === 'slow', 'ok, I am convinced it works') | |
const S = new Stack() | |
test(S.pop() === 'stack is empty', 'empty stack gives msg') | |
test(S.push(4), 'push 4') | |
test(S.push(7), 'push 7') | |
test(S.size === 2, 'size is 2') | |
test(S.store[1] === 7, 'second in store is 7') | |
test(S.pop() === 7, 'pop it is 7') | |
test(S.size === 1, 'stack size is 1') | |
// I have copied some test from another implementation | |
// | |
beforeEach(()=>{ | |
window.queue = new Queue() | |
}) | |
it("should be instantiable", function() { | |
expect(queue).toBeTruthy(); | |
}); | |
it("should be be empty on instantiation", function() { | |
expect(queue.isEmpty()).toEqual(true); | |
}); | |
it("should be able to take a value on instantiation", function() { | |
const qq = new Queue(456); | |
expect(qq.isEmpty()).toEqual(false); | |
expect(qq.dequeue()).toEqual(456); | |
}); | |
it("should be able to hold a value", function() { | |
queue.enqueue(5); | |
expect(queue.print()).toEqual('5'); | |
}); | |
it("should be able to pop the oldest entered value", function() { | |
queue.enqueue(5); | |
queue.enqueue(3); | |
queue.enqueue(2); | |
queue.enqueue(1); | |
expect(queue.dequeue()).toEqual(5); | |
}); | |
it("should dequeue items in first in first out order", function() { | |
queue.enqueue(1); | |
queue.enqueue(2); | |
queue.enqueue(3); | |
queue.enqueue(4); | |
queue.enqueue(5); | |
expect(queue.dequeue()).toEqual(1); | |
expect(queue.dequeue()).toEqual(2); | |
expect(queue.dequeue()).toEqual(3); | |
expect(queue.dequeue()).toEqual(4); | |
expect(queue.dequeue()).toEqual(5); | |
}); | |
it("should be able to pop the oldest entered value, even when the value was given during instantiation", function() { | |
window.queue = new Queue(5); | |
queue.enqueue(3); | |
queue.enqueue(2); | |
queue.enqueue(1); | |
expect(queue.dequeue()).toEqual(5); | |
window.queue = new Queue(75); | |
expect(queue.dequeue()).toEqual(75); | |
}); | |
it("should be able to pop pop past its limit without breaking", function() { | |
queue.enqueue(5); | |
queue.enqueue(3); | |
queue.enqueue(2); | |
expect(queue.isEmpty()).toEqual(false); | |
queue.enqueue(1); | |
expect(queue.dequeue()).toEqual(5); | |
expect(queue.dequeue()).toEqual(3); | |
expect(queue.dequeue()).toEqual(2); | |
expect(queue.dequeue()).toEqual(1); | |
expect(queue.dequeue()).toEqual(undefined); | |
expect(queue.dequeue()).toEqual(undefined); | |
expect(queue.isEmpty()).toEqual(true); | |
}); | |
it("should be able to pop pop past its limit without breaking and start over again without a hitch", function() { | |
queue.enqueue(5); | |
queue.enqueue(3); | |
queue.enqueue(2); | |
expect(queue.isEmpty()).toEqual(false); | |
queue.enqueue(1); | |
expect(queue.dequeue()).toEqual(5); | |
expect(queue.dequeue()).toEqual(3); | |
expect(queue.dequeue()).toEqual(2); | |
expect(queue.dequeue()).toEqual(1); | |
expect(queue.dequeue()).toEqual(undefined); | |
expect(queue.dequeue()).toEqual(undefined); | |
expect(queue.isEmpty()).toEqual(true); | |
queue.enqueue(5); | |
queue.enqueue(3); | |
queue.enqueue(2); | |
queue.enqueue(1); | |
expect(queue.isEmpty()).toEqual(false); | |
expect(queue.dequeue()).toEqual(5); | |
expect(queue.dequeue()).toEqual(3); | |
expect(queue.dequeue()).toEqual(2); | |
expect(queue.dequeue()).toEqual(1); | |
expect(queue.dequeue()).toEqual(undefined); | |
expect(queue.dequeue()).toEqual(undefined); | |
expect(queue.isEmpty()).toEqual(true); | |
}); | |
it("should be able to print itself with no values", function() { | |
expect(queue.print()).toEqual(""); | |
}); | |
it("should be able to print itself with 1 value", function() { | |
queue.enqueue(5); | |
expect(queue.print()).toEqual("5"); | |
}); | |
it("should be able to print itself with multiple values", function() { | |
queue.enqueue(5); | |
queue.enqueue(3); | |
queue.enqueue(2); | |
queue.enqueue(1); | |
expect(queue.print()).toEqual("5 3 2 1"); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Today you will encounter: | |
- Data Structures | |
- How to Implement Queue & Stack & List in JS in a OOP and Functional way | |
- JavaScript ES6 | |
- Classes, Simple Inheritance and Custom Multi/Mixin Inheritance | |
*/ | |
// Stacks are LIFO , Last In First Out | |
class Stack { | |
constructor(){ | |
this.size = 0 | |
this.store = {} // array or object does not matter | |
} | |
push(item){ this.store[this.size++] = item } | |
pop(){ | |
if(this.size === 0){ return 'stack is empty'} | |
let value = this.store[this.size-1] | |
delete this.store[--this.size] | |
return value | |
} | |
next(){ | |
if(!this.iterable) this.iterable = getIterable.call(this) | |
return this.iterable.next() | |
function *getIterable(){ yield this.pop() } | |
} | |
} | |
// Queues are FIFO = First In First Out | |
class Queue { | |
constructor(initVal){ | |
this.size = 0 | |
this.store = [] | |
if(initVal){ | |
this.enqueue(initVal) | |
} | |
} | |
enqueue(value){ | |
if(!value){ return 'you cannot queue nothing' } | |
this.store[this.size] = value | |
this.size++ | |
return true | |
} | |
dequeue(){ | |
if(this.isEmpty()){ return } | |
const returnValue = this.store[0] | |
// now shift everything to the left | |
this.store.map( (val,id) => { | |
this.store[id] = this.store[id+1] | |
}) | |
delete this.store[this.size] | |
this.size-- | |
return returnValue | |
} | |
print(){ | |
let out = '' | |
this.store.map( val => out+=JSON.stringify(val)+' ' ) | |
return out.trimRight() | |
} | |
isEmpty() { return this.length() === 0 } | |
length(){ return this.size } | |
next(){ | |
if(!this.iterable) this.iterable = getIterable.call(this) | |
return this.iterable.next() | |
function *getIterable(){ yield this.dequeue() } | |
} | |
} | |
// | |
// TESTING | |
// | |
// super simple harness | |
const passColor = 'color:green' | |
const failColor = 'color:red' | |
const log = (...msg) => console.log(...msg) | |
// super micro nano test harness for the console | |
// | |
const test = function t(expr, msg){ | |
expr ? log('%c!pass:'+msg, passColor) : log('%c?fail:'+msg, failColor) | |
} | |
test(true, 'selftest pass') | |
test(false, 'selftest fail') | |
// mocks for BDD style tests copied from elsewhere | |
// | |
function toBeTruthy(){} //test(this.value, this.value+' true') } | |
function toEqual(expect){} //test(this.value === expect, this.value+' equal to '+expect) } | |
function beforeEach(f){ window.beforeEach = f } | |
function it(msg, f){ | |
//log(msg) | |
if(window.beforeEach) window.beforeEach() | |
f() | |
} | |
function expect(val){ | |
var k = {value: val} | |
var host = { | |
toBeTruthy: toBeTruthy.bind(k), | |
toEqual: toEqual.bind(k) | |
} | |
return host | |
} | |
// UNIT TESTS | |
// | |
// these where created while TDD | |
const Q = new Queue() | |
test(Q.size === 0, 'init, size is 0') | |
test(Q.enqueue() === 'you cannot queue nothing', 'you cannot enqueue nothing') | |
test(Q.enqueue(4) === true, "enqueueing works") | |
Q.enqueue("slow") | |
Q.enqueue('7') | |
test(Q.store[0] === 4, 'it really works') | |
test(Q.next().value === 4, 'dequeue works') | |
test(Q.size === 2, 'size correct after dequeue') | |
test(Q.next().value === 'slow', 'ok, I am convinced it works') | |
const S = new Stack() | |
test(S.next().value === 'stack is empty', 'empty stack gives msg') | |
S.push(4) | |
S.push(7) | |
test(S.size === 2, 'size is 2') | |
test(S.store[1] === 7, 'second in store is 7') | |
test(S.next().value === 7, 'pop it is 7') | |
test(S.size === 1, 'stack size is 1') | |
// I have copied some test from another implementation | |
// | |
beforeEach(()=>{ | |
window.queue = new Queue() | |
}) | |
it("should be instantiable", function() { | |
expect(queue).toBeTruthy(); | |
}); | |
it("should be be empty on instantiation", function() { | |
expect(queue.isEmpty()).toEqual(true); | |
}); | |
it("should be able to take a value on instantiation", function() { | |
const qq = new Queue(456); | |
expect(qq.isEmpty()).toEqual(false); | |
expect(qq.dequeue()).toEqual(456); | |
}); | |
it("should be able to hold a value", function() { | |
queue.enqueue(5); | |
expect(queue.print()).toEqual('5'); | |
}); | |
it("should be able to pop the oldest entered value", function() { | |
queue.enqueue(5); | |
queue.enqueue(3); | |
queue.enqueue(2); | |
queue.enqueue(1); | |
expect(queue.dequeue()).toEqual(5); | |
}); | |
it("should dequeue items in first in first out order", function() { | |
queue.enqueue(1); | |
queue.enqueue(2); | |
queue.enqueue(3); | |
queue.enqueue(4); | |
queue.enqueue(5); | |
expect(queue.dequeue()).toEqual(1); | |
expect(queue.dequeue()).toEqual(2); | |
expect(queue.dequeue()).toEqual(3); | |
expect(queue.dequeue()).toEqual(4); | |
expect(queue.dequeue()).toEqual(5); | |
}); | |
it("should be able to pop the oldest entered value, even when the value was given during instantiation", function() { | |
window.queue = new Queue(5); | |
queue.enqueue(3); | |
queue.enqueue(2); | |
queue.enqueue(1); | |
expect(queue.dequeue()).toEqual(5); | |
window.queue = new Queue(75); | |
expect(queue.dequeue()).toEqual(75); | |
}); | |
it("should be able to pop pop past its limit without breaking", function() { | |
queue.enqueue(5); | |
queue.enqueue(3); | |
queue.enqueue(2); | |
expect(queue.isEmpty()).toEqual(false); | |
queue.enqueue(1); | |
expect(queue.dequeue()).toEqual(5); | |
expect(queue.dequeue()).toEqual(3); | |
expect(queue.dequeue()).toEqual(2); | |
expect(queue.dequeue()).toEqual(1); | |
expect(queue.dequeue()).toEqual(undefined); | |
expect(queue.dequeue()).toEqual(undefined); | |
expect(queue.isEmpty()).toEqual(true); | |
}); | |
it("should be able to pop pop past its limit without breaking and start over again without a hitch", function() { | |
queue.enqueue(5); | |
queue.enqueue(3); | |
queue.enqueue(2); | |
expect(queue.isEmpty()).toEqual(false); | |
queue.enqueue(1); | |
expect(queue.dequeue()).toEqual(5); | |
expect(queue.dequeue()).toEqual(3); | |
expect(queue.dequeue()).toEqual(2); | |
expect(queue.dequeue()).toEqual(1); | |
expect(queue.dequeue()).toEqual(undefined); | |
expect(queue.dequeue()).toEqual(undefined); | |
expect(queue.isEmpty()).toEqual(true); | |
queue.enqueue(5); | |
queue.enqueue(3); | |
queue.enqueue(2); | |
queue.enqueue(1); | |
expect(queue.isEmpty()).toEqual(false); | |
expect(queue.dequeue()).toEqual(5); | |
expect(queue.dequeue()).toEqual(3); | |
expect(queue.dequeue()).toEqual(2); | |
expect(queue.dequeue()).toEqual(1); | |
expect(queue.dequeue()).toEqual(undefined); | |
expect(queue.dequeue()).toEqual(undefined); | |
expect(queue.isEmpty()).toEqual(true); | |
}); | |
it("should be able to print itself with no values", function() { | |
expect(queue.print()).toEqual(""); | |
}); | |
it("should be able to print itself with 1 value", function() { | |
queue.enqueue(5); | |
expect(queue.print()).toEqual("5"); | |
}); | |
it("should be able to print itself with multiple values", function() { | |
queue.enqueue(5); | |
queue.enqueue(3); | |
queue.enqueue(2); | |
queue.enqueue(1); | |
expect(queue.print()).toEqual("5 3 2 1"); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To run tests just paste everything into a JS console :D