Merge pull request #4 from kevinwin/master

javascript code for grokking_algorithms [ch 2 - 9]
This commit is contained in:
Aditya Bhargava
2016-06-22 07:22:50 -07:00
committed by GitHub
22 changed files with 389 additions and 0 deletions

View File

@@ -0,0 +1,27 @@
'use strict';
// Finds the smallest value in an array
function findSmallest(arr) {
let smallest = arr[0]; // Stores the smallest value
let smallest_index = 0; // Stores the index of the smallest value
for (let i = 1; i < arr.length; i++) {
if (arr[i] < smallest) {
smallest = arr[i];
smallest_index = i;
}
}
return smallest_index;
}
// Sort array
function selectionSort(arr) {
const newArr = [];
for (let i = 0, length = arr.length; i < length; i++) {
// Finds the smallest element in the array and adds it to the new array
let smallest = findSmallest(arr);
newArr.push(arr.splice(smallest, 1)[0]);
}
return newArr;
}
console.log(selectionSort([5, 3, 6, 2, 10])); // [2, 3, 5, 6, 10]

View File

@@ -0,0 +1,11 @@
function countdown(i) {
console.log(i);
// base case
if (i <= 0) {
return;
} else {
countdown(i-1);
}
}
countdown(5);

16
03_recursion/02_greet.js Normal file
View File

@@ -0,0 +1,16 @@
function greet2(name) {
console.log('how are you, ' + name + '?');
}
function bye() {
console.log('ok bye!');
}
function greet(name) {
console.log('hello, ' + name + '!');
greet2(name);
console.log('getting ready to say bye...');
bye();
}
greet('adit');

View File

@@ -0,0 +1,9 @@
function fact(x) {
if (x === 1) {
return 1;
} else {
return x * fact(x-1);
}
}
console.log(fact(5));

View File

@@ -0,0 +1,11 @@
'use strict';
function sum(arr) {
let total = 0;
for (let x = 0; x < arr.length; x++) {
total += arr[x];
}
return total;
}
console.log(sum([1, 2, 3, 4])) // 10

View File

@@ -0,0 +1,10 @@
'use strict';
function sum(list) {
if (list.length === 0) {
return 0;
}
return list[0] + sum(list.slice(1));
}
console.log(sum([1, 2, 3, 4])) // 10

View File

@@ -0,0 +1,10 @@
'use strict';
function count(list) {
if (list.length === 0) {
return 0;
}
return 1 + count(list.slice(1));
}
console.log(count([0, 1, 2, 3, 4, 5])); // 6

View File

@@ -0,0 +1,11 @@
'use strict';
function max(list) {
if (list.length === 2) {
return list[0] > list[1] ? list[0] : list[1];
}
let sub_max = max(list.slice(1));
return list[0] > sub_max ? list[0] : sub_max;
}
console.log(max([1, 5, 10, 25, 16, 1])); // 25

View File

@@ -0,0 +1,18 @@
'use strict';
function quicksort(array) {
if (array.length < 2) {
// base case, arrays with 0 or 1 element are already "sorted"
return array;
} else {
// recursive case
let pivot = array[0];
// sub-array of all the elements less than the pivot
let less = array.slice(1).filter(function(el) { return el <= pivot; });
// sub-array of all the elements greater than the pivot
let greater = array.slice(1).filter(function(el) { return el > pivot; });
return quicksort(less).concat([pivot], quicksort(greater));
}
}
console.log(quicksort([10, 5, 2, 3])); // [2, 3, 5, 10]

View File

@@ -0,0 +1,11 @@
'use strict';
function sum(arr) {
let total = 0;
for (let x = 0; x < arr.length; x++) {
total += arr[x];
}
return total;
}
console.log(sum([1, 2, 3, 4])) // 10

View File

@@ -0,0 +1,10 @@
'use strict';
function sum(list) {
if (list.length === 0) {
return 0;
}
return list[0] + sum(list.slice(1));
}
console.log(sum([1, 2, 3, 4])) // 10

View File

@@ -0,0 +1,10 @@
'use strict';
function count(list) {
if (list.length === 0) {
return 0;
}
return 1 + count(list.slice(1));
}
console.log(count([0, 1, 2, 3, 4, 5])); // 6

View File

@@ -0,0 +1,11 @@
'use strict';
function max(list) {
if (list.length === 2) {
return list[0] > list[1] ? list[0] : list[1];
}
let sub_max = max(list.slice(1));
return list[0] > sub_max ? list[0] : sub_max;
}
console.log(max([1, 5, 10, 25, 16, 1])); // 25

View File

@@ -0,0 +1,18 @@
'use strict';
function quicksort(array) {
if (array.length < 2) {
// base case, arrays with 0 or 1 element are already "sorted"
return array;
} else {
// recursive case
let pivot = array[0];
// sub-array of all the elements less than the pivot
let less = array.slice(1).filter(function(el) { return el <= pivot; });
// sub-array of all the elements greater than the pivot
let greater = array.slice(1).filter(function(el) { return el > pivot; });
return quicksort(less).concat([pivot], quicksort(greater));
}
}
console.log(quicksort([10, 5, 2, 3])); // [2, 3, 5, 10]

View File

@@ -0,0 +1,10 @@
'use strict';
const book = {};
// an apple costs 67 cents
book['apple'] = 0.67;
// milk costs $1.49
book['milk'] = 1.49;
book['avocado'] = 1.49;
console.log(book); // { apple: 0.67, milk: 1.49, avocado: 1.49 }

View File

@@ -0,0 +1,16 @@
'use strict';
const voted = {};
function check_voter(name) {
if (voted[name]) {
console.log('kick them out!');
} else {
voted[name] = true;
console.log('let them vote!');
}
}
check_voter("tom"); // let them vote!
check_voter("mike"); // let them vote!
check_voter("mike"); // kick them out!

View File

@@ -0,0 +1,10 @@
'use strict';
const book = {};
// an apple costs 67 cents
book['apple'] = 0.67;
// milk costs $1.49
book['milk'] = 1.49;
book['avocado'] = 1.49;
console.log(book); // { apple: 0.67, milk: 1.49, avocado: 1.49 }

View File

@@ -0,0 +1,16 @@
'use strict';
const voted = {};
function check_voter(name) {
if (voted[name]) {
console.log('kick them out!');
} else {
voted[name] = true;
console.log('let them vote!');
}
}
check_voter("tom"); // let them vote!
check_voter("mike"); // let them vote!
check_voter("mike"); // kick them out!

View File

@@ -0,0 +1,41 @@
'use strict';
function person_is_seller(name) {
return name[name.length-1] === 'm';
}
const graph = {};
graph["you"] = ["alice", "bob", "claire"];
graph["bob"] = ["anuj", "peggy"];
graph["alice"] = ["peggy"];
graph["claire"] = ["thom", "jonny"];
graph["anuj"] = [];
graph["peggy"] = [];
graph["thom"] = [];
graph["jonny"] = [];
function search(name) {
let search_queue = [];
search_queue = search_queue.concat(graph[name]);
// This array is how you keep track of which people you've searched before.
const searched = [];
while (search_queue.length) {
let person = search_queue.shift();
// Only search this person if you haven't already searched them
if (searched.indexOf(person) === -1) {
if (person_is_seller(person)) {
console.log(person + ' is a mango seller!');
return true;
} else {
search_queue = search_queue.concat(graph[person]);
// Marks this person as searched
searched.push(person);
}
}
}
return false;
}
search('you'); // thom is a mango seller!

View File

@@ -0,0 +1,75 @@
'use strict';
// the graph
const graph = {}
graph["start"] = {}
graph["start"]["a"] = 6
graph["start"]["b"] = 2
graph["a"] = {}
graph["a"]["fin"] = 1
graph["b"] = {}
graph["b"]["a"] = 3
graph["b"]["fin"] = 5
graph["fin"] = {}
// The costs table
const costs = {};
costs['a'] = 6
costs['b'] = 2;
costs['fin'] = Infinity;
// the parents table
const parents = {};
parents['a'] = 'start';
parents['b'] = 'start';
parents['fin'] = null;
let processed = [];
function find_lowest_cost_node(costs) {
let lowest_cost = Infinity;
let lowest_cost_node = null;
// Go through each node
for (let node in costs) {
let cost = costs[node];
// If it's the lowest cost so far and hasn't been processed yet...
if (cost < lowest_cost && (processed.indexOf(node) === -1)) {
// ... set it as the new lowest-cost node.
lowest_cost = cost;
lowest_cost_node = node;
}
}
return lowest_cost_node;
}
let node = find_lowest_cost_node(costs);
while (node !== null) {
let cost = costs[node];
// Go through all the neighbors of this node
let neighbors = graph[node];
Object.keys(neighbors).forEach(function(n) {
let new_cost = cost + neighbors[n];
// If it's cheaper to get to this neighbor by going through this node
if (costs[n] > new_cost) {
// ... update the cost for this node
costs[n] = new_cost;
// This node becomes the new parent for this neighbor.
parents[n] = node;
}
});
// Mark the node as processed
processed = processed.concat(node);
// Find the next node to process, and loop
node = find_lowest_cost_node(costs);
}
console.log("Cost from the start to each node:");
console.log(costs); // { a: 5, b: 2, fin: 6 }

View File

@@ -0,0 +1,31 @@
'use strict';
// You pass an array in, and it gets converted to a set.
let states_needed = new Set(["mt", "wa", "or", "id", "nv", "ut", "ca", "az"]);
const stations = {};
stations["kone"] = new Set(["id", "nv", "ut"]);
stations["ktwo"] = new Set(["wa", "id", "mt"]);
stations["kthree"] = new Set(["or", "nv", "ca"]);
stations["kfour"] = new Set(["nv", "ut"]);
stations["kfive"] = new Set(["ca", "az"]);
const final_stations = new Set();
while (states_needed.size) {
let best_station = null;
let states_covered = new Set();
for (let station in stations) {
let states = stations[station];
let covered = new Set([...states_needed].filter((x) => states.has(x)));
if (covered.size > states_covered.size) {
best_station = station;
states_covered = covered;
}
}
states_needed = new Set([...states_needed].filter((x) => !states_covered.has(x)));
final_stations.add(best_station);
}
console.log(final_stations); // Set { 'kone', 'ktwo', 'kthree', 'kfive' }

View File

@@ -0,0 +1,7 @@
if (word_a[i] === word_b[j]) {
// The letters match
cell[i][j] = cell[i-1][j-1] + 1;
} else {
// The letters don't match
cell[i][j] = Math.max(cell[i-1][j], cell[i][j-1]);
}