├── HackerRank ├── Database │ └── SQL │ │ ├── select_all.sql │ │ ├── select_by_id.sql │ │ ├── japanese_cities_names.sql │ │ ├── japansese_cities_atributes.sql │ │ ├── revising_the_select_query1.sql │ │ ├── revising_the_select_query2.sql │ │ └── higher_than_75_marks.sql ├── Algorithm │ ├── Warmup │ │ ├── very_big_sum.rb │ │ ├── simple_array_sum.py │ │ ├── very_big_sum.py │ │ ├── staircase.py │ │ ├── time_conversion.py │ │ ├── plus_minus.py │ │ ├── diagonal_difference.py │ │ ├── introToTutorial.js │ │ ├── insertionSortPart2.js │ │ ├── compare_the_triplets.js │ │ └── insertionSortPart1.js │ ├── Strings │ │ ├── pangrams.js │ │ ├── anagram.js │ │ ├── the_love_letter_mystery.js │ │ ├── alternating_characters.js │ │ ├── funny_Strings.js │ │ ├── closest_numbers.js │ │ ├── ceasar_cipher.js │ │ ├── gemstones.js │ │ └── game_of_thrones_I.js │ ├── Implementation │ │ ├── extra_long_factorials.rb │ │ ├── cut_the_sticks.js │ │ ├── encryption.js │ │ ├── service_lane.js │ │ ├── utopian_tree.js │ │ ├── find_digits.js │ │ ├── library_fine.js │ │ ├── lisas_workbook.js │ │ ├── chocolate_feast.js │ │ ├── angry_professor.js │ │ ├── modified_kaprekar_numbers.js │ │ └── cavity_map.js │ ├── Bit Manipulation │ │ ├── flipping_bits.js │ │ ├── maximizing_xor.js │ │ └── lonely_integer.js │ ├── Greedy │ │ └── max_min.js │ ├── Search │ │ ├── ice_cream_parlor.js │ │ └── missing_numbers.js │ ├── Dynamic Programming │ │ └── the_maximum_subarray.js │ └── Graph Theory │ │ └── event_tree.js ├── Regex │ ├── alien_username.js │ ├── split_the_phone_numbers.js │ ├── valid_pan_format.js │ ├── find_hackerrank.js │ ├── find_a_substring.js │ ├── detecting_valid_latitude_and_longitude_pairs.js │ ├── ip_address_validation.js │ └── detect_html_tags.js └── DataStructures │ ├── arrays_ds.js │ └── sparse_arrays.js ├── README.md ├── leetcode ├── 151_reverse_words_in_a_string.js ├── power_of_two.js ├── 104_maximum_depth_of_binary_tree.js ├── 263_ugly_number.js ├── 238_product_of_array_except_self.js ├── 293_flip_game.js ├── remove_duplicates_from_sorted_array.js ├── 125_valid_palindrome.js ├── 339_nested_list_weight_sum.js ├── 206_reverse_linked_list.js ├── rotateArray.js ├── 232_implement_queue_using_stacks.js ├── 243_shortest_word_distance.js ├── 225_implement_stack_using_queues.js ├── 242_valid_anagram.js ├── 204_count_primes.js ├── 66_plus_one.js ├── 186_reverse_words_in_a_string_II.js ├── 245_shortest_word_distance_III.js ├── 349_intersection_of_two_arrays.js ├── group_shifted_strings.js ├── 350_insersection_of_two_arrays_II.js ├── 20_valid_parantheses.js ├── 383_ransom_note.js ├── 266_palindrome_permutation.js ├── 345_reverse_vowels_of_a_string.js ├── 9_palindrome_number.js ├── 234_palindrome_linked_list.js ├── 288_unique_word_abbreviation.js ├── 110_balanced_binary_tree.js └── reverseInPlace.js ├── Udacity ├── dictionary.py ├── quick_sort.py ├── fib_sequence_rec.py ├── binary_search.py └── implement_hash.py ├── KhanAcademy ├── Quick Sort │ ├── quickSortI.js │ └── quickSortII.js ├── Merge Sort │ ├── mergeSort.js │ └── mergeSortLinear.js └── Selection Sort │ └── selectionSortVisualizer.js ├── InterviewCake └── isBST.js ├── Sort ├── Basic Sorts │ ├── basic_sorts.py │ ├── basic_sorts.rb │ └── basicSorts.js ├── sortingIII.js └── sortingII.js └── Data Structures ├── Linked List ├── linked_list.py ├── linked_list.rb └── linkedList.js ├── Trees ├── BST-Traverse.js └── BST.js ├── Hash Table └── hashTable.js └── Graphs └── graph.js /HackerRank/Database/SQL/select_all.sql: -------------------------------------------------------------------------------- 1 | select * from City; 2 | -------------------------------------------------------------------------------- /HackerRank/Database/SQL/select_by_id.sql: -------------------------------------------------------------------------------- 1 | select * from City 2 | where ID=1661; 3 | -------------------------------------------------------------------------------- /HackerRank/Database/SQL/japanese_cities_names.sql: -------------------------------------------------------------------------------- 1 | select Name from City where CountryCode = 'JPN'; 2 | -------------------------------------------------------------------------------- /HackerRank/Database/SQL/japansese_cities_atributes.sql: -------------------------------------------------------------------------------- 1 | select * from CITY 2 | where COUNTRYCODE='JPN'; 3 | -------------------------------------------------------------------------------- /HackerRank/Database/SQL/revising_the_select_query1.sql: -------------------------------------------------------------------------------- 1 | Select * from City 2 | where CountryCode='USA' and population > 100000; 3 | -------------------------------------------------------------------------------- /HackerRank/Database/SQL/revising_the_select_query2.sql: -------------------------------------------------------------------------------- 1 | Select name from City 2 | where CountryCode='USA' and population > 120000; 3 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Warmup/very_big_sum.rb: -------------------------------------------------------------------------------- 1 | #!/bin/ruby 2 | 3 | n = gets.strip.to_i 4 | arr = gets.strip 5 | arr = arr.split(' ').map(&:to_i) 6 | puts arr.reduce(:+) 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Practice Algorithm 2 | Solutions of [Hackerrank](https://www.hackerrank.com), [Leetcode](https://www.leetcode.com) challenges in JavaScript. 3 | And other useful algorithm resources. 4 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Strings/pangrams.js: -------------------------------------------------------------------------------- 1 | require 'set' 2 | 3 | s = Set.new(gets.downcase.gsub(/\s+/, "").chars()) 4 | if(s.size() == 26) 5 | puts "pangram" 6 | else 7 | puts "not pangram" 8 | end 9 | -------------------------------------------------------------------------------- /HackerRank/Database/SQL/higher_than_75_marks.sql: -------------------------------------------------------------------------------- 1 | select name from 2 | ( 3 | select name, substr(name, length(name)-2) as sub_name 4 | from Students 5 | where marks > 75 order by sub_name, id asc 6 | ); 7 | -------------------------------------------------------------------------------- /leetcode/151_reverse_words_in_a_string.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} str 3 | * @returns {string} 4 | */ 5 | var reverseWords = function(str) { 6 | return str.split(' ').reverse().join(' ').replace(/^\s+|\s+$/g,'').replace(/\s+/g, ' '); 7 | }; 8 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Warmup/simple_array_sum.py: -------------------------------------------------------------------------------- 1 | #!/bin/python 2 | 3 | import sys 4 | 5 | 6 | n = int(raw_input().strip()) 7 | arr = map(int,raw_input().strip().split(' ')) 8 | sum = 0 9 | 10 | for number in arr: 11 | sum += number 12 | 13 | print sum 14 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Warmup/very_big_sum.py: -------------------------------------------------------------------------------- 1 | #!/bin/python 2 | 3 | import sys 4 | 5 | 6 | n = int(raw_input().strip()) 7 | arr = map(int,raw_input().strip().split(' ')) 8 | 9 | total = 0 10 | for number in arr: 11 | total += number 12 | 13 | print total 14 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Implementation/extra_long_factorials.rb: -------------------------------------------------------------------------------- 1 | #!/bin/ruby 2 | 3 | n = gets.strip.to_i 4 | 5 | 6 | def main(n) 7 | sum = fac(n); 8 | p sum; 9 | end 10 | 11 | def fac(n) 12 | if (n <= 1) 13 | return 1; 14 | else 15 | return n * fac(n - 1); 16 | end 17 | end 18 | 19 | main(n) 20 | -------------------------------------------------------------------------------- /leetcode/power_of_two.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} n 3 | * @return {boolean} 4 | */ 5 | var isPowerOfTwo = function(n) { 6 | if(n < 1) { return false; } 7 | if(n === 1){ return true; } 8 | 9 | var count = 1; 10 | 11 | while(count <= n){ 12 | count *= 2; 13 | } 14 | // console.log(count); 15 | return count / 2 === n; 16 | }; 17 | -------------------------------------------------------------------------------- /leetcode/104_maximum_depth_of_binary_tree.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * function TreeNode(val) { 4 | * this.val = val; 5 | * this.left = this.right = null; 6 | * } 7 | */ 8 | /** 9 | * @param {TreeNode} root 10 | * @return {number} 11 | */ 12 | var maxDepth = function(root) { 13 | if(root === null){ 14 | return 0; 15 | } 16 | 17 | return 1+ Math.max(maxDepth(root.left), maxDepth(root.right)); 18 | }; 19 | -------------------------------------------------------------------------------- /leetcode/263_ugly_number.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} num 3 | * @return {boolean} 4 | */ 5 | var isUgly = function(num) { 6 | while(num >= 2) { 7 | if(num%2 === 0) { 8 | num /= 2; 9 | } else if(num%3 === 0) { 10 | num /= 3; 11 | } else if(num%5 === 0) { 12 | num /= 5; 13 | } else { 14 | return false; 15 | } 16 | } 17 | 18 | return num === 1; 19 | }; 20 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Warmup/staircase.py: -------------------------------------------------------------------------------- 1 | #!/bin/python 2 | 3 | import sys 4 | 5 | 6 | n = int(raw_input().strip()) 7 | for i in range(1, n + 1): 8 | each_line = '' 9 | number_of_space = n - i 10 | number_to_print = n - number_of_space 11 | # print number_of_space 12 | 13 | for i in range(1, number_of_space + 1): 14 | if i != 0: 15 | each_line += str(' ') 16 | 17 | print (each_line) + str(number_to_print * '#') 18 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Warmup/time_conversion.py: -------------------------------------------------------------------------------- 1 | #!/bin/python 2 | 3 | import sys 4 | import re 5 | 6 | time = raw_input().strip() 7 | time_arr = time.split(':') 8 | 9 | if 'PM' in time and time_arr[0] != '12': 10 | time_arr[0] = str(int(time_arr[0]) + 12) 11 | elif 'AM' in time and time_arr[0] == '12': 12 | time_arr[0] = '00' 13 | 14 | time_arr[2] = time_arr[2][0:2] 15 | new_time = time_arr[0] + ':' + time_arr[1] + ':' + time_arr[2] 16 | print new_time 17 | -------------------------------------------------------------------------------- /leetcode/238_product_of_array_except_self.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number[]} 4 | */ 5 | var productExceptSelf = function(nums) { 6 | var len = nums.length; 7 | var output = Array(len).fill(1); 8 | var left = 1; 9 | var right = 1; 10 | 11 | for(var i = 0; i < len - 1; i++) { 12 | left *= nums[i]; 13 | right *= nums[len - i - 1]; 14 | output[i + 1] *= left; 15 | output[len - i - 2] *= right; 16 | } 17 | 18 | return output; 19 | }; 20 | -------------------------------------------------------------------------------- /leetcode/293_flip_game.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @return {string[]} 4 | */ 5 | var generatePossibleNextMoves = function(s) { 6 | var result = []; 7 | var arr = s.split(''); 8 | 9 | for(var i = 0; i < s.length - 1; i++) { 10 | if(arr[i] === '+' && arr[i+1] === '+') { 11 | arr[i] = '-'; 12 | arr[i+1] = '-'; 13 | result.push(arr.join('')); 14 | arr[i] = '+'; 15 | arr[i+1] = '+'; 16 | } 17 | } 18 | 19 | return result; 20 | }; 21 | -------------------------------------------------------------------------------- /leetcode/remove_duplicates_from_sorted_array.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number} 4 | */ 5 | var removeDuplicates = function(nums) { 6 | if(!nums || nums.length === 0) { 7 | return 0; 8 | } 9 | 10 | var end = 0; 11 | 12 | for(var i = 1; i < nums.length; i++) { 13 | if(nums[i] !== nums[end]) { 14 | end++; 15 | 16 | if(i !== end) { 17 | nums[end] = nums[i]; 18 | } 19 | } 20 | } 21 | 22 | return end+1; 23 | }; 24 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Bit Manipulation/flipping_bits.js: -------------------------------------------------------------------------------- 1 | function processData(input) { 2 | var numbers = input.split("\n").map(function(item) {return parseInt(item);}); 3 | for(var i = 1; i < numbers.length; i++ ) { 4 | console.log((~numbers[i]) >>> 0); 5 | } 6 | } 7 | 8 | process.stdin.resume(); 9 | process.stdin.setEncoding("ascii"); 10 | _input = ""; 11 | process.stdin.on("data", function (input) { 12 | _input += input; 13 | }); 14 | 15 | process.stdin.on("end", function () { 16 | processData(_input); 17 | }); 18 | -------------------------------------------------------------------------------- /leetcode/125_valid_palindrome.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @return {boolean} 4 | */ 5 | function isPalindrome(s){ 6 | s = s.toLowerCase(); 7 | var p1 = 0, p2 = s.length - 1; 8 | 9 | while(p1 < p2){ 10 | if(!s[p1].match(/[a-z0-9]/)){ 11 | p1++; 12 | }else if(!s[p2].match(/[a-z0-9]/)){ 13 | p2--; 14 | }else if(s[p1] !== s[p2]){ 15 | return false; 16 | }else { 17 | p1++; 18 | p2--; 19 | } 20 | } 21 | 22 | return true; 23 | } 24 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Strings/anagram.js: -------------------------------------------------------------------------------- 1 | def substitutions(input) 2 | half1 = input.slice(0, input.length / 2) 3 | half2 = input.slice(input.length / 2, input.length) 4 | 5 | for i in 0..half1.length - 1 do 6 | half2.sub!(half1[i], "") if half2.include?(half1[i]) 7 | end 8 | return half2.length 9 | end 10 | 11 | tests = gets.chomp.to_i 12 | tests.times do 13 | input = gets.chomp 14 | result = 0 15 | if input.length % 2 != 0 16 | result = -1 17 | else 18 | result = substitutions(input) 19 | end 20 | 21 | puts result 22 | end 23 | -------------------------------------------------------------------------------- /HackerRank/Regex/alien_username.js: -------------------------------------------------------------------------------- 1 | function processData(input) { 2 | var lines = input.split("\n"); 3 | for(var i = 1; i < lines.length; i++) { 4 | if(lines[i].match(/^[_\.]\d+[a-z]*_?$/ig)) { 5 | console.log("VALID"); 6 | } else { 7 | console.log("INVALID"); 8 | } 9 | } 10 | } 11 | 12 | process.stdin.resume(); 13 | process.stdin.setEncoding("ascii"); 14 | _input = ""; 15 | process.stdin.on("data", function (input) { 16 | _input += input; 17 | }); 18 | 19 | process.stdin.on("end", function () { 20 | processData(_input); 21 | }); 22 | -------------------------------------------------------------------------------- /leetcode/339_nested_list_weight_sum.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {NestedInteger[]} nestedList 3 | * @return {number} 4 | */ 5 | var depthSum = function(nestedList) { 6 | 7 | function traverse(arr, lvl) { 8 | var sum = 0; 9 | 10 | for(var i = 0; i < arr.length; i++) { 11 | if(arr[i].isInteger()) { 12 | sum += arr[i].getInteger()*lvl; 13 | } else { 14 | sum += traverse(arr[i].getList(), lvl + 1); 15 | } 16 | } 17 | 18 | return sum; 19 | } 20 | 21 | return traverse(nestedList, 1); 22 | }; 23 | -------------------------------------------------------------------------------- /leetcode/206_reverse_linked_list.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for singly-linked list. 3 | * function ListNode(val) { 4 | * this.val = val; 5 | * this.next = null; 6 | * } 7 | */ 8 | /** 9 | * @param {ListNode} head 10 | * @return {ListNode} 11 | */ 12 | var reverseList = function(head) { 13 | if(head === null){ 14 | return head; 15 | } 16 | 17 | var cur = head; 18 | var pre = null; 19 | 20 | while(cur){ 21 | var post = cur.next; 22 | cur.next = pre; 23 | pre = cur; 24 | cur = post; 25 | } 26 | 27 | return pre; 28 | }; 29 | -------------------------------------------------------------------------------- /HackerRank/Regex/split_the_phone_numbers.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const processData = input => { 4 | let numbers = input.split('\n').slice(1); 5 | for(let i = 0; i < numbers.length; i++) { 6 | let splits = numbers[i].split(/ |\-/); 7 | console.log("CountryCode=" + splits[0] 8 | + ",LocalAreaCode=" + splits[1] + ",Number=" + splits[2]); 9 | } 10 | }; 11 | 12 | process.stdin.resume(); 13 | process.stdin.setEncoding("ascii"); 14 | 15 | var _input = ""; 16 | process.stdin.on("data", input => _input += input); 17 | process.stdin.on("end", () => processData(_input)); 18 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Warmup/plus_minus.py: -------------------------------------------------------------------------------- 1 | #!/bin/python 2 | 3 | import sys 4 | 5 | 6 | n = int(raw_input().strip()) 7 | arr = map(int,raw_input().strip().split(' ')) 8 | 9 | positive = 0 10 | negative = 0 11 | zeros = 0 12 | length = len(arr) 13 | 14 | for number in arr: 15 | if number >= 1: 16 | positive += 1 17 | elif number < 0: 18 | negative += 1 19 | else: 20 | zeros += 1 21 | #print(positive, negative, zeros, length) 22 | 23 | print float(positive) / length 24 | print float(negative) / length 25 | print float(zeros) / length 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /HackerRank/DataStructures/arrays_ds.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const processData = input => { 4 | let lines = input.split('\n'); 5 | let l = parseInt(lines[0]); 6 | let array = lines[1].split(' ').map(item => parseInt(item)); 7 | let reversed = []; 8 | for(let i = l - 1; i >= 0; i--) { 9 | reversed.push(array[i]); 10 | } 11 | console.log(reversed.join(" ")); 12 | }; 13 | 14 | process.stdin.resume(); 15 | process.stdin.setEncoding("ascii"); 16 | 17 | var _input = ""; 18 | process.stdin.on("data", input => _input += input); 19 | process.stdin.on("end", () => processData(_input)); 20 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Warmup/diagonal_difference.py: -------------------------------------------------------------------------------- 1 | #!/bin/python 2 | 3 | import sys 4 | 5 | 6 | n = int(raw_input().strip()) 7 | a = [] 8 | for a_i in xrange(n): 9 | a_temp = map(int,raw_input().strip().split(' ')) 10 | a.append(a_temp) 11 | 12 | # print a 13 | first_sum = 0 14 | second_sum = 0 15 | 16 | for index, array in enumerate(a): 17 | #print (index, array) 18 | first_sum += array[index] 19 | 20 | #Reversing the array 21 | reversed_array = list(reversed(array)) 22 | second_sum += reversed_array[index] 23 | #print reversed_array 24 | 25 | print abs(first_sum - second_sum) 26 | 27 | -------------------------------------------------------------------------------- /HackerRank/Regex/valid_pan_format.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const PAN = /[A-Z]{5}\d{4}[A-Z]/; 4 | 5 | const processData = input => { 6 | let lines = input.split('\n').slice(1); 7 | let isPan = s => { 8 | if(s.match(PAN)) { 9 | return "YES"; 10 | } else { 11 | return "NO"; 12 | } 13 | }; 14 | console.log(lines.map(isPan).join('\n')); 15 | }; 16 | 17 | process.stdin.resume(); 18 | process.stdin.setEncoding("ascii"); 19 | 20 | var _input = ""; 21 | process.stdin.on("data", input => _input += input); 22 | process.stdin.on("end", () => processData(_input)); 23 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Implementation/cut_the_sticks.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const processData = input => { 4 | const lines = input.split('\n'); 5 | let sticks = lines[1].split(' ').map(i => parseInt(i)); 6 | while(sticks.length > 0) { 7 | console.log(sticks.length); 8 | sticks.sort((a, b) => a - b); 9 | const min = sticks[0]; 10 | sticks = sticks.filter(i => i > min); 11 | } 12 | }; 13 | 14 | process.stdin.resume(); 15 | process.stdin.setEncoding("ascii"); 16 | 17 | let _input = ""; 18 | process.stdin.on("data", input => _input += input); 19 | process.stdin.on("end", () => processData(_input)); 20 | -------------------------------------------------------------------------------- /leetcode/rotateArray.js: -------------------------------------------------------------------------------- 1 | var rotate = function(nums, k) { 2 | var len = nums.length; 3 | if (k === 0){ 4 | return; 5 | } 6 | else if (k < len && len >= 2 * k + 1){ 7 | for (var i = 1; i <= k + 1; i++){ 8 | var temp = nums.shift(); 9 | nums.push(temp); 10 | } 11 | } else { 12 | for (var i = 0; i < k; i++){ 13 | var temp = nums.shift(); 14 | nums.push(temp); 15 | } 16 | } 17 | 18 | }; 19 | 20 | var num = [1,2,3]; 21 | rotate(num, 2); 22 | console.log(num); 23 | 24 | // var eq = require('assert').deepEqual; 25 | // var num = [1,2,3,4,5,6,7]; 26 | // rotate(num, 3); 27 | // eq(num, [5, 6, 7, 1, 2, 3, 4]); 28 | 29 | 30 | -------------------------------------------------------------------------------- /Udacity/dictionary.py: -------------------------------------------------------------------------------- 1 | locations = {'North America': {'USA': ['Mountain View']}} 2 | locations['North America']['USA'].append('Atlanta') 3 | locations['Asia'] = {'India': ['Bangalore']} 4 | locations['Asia']['China'] = ['Shanghai'] 5 | locations['Africa'] = {'Egypt': ['Cairo']} 6 | 7 | print 1 8 | usa_sorted = sorted(locations['North America']['USA']) 9 | for city in usa_sorted: 10 | print city 11 | 12 | print 2 13 | asia_cities = [] 14 | for countries, cities in locations['Asia'].iteritems(): 15 | city_country = cities[0] + " - " + countries 16 | asia_cities.append(city_country) 17 | asia_sorted = sorted(asia_cities) 18 | for city in asia_sorted: 19 | print city 20 | -------------------------------------------------------------------------------- /leetcode/232_implement_queue_using_stacks.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @constructor 3 | */ 4 | var Queue = function() { 5 | this.stack = []; 6 | }; 7 | 8 | /** 9 | * @param {number} x 10 | * @returns {void} 11 | */ 12 | Queue.prototype.push = function(x) { 13 | this.stack.push(x); 14 | }; 15 | 16 | /** 17 | * @returns {void} 18 | */ 19 | Queue.prototype.pop = function() { 20 | this.stack.shift(); 21 | }; 22 | 23 | /** 24 | * @returns {number} 25 | */ 26 | Queue.prototype.peek = function() { 27 | return this.stack[0]; 28 | }; 29 | 30 | /** 31 | * @returns {boolean} 32 | */ 33 | Queue.prototype.empty = function() { 34 | return this.stack.length === 0; 35 | }; 36 | -------------------------------------------------------------------------------- /leetcode/243_shortest_word_distance.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string[]} words 3 | * @param {string} word1 4 | * @param {string} word2 5 | * @return {number} 6 | */ 7 | var shortestDistance = function(words, word1, word2) { 8 | var idx1 = -1; 9 | var idx2 = -1; 10 | var dist = words.length - 1; 11 | 12 | for(var i = 0; i < words.length; i++) { 13 | if(words[i] === word1) { 14 | idx1 = i; 15 | } else if(words[i] === word2) { 16 | idx2 = i; 17 | } 18 | 19 | if(idx1 !== -1 && idx2 !== -1) { 20 | dist = Math.min(dist, Math.abs(idx1 - idx2)) 21 | } 22 | } 23 | 24 | return dist; 25 | }; 26 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Strings/the_love_letter_mystery.js: -------------------------------------------------------------------------------- 1 | function processData(input) { 2 | var lines = input.split('\n'); 3 | for(var i = 1; i < lines.length; i++) { 4 | var diff = 0; 5 | for(var j = 0; j < lines[i].length / 2; j++) { 6 | diff += Math.abs(lines[i].charCodeAt(j) - lines[i].charCodeAt(lines[i].length - j - 1)); 7 | } 8 | console.log(diff); 9 | } 10 | } 11 | 12 | process.stdin.resume(); 13 | process.stdin.setEncoding("ascii"); 14 | _input = ""; 15 | process.stdin.on("data", function (input) { 16 | _input += input; 17 | }); 18 | 19 | process.stdin.on("end", function () { 20 | processData(_input); 21 | }); 22 | -------------------------------------------------------------------------------- /leetcode/225_implement_stack_using_queues.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @constructor 3 | */ 4 | var Stack = function() { 5 | this.stack = []; 6 | }; 7 | 8 | /** 9 | * @param {number} x 10 | * @returns {void} 11 | */ 12 | Stack.prototype.push = function(x) { 13 | this.stack.push(x); 14 | }; 15 | 16 | /** 17 | * @returns {void} 18 | */ 19 | Stack.prototype.pop = function() { 20 | this.stack.pop(); 21 | }; 22 | 23 | /** 24 | * @returns {number} 25 | */ 26 | Stack.prototype.top = function() { 27 | return this.stack[this.stack.length - 1]; 28 | }; 29 | 30 | /** 31 | * @returns {boolean} 32 | */ 33 | Stack.prototype.empty = function() { 34 | return this.stack.length === 0; 35 | }; 36 | -------------------------------------------------------------------------------- /leetcode/242_valid_anagram.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @param {string} t 4 | * @return {boolean} 5 | */ 6 | var isAnagram = function(s, t) { 7 | var slen = s.length; 8 | var tlen = t.length; 9 | 10 | if(slen !== tlen) { 11 | return false; 12 | } 13 | 14 | var hash = {}; 15 | 16 | for(var i = 0; i < slen; i++) { 17 | var char = s[i]; 18 | hash[char] = hash[char] || 0; 19 | hash[char]++; 20 | } 21 | 22 | for(i = 0; i < tlen; i++) { 23 | char = t[i]; 24 | 25 | if(hash[char] === undefined || hash[char] === 0) { 26 | return false; 27 | } 28 | 29 | hash[char]--; 30 | } 31 | 32 | return true; 33 | }; 34 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Bit Manipulation/maximizing_xor.js: -------------------------------------------------------------------------------- 1 | function processData(input) { 2 | var l = parseInt(input.split("\n")[0]); 3 | var r = parseInt(input.split("\n")[1]); 4 | var max = 0; 5 | for(var i = l; i <= r; i++) { 6 | for(var j = l; j <= r; j++) { 7 | var xor = i ^ j; 8 | if(xor > max) { 9 | max = xor; 10 | } 11 | } 12 | } 13 | console.log(max); 14 | } 15 | 16 | process.stdin.resume(); 17 | process.stdin.setEncoding("ascii"); 18 | _input = ""; 19 | process.stdin.on("data", function (input) { 20 | _input += input; 21 | }); 22 | 23 | process.stdin.on("end", function () { 24 | processData(_input); 25 | }); 26 | -------------------------------------------------------------------------------- /Udacity/quick_sort.py: -------------------------------------------------------------------------------- 1 | """Implement quick sort in Python. 2 | Input a list. 3 | Output a sorted list.""" 4 | def quicksort(array): 5 | 6 | if len(array) <= 1: 7 | return array 8 | 9 | pivot_index = len(array) / 2 10 | pivot_value = array[pivot_index] 11 | before = [] 12 | after = [] 13 | 14 | for number in range(0, len(array)): 15 | if number != pivot_index: 16 | if array[number] <= pivot_value: 17 | before.append(array[number]) 18 | else: 19 | after.append(array[number]) 20 | 21 | return quicksort(before) + [pivot_value] + quicksort(after) 22 | 23 | test = [21, 4, 1, 3, 9, 20, 25, 6, 21, 14] 24 | print quicksort(test) 25 | -------------------------------------------------------------------------------- /Udacity/fib_sequence_rec.py: -------------------------------------------------------------------------------- 1 | """Implement a function recursivly to get the desired 2 | Fibonacci sequence value. 3 | Your code should have the same input/output as the 4 | iterative code in the instructions.""" 5 | 6 | def get_fib(position): 7 | 8 | fib = [0, 1] 9 | def recursion(num): 10 | if num >= position: 11 | return 12 | else: 13 | first = len(fib) - 1 14 | second = len(fib) - 2 15 | to_insert = fib[first] + fib[second] 16 | 17 | fib.append(to_insert) 18 | recursion(num + 1) 19 | recursion(1) 20 | return fib[position] 21 | 22 | # Test cases 23 | print get_fib(9) 24 | print get_fib(11) 25 | print get_fib(0) 26 | -------------------------------------------------------------------------------- /leetcode/204_count_primes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} n 3 | * @return {number} 4 | */ 5 | var countPrimes = function(n) { 6 | if(n <= 2){ 7 | return 0; 8 | } 9 | 10 | var mem = []; 11 | 12 | for(var i = 2; i < n; i++){ 13 | mem[i] = true; 14 | } 15 | 16 | sq = parseInt(Math.sqrt(n - 1)); 17 | 18 | for(i = 2; i <= sq; i++){ 19 | if(mem[i]){ 20 | for(var j = i + i; j < mem.length; j += i){ 21 | mem[j] = false; 22 | } 23 | } 24 | } 25 | 26 | var count = 0; 27 | for(i = 2; i < mem.length; i++){ 28 | if(mem[i]){ 29 | count++; 30 | } 31 | } 32 | 33 | return count; 34 | } 35 | -------------------------------------------------------------------------------- /leetcode/66_plus_one.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} digits 3 | * @return {number[]} 4 | */ 5 | var plusOne = function(digits) { 6 | if(digits.length === 0){ return [1] } 7 | 8 | var pointer = digits.length - 1, 9 | val = 0, check = true; 10 | 11 | while(check){ 12 | val = digits[pointer] + 1; 13 | if(val > 9 && pointer === 0){ 14 | digits[pointer] = 0; 15 | digits.unshift(1); 16 | check = false; 17 | }else if(val > 9){ 18 | digits[pointer] = 0; 19 | pointer--; 20 | }else { 21 | digits[pointer] = val; 22 | check = false; 23 | } 24 | } 25 | 26 | return digits; 27 | }; 28 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Implementation/encryption.js: -------------------------------------------------------------------------------- 1 | function processData(input) { 2 | var height = parseInt(Math.ceil(Math.sqrt(input.length)), 10); 3 | var width = parseInt(Math.floor(Math.sqrt(input.length)), 10); 4 | var result = ''; 5 | for(var i = 0; i < height; i++) { 6 | var j = i; 7 | while(j < input.length) { 8 | result += input[j]; 9 | j += height; 10 | } 11 | result += ' '; 12 | } 13 | console.log(result); 14 | } 15 | 16 | process.stdin.resume(); 17 | process.stdin.setEncoding("ascii"); 18 | _input = ""; 19 | process.stdin.on("data", function (input) { 20 | _input += input; 21 | }); 22 | 23 | process.stdin.on("end", function () { 24 | processData(_input); 25 | }); 26 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Warmup/introToTutorial.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const processData = input => { 4 | let getPosition = (arr, val) => { 5 | for(let i = 0; i < arr.length; i++) { 6 | if(arr[i] == val) { 7 | return i; 8 | } 9 | } 10 | }; 11 | let lines = input.split('\n'); 12 | let searchedValue = parseInt(lines[0]); 13 | let array = lines[2].split(' ').map(i => parseInt(i)); 14 | let position = getPosition(array, searchedValue); 15 | console.log(position); 16 | }; 17 | 18 | process.stdin.resume(); 19 | process.stdin.setEncoding("ascii"); 20 | 21 | var _input = ""; 22 | process.stdin.on("data", input => _input += input); 23 | process.stdin.on("end", () => processData(_input)); 24 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Strings/alternating_characters.js: -------------------------------------------------------------------------------- 1 | function processData(input) { 2 | var lines = input.split("\n"); 3 | console.log(lines.slice(1, lines.length).map(deletions).join("\n")); 4 | } 5 | 6 | function deletions(s) { 7 | var last = s.charAt(0); 8 | var dels = 0; 9 | for(var i = 1; i < s.length; i++) { 10 | if(last === s.charAt(i)) { 11 | dels++; 12 | } else { 13 | last = s.charAt(i); 14 | } 15 | } 16 | return dels; 17 | } 18 | 19 | process.stdin.resume(); 20 | process.stdin.setEncoding("ascii"); 21 | _input = ""; 22 | process.stdin.on("data", function (input) { 23 | _input += input; 24 | }); 25 | 26 | process.stdin.on("end", function () { 27 | processData(_input); 28 | }); 29 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Greedy/max_min.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const processData = input => { 4 | let lines = input.split('\n').map(i => parseInt(i)); 5 | let k = lines[1]; 6 | let sortedLines = lines.slice(2).sort((l,j) => l - j); 7 | let unfairness = sortedLines[sortedLines.length - 1]; 8 | for(let i = 0; i <= sortedLines.length - k; i++) { 9 | let temp = sortedLines[i + k - 1] - sortedLines[i]; 10 | if(unfairness > temp) { 11 | unfairness = temp 12 | } 13 | } 14 | console.log(unfairness); 15 | }; 16 | 17 | process.stdin.resume(); 18 | process.stdin.setEncoding("ascii"); 19 | 20 | var _input = ""; 21 | process.stdin.on("data", input => _input += input); 22 | process.stdin.on("end", () => processData(_input)); 23 | -------------------------------------------------------------------------------- /leetcode/186_reverse_words_in_a_string_II.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {character[]} str 3 | * @return {void} Do not return anything, modify the string in-place instead. 4 | */ 5 | 6 | var reverseWords = function(str) { 7 | var arr = str; 8 | 9 | reverse(arr, 0, arr.length - 1); 10 | var last = 0; 11 | 12 | for(var i = 0; i <= arr.length; i++) { 13 | if(arr[i] === ' ' || i === arr.length) { 14 | reverse(arr, last, i - 1); 15 | last = i + 1; 16 | } 17 | } 18 | 19 | function reverse(arr, beg, end) { 20 | while(beg < end) { 21 | var tmp = str[beg]; 22 | str[beg] = str[end]; 23 | str[end] = tmp; 24 | beg++; 25 | end--; 26 | } 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /HackerRank/Regex/find_hackerrank.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | let findHackerrank = line => { 4 | if(line.match(/^hackerrank$/) || line.match(/^hackerrank.*hackerrank$/)) 5 | return "0"; 6 | else if(line.match(/^hackerrank.*/)) 7 | return "1"; 8 | else if(line.match(/.*hackerrank$/)) 9 | return "2"; 10 | else 11 | return "-1"; 12 | }; 13 | 14 | const processData = input => { 15 | let lines = input.split('\n').slice(1); 16 | console.log(lines.filter(line => line.match(/[a-z]+/)).map(findHackerrank).join('\n')) 17 | }; 18 | 19 | process.stdin.resume(); 20 | process.stdin.setEncoding("ascii"); 21 | 22 | var _input = ""; 23 | process.stdin.on("data", input => _input += input); 24 | process.stdin.on("end", () => processData(_input)); 25 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Bit Manipulation/lonely_integer.js: -------------------------------------------------------------------------------- 1 | function processData(input) { 2 | var arr = input.split("\n")[1].split(" ").map(function(item) {return parseInt(item)}); 3 | var hash = {}; 4 | for(var i = 0; i < arr.length; i++) { 5 | if(hash[arr[i]]) { 6 | hash[arr[i]] += 1; 7 | } else { 8 | hash[arr[i]] = 1; 9 | } 10 | } 11 | for(prop in hash) { 12 | if(hash.hasOwnProperty(prop) && hash[prop] == 1) { 13 | console.log(prop); 14 | return; 15 | } 16 | } 17 | } 18 | 19 | process.stdin.resume(); 20 | process.stdin.setEncoding("ascii"); 21 | _input = ""; 22 | process.stdin.on("data", function (input) {_input += input;}); 23 | 24 | process.stdin.on("end", function () {processData(_input);}); 25 | -------------------------------------------------------------------------------- /leetcode/245_shortest_word_distance_III.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string[]} words 3 | * @param {string} word1 4 | * @param {string} word2 5 | * @return {number} 6 | */ 7 | var shortestWordDistance = function(words, word1, word2) { 8 | var idx1 = -1; 9 | var idx2 = -1; 10 | var dist = words.length - 1; 11 | 12 | for(var i = 0; i < words.length; i++) { 13 | if(words[i] === word1) { 14 | if(words[idx1] === word1 && word1 === word2) { 15 | idx2 = idx1; 16 | } 17 | 18 | idx1 = i; 19 | } else if(words[i] === word2) { 20 | idx2 = i; 21 | } 22 | 23 | if(idx1 !== -1 && idx2 !== -1) { 24 | dist = Math.min(dist, Math.abs(idx1 - idx2)) 25 | } 26 | } 27 | 28 | return dist; 29 | }; 30 | -------------------------------------------------------------------------------- /leetcode/349_intersection_of_two_arrays.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums1 3 | * @param {number[]} nums2 4 | * @return {number[]} 5 | */ 6 | var intersection = function(nums1, nums2) { 7 | var hash = {}; 8 | var result = []; 9 | var i = 0; 10 | while(i < nums1.length || i < nums2.length) { 11 | if(i < nums1.length) { 12 | hash[nums1[i]] = hash[nums1[i]] || []; 13 | hash[nums1[i]][0] = true; 14 | } 15 | 16 | if(i < nums2.length) { 17 | hash[nums2[i]] = hash[nums2[i]] || []; 18 | hash[nums2[i]][1] = true; 19 | } 20 | 21 | i++ 22 | } 23 | 24 | for(i in hash) { 25 | if(hash[i][0] && hash[i][1]) { 26 | result.push(parseInt(i)); 27 | } 28 | } 29 | 30 | return result; 31 | }; 32 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Warmup/insertionSortPart2.js: -------------------------------------------------------------------------------- 1 | let insertIntoSorted = arr => { 2 | 3 | for (var i = 1; i < arr.length; i++) { 4 | var key = arr[i]; 5 | var j = i - 1; 6 | 7 | while (j >= 0 && key < arr[j]) { 8 | arr[j + 1] = arr[j]; 9 | j -= 1; 10 | } 11 | arr[j + 1] = key; 12 | printArray(arr); 13 | } 14 | }; 15 | 16 | let printArray = arr => console.log(arr.join(" ")); 17 | 18 | const processData = input => { 19 | let lines = input.split('\n'); 20 | let arr = lines[1].split(' ').map(i => parseInt(i)); 21 | insertIntoSorted(arr) 22 | }; 23 | 24 | process.stdin.resume(); 25 | process.stdin.setEncoding("ascii"); 26 | 27 | var _input = ""; 28 | process.stdin.on("data", input => _input += input); 29 | process.stdin.on("end", () => processData(_input)); 30 | -------------------------------------------------------------------------------- /leetcode/group_shifted_strings.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string[]} strings 3 | * @return {string[][]} 4 | */ 5 | var groupStrings = function(strings) { 6 | 7 | var result = []; 8 | var map = new Map(); 9 | 10 | for(var i = 0; i < strings.length; i++){ 11 | var string = strings[i]; 12 | var shift = ''; 13 | 14 | for(var j = 0; j < string.length; j++){ 15 | shift += (string.charCodeAt(j) - string.charCodeAt(0) + 26) % 26; 16 | shift += ' '; 17 | } 18 | 19 | if(map.has(shift)){ 20 | map.get(shift).push(string); 21 | }else{ 22 | map.set(shift, [string]); 23 | } 24 | // console.log(map); 25 | } 26 | 27 | map.forEach(function(value, key){ 28 | result.push(value); 29 | }); 30 | 31 | return result; 32 | 33 | }; 34 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Warmup/compare_the_triplets.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const processData = input => { 4 | const lines = input.split('\n'); 5 | const alicesRating = lines[0].split(' ').map(i => parseInt(i)); 6 | const bobRating = lines[1].split(' ').map(i => parseInt(i)); 7 | 8 | let aliceScore = 0; 9 | let bobScore = 0; 10 | for(let i = 0; i < alicesRating.length; i++) { 11 | if (alicesRating[i] > bobRating[i]) { 12 | aliceScore++; 13 | } else if (alicesRating[i] < bobRating[i]) { 14 | bobScore++; 15 | } 16 | } 17 | console.log(aliceScore + ' ' + bobScore); 18 | }; 19 | 20 | process.stdin.resume(); 21 | process.stdin.setEncoding("ascii"); 22 | 23 | let _input = ""; 24 | process.stdin.on("data", input => _input += input); 25 | process.stdin.on("end", () => processData(_input)); 26 | -------------------------------------------------------------------------------- /HackerRank/Regex/find_a_substring.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const processData = input => { 4 | let inputLines = input.split('\n'); 5 | let linesLength = parseInt(inputLines[0]); 6 | let substrings = inputLines.slice(linesLength + 2); 7 | for(let j = 0; j < substrings.length; j++) { 8 | let count = 0; 9 | let pattern = "\\w+" + substrings[j] + "\\w+"; 10 | for(let i = 1; i <= linesLength; i++) { 11 | let line = inputLines[i]; 12 | let match = line.match(new RegExp(pattern, "g")); 13 | count += match ? match.length : 0; 14 | } 15 | console.log(count); 16 | } 17 | }; 18 | 19 | process.stdin.resume(); 20 | process.stdin.setEncoding("ascii"); 21 | 22 | var _input = ""; 23 | process.stdin.on("data", input => _input += input); 24 | process.stdin.on("end", () => processData(_input)); 25 | -------------------------------------------------------------------------------- /leetcode/350_insersection_of_two_arrays_II.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums1 3 | * @param {number[]} nums2 4 | * @return {number[]} 5 | */ 6 | var intersect = function(nums1, nums2) { 7 | var hash = {}; 8 | var arr1, arr2; 9 | 10 | if(nums1.length > nums2.length) { 11 | arr1 = nums2; 12 | arr2 = nums1; 13 | } else { 14 | arr1 = nums1; 15 | arr2 = nums2; 16 | } 17 | 18 | var count = arr1.length; 19 | var result = []; 20 | 21 | for(var i = 0; i < arr1.length; i++) { 22 | hash[arr1[i]] = hash[arr1[i]] || 0; 23 | hash[arr1[i]]++; 24 | } 25 | 26 | for(i = 0; i < arr2.length && count !== 0; i++) { 27 | if(hash[arr2[i]] > 0) { 28 | hash[arr2[i]]--; 29 | count--; 30 | result.push(arr2[i]); 31 | } 32 | } 33 | 34 | return result; 35 | }; 36 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Implementation/service_lane.js: -------------------------------------------------------------------------------- 1 | function processData(input) { 2 | var lines = input.split('\n'); 3 | var lanes = lines[1].split(' ').map(function(item) {return parseInt(item)}); 4 | for(var i = 2; i < lines.length; i++) { 5 | var arr = lines[i].split(' ').map(function(item) {return parseInt(item)}); 6 | console.log(findMin(lanes, arr[0], arr[1])); 7 | } 8 | } 9 | 10 | function findMin(arr, i, j) { 11 | var min = 10000000; 12 | for(var k = i; k <= j; k++) { 13 | if(arr[k] < min) { 14 | min = arr[k]; 15 | } 16 | } 17 | return min; 18 | } 19 | 20 | process.stdin.resume(); 21 | process.stdin.setEncoding("ascii"); 22 | _input = ""; 23 | process.stdin.on("data", function (input) { 24 | _input += input; 25 | }); 26 | 27 | process.stdin.on("end", function () { 28 | processData(_input); 29 | }); 30 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Implementation/utopian_tree.js: -------------------------------------------------------------------------------- 1 | function processData(input) { 2 | var numbers = input.split("\n").map(function(i) {return parseInt(i); }); 3 | var index = 0; 4 | var tests = numbers[index++]; 5 | 6 | for(var i = 0; i < tests; i++) { 7 | var cycles = numbers[index++]; 8 | console.log(tree(0, cycles, 1)); 9 | } 10 | } 11 | 12 | function tree(actual, cycles, height) { 13 | if(actual == cycles) { 14 | return height 15 | } 16 | if(actual % 2 == 0) 17 | return tree(actual + 1, cycles, height * 2) 18 | return tree(actual + 1, cycles, height + 1) 19 | } 20 | 21 | process.stdin.resume(); 22 | process.stdin.setEncoding("ascii"); 23 | _input = ""; 24 | process.stdin.on("data", function (input) { 25 | _input += input; 26 | }); 27 | 28 | process.stdin.on("end", function () { 29 | processData(_input); 30 | }); 31 | -------------------------------------------------------------------------------- /HackerRank/Regex/detecting_valid_latitude_and_longitude_pairs.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const LATITUDE_LONGITUDE_PATTERN = 4 | "^\\([+-]?((90(\\.0+)?)|([1-8][0-9](\\.[0-9]+)?)|([0-9](\\.[0-9]+)?)),\\s*[+-]?(((([1-9][0-9])|([0-9]))(\\.[0-9]+)?)|(1((80(\\.0+)?)|([0-7][0-9](\\.[0-9]+)?))))\\)$"; 5 | 6 | const processData = input => { 7 | let validate = pair => { 8 | if(pair.match(LATITUDE_LONGITUDE_PATTERN)) { 9 | return "Valid"; 10 | } else { 11 | return "Invalid"; 12 | } 13 | }; 14 | let pairs = input.split('\n').slice(1); 15 | let validations = pairs.map(validate); 16 | console.log(validations.join('\n')); 17 | }; 18 | 19 | process.stdin.resume(); 20 | process.stdin.setEncoding("ascii"); 21 | 22 | var _input = ""; 23 | process.stdin.on("data", input => _input += input); 24 | process.stdin.on("end", () => processData(_input)); 25 | -------------------------------------------------------------------------------- /leetcode/20_valid_parantheses.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @return {boolean} 4 | */ 5 | var isValid = function(s) { 6 | var stack = []; 7 | var index = 0; 8 | 9 | while(index < s.length){ 10 | var cur = s[index]; 11 | 12 | if(cur === '(' || cur === '[' || cur === '{'){ 13 | stack.push(cur); 14 | }else{ 15 | var oldCur = stack.pop(); 16 | if( oldCur === '(' && cur !== ')' ){ 17 | return false; 18 | }else if( oldCur === '[' && cur !== ']' ){ 19 | return false; 20 | }else if( oldCur === '{' && cur !== '}' ){ 21 | return false; 22 | }else if(oldCur === undefined) { 23 | return false; 24 | } 25 | } 26 | 27 | index++; 28 | } 29 | // console.log(stack); 30 | return stack.length === 0; 31 | }; 32 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Strings/funny_Strings.js: -------------------------------------------------------------------------------- 1 | function processData(input) { 2 | var lines = input.split('\n'); 3 | for(var i = 1; i < lines.length; i++) { 4 | if(isFunny(lines[i])) { 5 | console.log("Funny"); 6 | } else { 7 | console.log("Not Funny"); 8 | } 9 | } 10 | } 11 | 12 | function isFunny(s) { 13 | for(var j = 0; j < s.length - 1; j++) { 14 | if(Math.abs(s.charCodeAt(j + 1) - s.charCodeAt(j)) !== 15 | Math.abs(s.charCodeAt(s.length - j - 2) - s.charCodeAt(s.length - j - 1))) { 16 | return false; 17 | } 18 | } 19 | return true; 20 | } 21 | 22 | process.stdin.resume(); 23 | process.stdin.setEncoding("ascii"); 24 | _input = ""; 25 | process.stdin.on("data", function (input) { 26 | _input += input; 27 | }); 28 | 29 | process.stdin.on("end", function () { 30 | processData(_input); 31 | }); 32 | -------------------------------------------------------------------------------- /leetcode/383_ransom_note.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} ransomNote 3 | * @param {string} magazine 4 | * @return {boolean} 5 | */ 6 | var canConstruct = function(ransomNote, magazine) { 7 | var hash = {}; 8 | var mLen = magazine.length; 9 | var rLen = ransomNote.length; 10 | var mIdx = 0; 11 | var rIdx = 0; 12 | 13 | while(rIdx < rLen) { 14 | var rc = ransomNote[rIdx]; 15 | 16 | if(hash[rc] === undefined || hash[rc] === 0) { 17 | var found = false; 18 | 19 | while(mIdx < mLen) { 20 | var mc = magazine[mIdx]; 21 | hash[mc] = hash[mc] || 0; 22 | hash[mc]++; 23 | mIdx++; 24 | 25 | if(mc === rc) { 26 | found = true; 27 | break; 28 | } 29 | } 30 | 31 | if(!found) { 32 | return false; 33 | } 34 | } 35 | 36 | hash[rc]--; 37 | rIdx++; 38 | } 39 | 40 | return true; 41 | }; 42 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Implementation/find_digits.js: -------------------------------------------------------------------------------- 1 | function processData(input) { 2 | var inputs = input.split('\n'); 3 | var tests = parseInt(inputs[0]); 4 | 5 | for(var i = 0; i < tests; i++) { 6 | for(var j = 1; j < inputs.length; j++) { 7 | var result = 0; 8 | var num = parseInt(inputs[j]); 9 | for(var k = 0; k < inputs[j].length; k++) { 10 | var c = parseInt(inputs[j][k]); 11 | if(c > 0 && num % c === 0) { 12 | result++; 13 | } 14 | } 15 | console.log(result); 16 | } 17 | return; 18 | } 19 | } 20 | 21 | process.stdin.resume(); 22 | process.stdin.setEncoding("ascii"); 23 | _input = ""; 24 | process.stdin.on("data", function (input) { 25 | _input += input; 26 | }); 27 | 28 | process.stdin.on("end", function () { 29 | processData(_input); 30 | }); 31 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Implementation/library_fine.js: -------------------------------------------------------------------------------- 1 | function processData(input) { 2 | var lines = input.split("\n"); 3 | var actualDate = lines[0].split(" "); 4 | var expectedDate = lines[1].split(" "); 5 | 6 | var yearDiff = parseInt(actualDate[2]) - parseInt(expectedDate[2]); 7 | var monthDiff = parseInt(actualDate[1]) - parseInt(expectedDate[1]); 8 | var dayDiff = parseInt(actualDate[0]) - parseInt(expectedDate[0]); 9 | 10 | console.log(fee(yearDiff, monthDiff, dayDiff)); 11 | } 12 | 13 | function fee(year, month, day) 14 | { 15 | if(year > 0) return 10000; 16 | if(year == 0 && month > 0) return month * 500; 17 | if(year == 0 && month == 0 && day > 0) return day * 15; 18 | return 0; 19 | } 20 | process.stdin.resume(); 21 | process.stdin.setEncoding("ascii"); 22 | _input = ""; 23 | process.stdin.on("data", function (input) { 24 | _input += input; 25 | }); 26 | 27 | process.stdin.on("end", function () { 28 | processData(_input); 29 | }); 30 | -------------------------------------------------------------------------------- /leetcode/266_palindrome_permutation.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @return {boolean} 4 | */ 5 | var canPermutePalindrome = function(s) { 6 | var countMap = {}; 7 | 8 | for(var i = 0; i < s.length; i++) { 9 | var c = s[i]; 10 | 11 | countMap[c] = countMap[c] || 0; 12 | countMap[c]++; 13 | } 14 | var oddCount = 0; 15 | 16 | for(i in countMap) { 17 | if(countMap[i]%2 === 1) { 18 | oddCount++; 19 | } 20 | } 21 | 22 | return oddCount < 2; 23 | }; 24 | 25 | // Solution (2) if it's ASCII 256 chars only 26 | 27 | // var canPermutePalindrome = function(s) { 28 | // // assume that s is only contact 256 english letters 29 | // var letters = Array(256).fill(0); 30 | // var odd = 0; 31 | // for(var i = 0; i < s.length; i++) { 32 | // var letterIndex = s[i].charCodeAt(0); 33 | // odd += (++letters[letterIndex] & 1) === 1 ? 1 : -1; 34 | // } 35 | // return odd < 2; 36 | // }; 37 | -------------------------------------------------------------------------------- /HackerRank/Regex/ip_address_validation.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const IP6_PATTERN = "([a-f0-9]{1,4}:){7}\\b[0-9a-f]{1,4}\\b"; 4 | const IP4_PATTERN = 5 | "\\b(((2[0-5][0-5])|(1[0-9][0-9])|(\\b[1-9][0-9]\\b)|(\\b\\d\\b))\\.){3}((2[0-5][0-5])|(1[0-9][0-9])|(\\b[1-9][0-9]\\b)|(\\b\\d\\b))\\b"; 6 | 7 | const processData = input => { 8 | let lines = input.split('\n').slice(1); 9 | let ipValidation = address => { 10 | if(address.match(new RegExp(IP4_PATTERN))) { 11 | return "IPv4"; 12 | } else if(address.match(new RegExp(IP6_PATTERN))) { 13 | return "IPv6"; 14 | } else { 15 | return "Neither"; 16 | } 17 | }; 18 | let validations = lines.map(ipValidation); 19 | console.log(validations.join('\n')); 20 | }; 21 | 22 | process.stdin.resume(); 23 | process.stdin.setEncoding("ascii"); 24 | 25 | var _input = ""; 26 | process.stdin.on("data", input => _input += input); 27 | process.stdin.on("end", () => processData(_input)); 28 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Warmup/insertionSortPart1.js: -------------------------------------------------------------------------------- 1 | let insertIntoSorted = arr => { 2 | let num = arr[arr.length - 1]; 3 | let placed = false; 4 | for(let j = arr.length - 2; j >= 0; j--) { 5 | if(arr[j] > num) { 6 | arr[j + 1] = arr[j]; 7 | printArray(arr); 8 | } else { 9 | arr[j + 1] = num; 10 | printArray(arr); 11 | placed = true; 12 | break; 13 | } 14 | } 15 | if(!placed) { 16 | arr[0] = num; 17 | printArray(arr); 18 | } 19 | }; 20 | 21 | let printArray = arr => console.log(arr.join(" ")); 22 | 23 | const processData = input => { 24 | let lines = input.split('\n'); 25 | let arr = lines[1].split(' ').map(i => parseInt(i)); 26 | insertIntoSorted(arr) 27 | }; 28 | 29 | process.stdin.resume(); 30 | process.stdin.setEncoding("ascii"); 31 | 32 | var _input = ""; 33 | process.stdin.on("data", input => _input += input); 34 | process.stdin.on("end", () => processData(_input)); 35 | -------------------------------------------------------------------------------- /HackerRank/Regex/detect_html_tags.js: -------------------------------------------------------------------------------- 1 | function processData(input) { 2 | const tagPattern = /<\s*[a-z0-9]+/g 3 | var lines = input.split("\n"); 4 | var tagSet = {}; 5 | for(var i = 1; i < lines.length; i++) { 6 | var tags = lines[i].match(tagPattern); 7 | if(tags) { 8 | tags = tags.map(function(item) {return item.replace(/ { 4 | const lines = input.split('\n'); 5 | const arr = lines[0].split(/\s+/).map(i => parseInt(i)); 6 | const n = arr[0]; 7 | const k = arr[1]; 8 | const problemsPerChapter = lines[1].split(/\s+/).map(i => parseInt(i)); 9 | let specialProblems = 0; 10 | let page = 1; 11 | for(let i = 0; i < n; i++) { 12 | const problems = problemsPerChapter[i]; 13 | for(let p = 1; p <= problems; p++) { 14 | if(p === page) { 15 | specialProblems++; 16 | } 17 | if(p !== problems && p % k === 0) { 18 | page++; 19 | } 20 | } 21 | page++; 22 | } 23 | console.log(specialProblems); 24 | }; 25 | 26 | process.stdin.resume(); 27 | process.stdin.setEncoding("ascii"); 28 | 29 | var _input = ""; 30 | process.stdin.on("data", input => _input += input); 31 | process.stdin.on("end", () => processData(_input)); 32 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Search/ice_cream_parlor.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const processData = input => { 4 | let lines = input.split('\n'); 5 | let tests = parseInt(lines[0]); 6 | let index = 1; 7 | for(let i = 0; i < tests; i++) { 8 | let amount = parseInt(lines[index++]); 9 | let lenght = parseInt(lines[index++]); 10 | let costs = lines[index++].split(" ").map(i => parseInt(i)); 11 | let indexes = []; 12 | for(let j = 0; j < lenght - 1; j++) { 13 | for(let k = j + 1; k < lenght; k++) { 14 | if(costs[j] + costs[k] === amount) { 15 | indexes.push(j + 1); 16 | indexes.push(k + 1); 17 | } 18 | } 19 | } 20 | console.log(indexes.join(" ")); 21 | } 22 | }; 23 | 24 | process.stdin.resume(); 25 | process.stdin.setEncoding("ascii"); 26 | 27 | var _input = ""; 28 | process.stdin.on("data", input => _input += input); 29 | process.stdin.on("end", () => processData(_input)); 30 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Implementation/chocolate_feast.js: -------------------------------------------------------------------------------- 1 | function processData(input) { 2 | var lines = input.split('\n'); 3 | for(var i = 1; i < lines.length; i++) { 4 | var amounts = lines[i].split(' ').map(function(item) { return parseInt(item); }); 5 | console.log(chocolates(amounts[0], amounts[1], amounts[2])); 6 | } 7 | } 8 | 9 | function chocolates(amount, price, discount) { 10 | var result = 0; 11 | var bought = parseInt(amount / price); 12 | result += bought; 13 | 14 | var wrappers = bought; 15 | while(wrappers >= discount) { 16 | var freeChoco = parseInt(wrappers / discount); 17 | result += freeChoco; 18 | wrappers = wrappers - freeChoco * discount + freeChoco; 19 | } 20 | return result; 21 | } 22 | process.stdin.resume(); 23 | process.stdin.setEncoding("ascii"); 24 | _input = ""; 25 | process.stdin.on("data", function (input) { 26 | _input += input; 27 | }); 28 | 29 | process.stdin.on("end", function () { 30 | processData(_input); 31 | }); 32 | -------------------------------------------------------------------------------- /leetcode/345_reverse_vowels_of_a_string.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @return {string} 4 | */ 5 | var reverseVowels = function(s) { // "hello" 6 | if(s.length < 2){ return s; } 7 | 8 | var p1 = 0, p2 = s.length - 1; //p1 = 0, p2 = 4 9 | var newStr = s.split(''); // '' ['h', 'e', 'l', 'l', 'o'] 10 | 11 | while(p1 < p2){ 12 | if(isVowel(newStr[p1]) && isVowel(newStr[p2])){ 13 | newStr = swap(newStr, p1, p2); 14 | p1++; 15 | p2--; 16 | }else if(!isVowel(newStr[p1])){ 17 | p1++; 18 | }else if(!isVowel(newStr[p2])){ 19 | p2--; 20 | } 21 | } 22 | 23 | return newStr.join(''); 24 | }; 25 | 26 | function isVowel(char){ 27 | var vowels = { 28 | 'a': true, 29 | 'e': true, 30 | 'i': true, 31 | 'o': true, 32 | 'u': true 33 | }; 34 | char = char.toLowerCase(); 35 | return vowels[char] ? true : false; 36 | } 37 | 38 | function swap(arr, idx1, idx2){ 39 | var temp = arr[idx1]; 40 | arr[idx1] = arr[idx2]; 41 | arr[idx2] = temp; 42 | 43 | return arr; 44 | } 45 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Strings/closest_numbers.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const processData = input => { 4 | let lines = input.split('\n'); 5 | let array = lines[1].split(' ').map(i => parseInt(i)).sort((a, b) => a - b); 6 | let minDiff = 1000000000000000000; 7 | for(let i = 0; i < array.length - 1; i++) { 8 | let diff = array[i + 1] - array[i]; 9 | if(diff < minDiff) { 10 | minDiff = diff; 11 | } 12 | } 13 | let elements = []; 14 | for(let i = 0; i < array.length - 1; i++) { 15 | let diff = array[i + 1] - array[i]; 16 | if(diff == minDiff) { 17 | elements.push(array[i]); 18 | elements.push(array[i + 1]); 19 | } 20 | } 21 | elements = elements.sort((a, b) => a - b); 22 | console.log(elements.join(" ")); 23 | }; 24 | 25 | process.stdin.resume(); 26 | process.stdin.setEncoding("ascii"); 27 | 28 | var _input = ""; 29 | process.stdin.on("data", input => _input += input); 30 | process.stdin.on("end", () => processData(_input)); 31 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Strings/ceasar_cipher.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const processData = input => { 4 | let lines = input.split('\n'); 5 | let text = lines[1]; 6 | let shift = parseInt(lines[2]); 7 | let encrypted = ''; 8 | for(let i = 0; i < text.length; i++) { 9 | if(text.charCodeAt(i) >= 'a'.charCodeAt(0) && text.charCodeAt(i) <= 'z'.charCodeAt(0)) { 10 | encrypted += String.fromCharCode((text.charCodeAt(i) - 'a'.charCodeAt(0) + shift) % 26 + 'a'.charCodeAt(0)) 11 | } else if(text.charCodeAt(i) >= 'A'.charCodeAt(0) && text.charCodeAt(i) <= 'Z'.charCodeAt(0)) { 12 | encrypted += String.fromCharCode((text.charCodeAt(i) - 'A'.charCodeAt(0) + shift) % 26 + 'A'.charCodeAt(0)) 13 | } else { 14 | encrypted += text.charAt(i); 15 | } 16 | } 17 | console.log(encrypted); 18 | }; 19 | 20 | process.stdin.resume(); 21 | process.stdin.setEncoding("ascii"); 22 | 23 | var _input = ""; 24 | process.stdin.on("data", input => _input += input); 25 | process.stdin.on("end", () => processData(_input)); 26 | -------------------------------------------------------------------------------- /Udacity/binary_search.py: -------------------------------------------------------------------------------- 1 | """You're going to write a binary search function. 2 | You should use an iterative approach - meaning 3 | using loops. 4 | Your function should take two inputs: 5 | a Python list to search through, and the value 6 | you're searching for. 7 | Assume the list only has distinct elements, 8 | meaning there are no repeated values, and 9 | elements are in a strictly increasing order. 10 | Return the index of value, or -1 if the value 11 | doesn't exist in the list.""" 12 | 13 | def binary_search(input_array, value): 14 | low = 0 15 | high = len(input_array) -1 16 | 17 | while low <= high: 18 | mid_index = (high + low) / 2 19 | 20 | if input_array[mid_index] == value: 21 | return mid_index 22 | elif value > input_array[mid_index]: 23 | low = mid_index + 1 24 | else: 25 | high = mid_index - 1 26 | 27 | return -1 28 | 29 | test_list = [1,3,9,11,15,19,29] 30 | test_val1 = 25 31 | test_val2 = 15 32 | print binary_search(test_list, test_val1) 33 | print binary_search(test_list, test_val2) 34 | -------------------------------------------------------------------------------- /leetcode/9_palindrome_number.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} x 3 | * @return {boolean} 4 | */ 5 | var isPalindrome = function (x) { 6 | if (x < 0) { 7 | return false; 8 | } 9 | 10 | var div = 1; 11 | 12 | while (parseInt(x / div) >= 10) { 13 | div *= 10; 14 | } 15 | 16 | var left, right; 17 | 18 | while (div > 1) { 19 | left = parseInt(x / div); 20 | right = x % 10; 21 | if (left !== right) { 22 | return false; 23 | } 24 | 25 | x = x % div; 26 | x = parseInt(x / 10); 27 | div /= 100; 28 | } 29 | 30 | return true; 31 | }; 32 | 33 | // a slightly different approach (easier to read) 34 | const isPalindrome2 = (number) => { 35 | if (number < 0) { 36 | return false; 37 | } 38 | 39 | if (number < 10) { 40 | return true; 41 | } 42 | 43 | let reverse = 0; 44 | let temp = number; 45 | while (temp !== 0) { 46 | const remainder = temp % 10; 47 | reverse = reverse * 10 + remainder; 48 | temp = Math.floor(temp / 10); 49 | } 50 | 51 | if (number === reverse) { 52 | return true; 53 | } 54 | 55 | return false; 56 | }; 57 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Implementation/angry_professor.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const processData = input => { 4 | const lines = input.split('\n'); 5 | const tests = parseInt(lines[0]); 6 | let actualLine = 1; 7 | for(let i = 0; i < tests; i++) { 8 | const studentsAndCancelation = lines[actualLine++].split(' ').map(i => parseInt(i)); 9 | const cancelation = studentsAndCancelation[1]; 10 | const arrivals = lines[actualLine++].split(' ').map(i => parseInt(i)); 11 | const beforeClass = studentsBeforeClass(arrivals); 12 | const canceled = cancelation > beforeClass ? "YES" : "NO"; 13 | console.log(canceled); 14 | } 15 | }; 16 | 17 | const studentsBeforeClass = (arrivals) => { 18 | let result = 0; 19 | for(let i = 0; i < arrivals.length; i++) { 20 | if(arrivals[i] <= 0) { 21 | result++; 22 | } 23 | } 24 | return result; 25 | }; 26 | 27 | process.stdin.resume(); 28 | process.stdin.setEncoding("ascii"); 29 | 30 | var _input = ""; 31 | process.stdin.on("data", input => _input += input); 32 | process.stdin.on("end", () => processData(_input)); 33 | -------------------------------------------------------------------------------- /leetcode/234_palindrome_linked_list.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for singly-linked list. 3 | * function ListNode(val) { 4 | * this.val = val; 5 | * this.next = null; 6 | * } 7 | */ 8 | /** 9 | * @param {ListNode} head 10 | * @return {boolean} 11 | */ 12 | var isPalindrome = function(head) { 13 | if(head === null || head.next === null){ 14 | return true; 15 | } 16 | 17 | var slow = head; 18 | var fast = head; 19 | 20 | while(fast.next && fast.next.next){ 21 | slow = slow.next; 22 | fast = fast.next.next; 23 | } 24 | 25 | var secondHead = slow.next; 26 | slow.next = null; 27 | 28 | var p1 = secondHead; 29 | var p2 = secondHead.next; 30 | 31 | while(p1 && p2){ 32 | var temp = p2.next; 33 | p2.next = p1; 34 | p1 = p2; 35 | p2 = temp; 36 | } 37 | 38 | secondHead.next = null; 39 | 40 | p = p1; 41 | q = head; 42 | 43 | while(p && q){ 44 | if(p.val !== q.val){ 45 | return false; 46 | } 47 | 48 | p = p.next; 49 | q = q.next; 50 | } 51 | 52 | return true; 53 | } 54 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Strings/gemstones.js: -------------------------------------------------------------------------------- 1 | function processData(input) { 2 | var lines = input.split('\n'); 3 | var first = lines[1].split(''); 4 | for(var i = 2; i < lines.length; i++) { 5 | first = intersect(first, lines[i].split('')); 6 | } 7 | console.log(first.length) 8 | } 9 | 10 | function intersect(arr1, arr2) { 11 | var unique1 = arr1.distinct(); 12 | var unique2 = arr2.distinct(); 13 | return unique1.distinct().filter(function(s) { 14 | return unique2.distinct().indexOf(s) !== -1 15 | }); 16 | } 17 | 18 | Array.prototype.distinct = function() { 19 | var hash = {}; 20 | var a = []; 21 | for(var i = 0; i < this.length; i++) { 22 | if(hash.hasOwnProperty(this[i])) { 23 | continue; 24 | } 25 | hash[this[i]] = true; 26 | a.push(this[i]); 27 | } 28 | return a; 29 | }; 30 | 31 | process.stdin.resume(); 32 | process.stdin.setEncoding("ascii"); 33 | _input = ""; 34 | process.stdin.on("data", function (input) { 35 | _input += input; 36 | }); 37 | 38 | process.stdin.on("end", function () { 39 | processData(_input); 40 | }); 41 | -------------------------------------------------------------------------------- /KhanAcademy/Quick Sort/quickSortI.js: -------------------------------------------------------------------------------- 1 | // This function partitions given array and returns 2 | // the index of the pivot. 3 | var partition=function(array, p, r){ 4 | // This code has been purposefully obfuscated, 5 | // as you will implement it yourself in next challenge 6 | var e=array,t=p,n=r; 7 | var r=function(e,t,n){var r=e[t];e[t]=e[n];e[n]=r;}; //sort function 8 | var i=t; 9 | for(var s=t;s { 19 | const abbr = this.getAbbr(word); 20 | 21 | if (!this.map.has(abbr)) { 22 | this.map.set(abbr, word); 23 | } else { 24 | if (this.map.get(abbr) !== word) { 25 | this.map.set(abbr, ''); 26 | } 27 | } 28 | }); 29 | }; 30 | 31 | 32 | ValidWordAbbr.prototype.isUnique = function(word) { 33 | const abbr = this.getAbbr(word); 34 | 35 | return !this.map.has(abbr) || this.map.get(abbr) === word; 36 | }; 37 | 38 | /** 39 | * Your ValidWordAbbr object will be instantiated and called as such: 40 | * var vwa = new ValidWordAbbr(dictionary); 41 | * vwa.isUnique("word"); 42 | * vwa.isUnique("anotherWord"); 43 | */ 44 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Implementation/modified_kaprekar_numbers.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const processData = input => { 4 | const lines = input.split('\n').map(i => parseInt(i)); 5 | const lower = lines[0]; 6 | const upper = lines[1]; 7 | const kaprekarNums = []; 8 | for(let i = lower; i <= upper; i++) { 9 | if(isKaprekar(i)) { 10 | kaprekarNums.push(i); 11 | } 12 | } 13 | if(kaprekarNums.length > 0) { 14 | console.log(kaprekarNums.join(" ")); 15 | } else { 16 | console.log("INVALID RANGE"); 17 | } 18 | }; 19 | 20 | const isKaprekar = (num) => { 21 | const square = parseInt(Math.pow(num, 2)).toString(); 22 | if(square.length > 1) { 23 | const l = parseInt(square.substring(0, square.length / 2)); 24 | const r = parseInt(square.substring(square.length / 2)); 25 | return (l + r) === num; 26 | } else { 27 | return parseInt(square) === num; 28 | } 29 | } 30 | 31 | process.stdin.resume(); 32 | process.stdin.setEncoding("ascii"); 33 | 34 | var _input = ""; 35 | process.stdin.on("data", input => _input += input); 36 | process.stdin.on("end", () => processData(_input)); 37 | -------------------------------------------------------------------------------- /leetcode/110_balanced_binary_tree.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * function TreeNode(val) { 4 | * this.val = val; 5 | * this.left = this.right = null; 6 | * } 7 | */ 8 | /** 9 | * @param {TreeNode} root 10 | * @return {boolean} 11 | */ 12 | var maxHeight = function(node){ 13 | if(node === null){ 14 | return 0; 15 | } 16 | return 1 + Math.max(maxHeight(node.left), maxHeight(node.right)); 17 | } 18 | 19 | var minHeight = function(node){ 20 | if(node === null){ 21 | return 0; 22 | } 23 | return 1 + Math.min(minHeight(node.left), minHeight(node.right)); 24 | } 25 | 26 | 27 | var height = function(node){ 28 | if(node === null){ 29 | return 0; 30 | } 31 | return 1 + Math.max(height(node.left), height(node.right)); 32 | } 33 | 34 | var isBalanced = function(root) { 35 | if(root === null){ 36 | return true; 37 | } 38 | 39 | var lh = height(root.left); 40 | var rh = height(root.right); 41 | 42 | var diff = Math.abs(lh - rh); 43 | 44 | if(diff <= 1){ 45 | return isBalanced(root.left) && isBalanced(root.right); 46 | } else { 47 | return false; 48 | } 49 | }; 50 | -------------------------------------------------------------------------------- /KhanAcademy/Merge Sort/mergeSort.js: -------------------------------------------------------------------------------- 1 | // Takes in an array that has two sorted subarrays, 2 | // from [p..q] and [q+1..r], and merges the array 3 | var merge = function(array, p, q, r) { 4 | // This code has been purposefully obfuscated, 5 | // as you'll write it yourself in next challenge. 6 | var a=[],b=[],c=p,d,e;for(d=0;c<=q;d++,c++){a[d]=array[c];}for(e=0;c<=r;e++,c++){b[e]=array[c];}c=p;for(e=d=0;d p) { 13 | var middle = Math.floor( (p+r)/2 ); // Arithmetic mean 14 | mergeSort(array, p, middle); 15 | mergeSort(array, middle+1, r); 16 | merge(array, p, middle, r); 17 | } 18 | }; 19 | 20 | // var array = [14, 7, 3, 12, 9, 11, 6, 2]; 21 | // mergeSort(array, 0, array.length-1); 22 | // println("Array after sorting: " + array); 23 | // Program.assertEqual(array, [2, 3, 6, 7, 9, 11, 12, 14]); 24 | 25 | // var array = [10, 2, 3, -2, 22, 15, 4]; 26 | // mergeSort(array, 0, array.length-1); 27 | // Program.assertEqual(array, [-2, 2, 3, 4, 10, 15, 22]); 28 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Dynamic Programming/the_maximum_subarray.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const _ = require('lodash'); 4 | 5 | const processData = input => { 6 | const lines = input.split('\n'); 7 | let index = 0; 8 | const tests = parseInt(lines[index++]); 9 | for(let i = 0; i < tests; i++) { 10 | const elementCount = lines[index++]; 11 | const arr = lines[index++].split(' ').map(el => parseInt(el)); 12 | const contiguousSum = kadane(arr); 13 | const positiveNumbers = arr.filter(el => el > 0); 14 | let nonContiguousSum; 15 | if(positiveNumbers.length === 0) { 16 | nonContiguousSum = _.max(arr); 17 | } else { 18 | nonContiguousSum = _.sum(positiveNumbers); 19 | } 20 | console.log(contiguousSum + ' ' + nonContiguousSum); 21 | } 22 | }; 23 | 24 | const kadane = arr => { 25 | let maxSoFar = arr[0]; 26 | let maxEndings = arr[0]; 27 | arr.slice(1, arr.length).forEach(el => { 28 | maxEndings = Math.max(el, maxEndings + el); 29 | maxSoFar = Math.max(maxSoFar, maxEndings); 30 | }); 31 | return maxSoFar; 32 | }; 33 | 34 | process.stdin.resume(); 35 | process.stdin.setEncoding("ascii"); 36 | 37 | let _input = ""; 38 | process.stdin.on("data", input => _input += input); 39 | process.stdin.on("end", () => processData(_input)); 40 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Strings/game_of_thrones_I.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | let isPalindrome = (length, charMap) => { 4 | let isPalindrome = true; 5 | if(length % 2 == 0) { 6 | for(let prop in charMap) { 7 | if(charMap.hasOwnProperty(prop) && charMap[prop] % 2 !== 0) { 8 | isPalindrome = false; 9 | break; 10 | } 11 | } 12 | } 13 | if(length % 2 != 0) { 14 | let oddCount = 0; 15 | for(let prop in charMap) { 16 | if(charMap[prop] % 2 !== 0) { 17 | oddCount++; 18 | } 19 | } 20 | isPalindrome = oddCount === 1; 21 | } 22 | if(isPalindrome) { 23 | return "YES"; 24 | } else { 25 | return "NO"; 26 | } 27 | }; 28 | 29 | const processData = input => { 30 | let charMap = {}; 31 | for(let i = 0; i < input.length; i++) { 32 | let count = charMap[input[i]]; 33 | if(count) { 34 | charMap[input[i]] = count + 1; 35 | } else { 36 | charMap[input[i]] = 1; 37 | } 38 | } 39 | console.log(isPalindrome(input.length, charMap)); 40 | }; 41 | 42 | process.stdin.resume(); 43 | process.stdin.setEncoding("ascii"); 44 | 45 | var _input = ""; 46 | process.stdin.on("data", input => _input += input); 47 | process.stdin.on("end", () => processData(_input)); 48 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Search/missing_numbers.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const processData = input => { 4 | let lines = input.split('\n'); 5 | let array1 = lines[1].split(' ').map(i => parseInt(i)); 6 | let array2 = lines[3].split(' ').map(i => parseInt(i)); 7 | let numHash1 = new Map(); 8 | let numHash2 = new Map(); 9 | for(let i = 0; i < array1.length; i++) { 10 | let count = numHash1.get(array1[i]); 11 | if(!count) { 12 | numHash1.set(array1[i], 1); 13 | } else { 14 | numHash1.set(array1[i], count + 1); 15 | } 16 | } 17 | for(let i = 0; i < array2.length; i++) { 18 | let count = numHash2.get(array2[i]); 19 | if(!count) { 20 | numHash2.set(array2[i], 1); 21 | } else { 22 | numHash2.set(array2[i], count + 1); 23 | } 24 | } 25 | let missingNumbers = []; 26 | for(let key of numHash2.keys()) { 27 | let countB = numHash2.get(key); 28 | if(!numHash1.get(key) || countB > numHash1.get(key)) { 29 | missingNumbers.push(key); 30 | } 31 | } 32 | 33 | console.log(missingNumbers.sort((a, b) => a - b).join(" ")); 34 | }; 35 | 36 | process.stdin.resume(); 37 | process.stdin.setEncoding("ascii"); 38 | 39 | var _input = ""; 40 | process.stdin.on("data", input => _input += input); 41 | process.stdin.on("end", () => processData(_input)); 42 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Implementation/cavity_map.js: -------------------------------------------------------------------------------- 1 | function processData(input) { 2 | var lines = input.split('\n'); 3 | var n = parseInt(lines[0]); 4 | var result = lines[1] + "\n"; 5 | for(var i = 2; i < lines.length - 1; i++) { 6 | result += lines[i][0]; 7 | for(var j = 1; j < lines[i].length - 1; j++) { 8 | if(isCavity(lines, i, j)) { 9 | result += 'X' 10 | } else { 11 | result += lines[i][j]; 12 | } 13 | } 14 | result += lines[i][n - 1]; 15 | result += "\n"; 16 | } 17 | if(n > 1) { 18 | result += lines[lines.length - 1]; 19 | } 20 | console.log(result); 21 | } 22 | 23 | function isCavity(map, i, j) { 24 | var depth = parseInt(map[i][j], 10); 25 | if (depth <= parseInt(map[i - 1][j], 10)) { 26 | return false; 27 | } 28 | if (depth <= parseInt(map[i][j - 1], 10)) { 29 | return false; 30 | } 31 | if (depth <= parseInt(map[i + 1][j], 10)) { 32 | return false; 33 | } 34 | if (depth <= parseInt(map[i][j + 1], 10)) { 35 | return false; 36 | } 37 | return true; 38 | } 39 | 40 | process.stdin.resume(); 41 | process.stdin.setEncoding("ascii"); 42 | _input = ""; 43 | process.stdin.on("data", function (input) { 44 | _input += input; 45 | }); 46 | 47 | process.stdin.on("end", function () { 48 | processData(_input); 49 | }); 50 | -------------------------------------------------------------------------------- /Udacity/implement_hash.py: -------------------------------------------------------------------------------- 1 | """Write a HashTable class that stores strings 2 | in a hash table, where keys are calculated 3 | using the first two letters of the string.""" 4 | 5 | class HashTable(object): 6 | def __init__(self): 7 | self.table = [None]*10000 8 | 9 | def store(self, string): 10 | hv = self.calculate_hash_value(string) 11 | if hv != -1: 12 | if self.table[hv] != None: 13 | self.table[hv].append(string) 14 | else: 15 | self.table[hv] = [string] 16 | 17 | def lookup(self, string): 18 | hv = self.calculate_hash_value(string) 19 | if hv != -1: 20 | if self.table[hv] != None: 21 | if string in self.table[hv]: 22 | return hv 23 | return -1 24 | 25 | def calculate_hash_value(self, string): 26 | value = ord(string[0])*100 + ord(string[1]) 27 | return value 28 | # Setup 29 | hash_table = HashTable() 30 | 31 | # Test calculate_hash_value 32 | # Should be 8568 33 | print hash_table.calculate_hash_value('UDACITY') 34 | 35 | # Test lookup edge case 36 | # Should be -1 37 | print hash_table.lookup('UDACITY') 38 | 39 | # Test store 40 | hash_table.store('UDACITY') 41 | # Should be 8568 42 | print hash_table.lookup('UDACITY') 43 | 44 | # Test store edge case 45 | hash_table.store('UDACIOUS') 46 | # Should be 8568 47 | print hash_table.lookup('UDACIOUS') 48 | -------------------------------------------------------------------------------- /HackerRank/DataStructures/sparse_arrays.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | process.stdin.resume(); 4 | process.stdin.setEncoding('ascii'); 5 | 6 | var input_stdin = ""; 7 | var input_stdin_array = ""; 8 | var input_currentline = 0; 9 | 10 | process.stdin.on('data', function (data) { 11 | input_stdin += data; 12 | }); 13 | 14 | process.stdin.on('end', function () { 15 | input_stdin_array = input_stdin.split("\n"); 16 | main(); 17 | }); 18 | 19 | function readLine() { 20 | return input_stdin_array[input_currentline++]; 21 | } 22 | 23 | function increase_node_count(node, c) { 24 | if(!node[c]) 25 | node[c] = {}; 26 | if(!node[c].count) 27 | node[c].count = 0; 28 | node[c].count++; 29 | } 30 | 31 | function add_word(w, node) { 32 | if(w.length === 0) { 33 | return; 34 | } 35 | else if(w.length === 1) { 36 | increase_node_count(node, w[0]); 37 | } 38 | else if(w.length > 1) { 39 | if(!node[w[0]]) 40 | node[w[0]] = {}; 41 | add_word(w.slice(1), node[w[0]]); 42 | } 43 | } 44 | 45 | function query(w, node) { 46 | if(!node || w.length === 0 || !node[w[0]]) 47 | return 0; 48 | if(w.length === 1) { 49 | if(node[w[0]].count) 50 | return node[w[0]].count; 51 | else 52 | return 0; 53 | } 54 | return query(w.slice(1), node[w[0]]); 55 | } 56 | 57 | 58 | function main() { 59 | let n = parseInt(readLine()); 60 | let trie = {}; 61 | for(let i = 0; i < n; i++) { 62 | let w = readLine(); 63 | add_word(w, trie); 64 | } 65 | let q = parseInt(readLine()); 66 | for(let i = 0; i < q; i++) { 67 | let w = readLine(); 68 | console.log(query(w, trie)); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /KhanAcademy/Quick Sort/quickSortII.js: -------------------------------------------------------------------------------- 1 | // Swaps two items in an array, changing the original array 2 | var swap = function(array, firstIndex, secondIndex) { 3 | var temp = array[firstIndex]; 4 | array[firstIndex] = array[secondIndex]; 5 | array[secondIndex] = temp; 6 | }; 7 | 8 | var partition = function(array, p, r) { 9 | var q = p; 10 | for (var j = p; j < r; j++) { 11 | if (array[j] <= array[r]){ 12 | swap(array, j, q); 13 | q++; 14 | } 15 | } 16 | // Compare array[j] with array[r], for j = p, p+1,...r-1 17 | // maintaining that: 18 | // array[p..q-1] are values known to be <= to array[r] 19 | // array[q..j-1] are values known to be > array[r] 20 | // array[j..r-1] haven't been compared with array[r] 21 | // If array[j] > array[r], just increment j. 22 | // If array[j] <= array[r], swap array[j] with array[q], 23 | // increment q, and increment j. 24 | // Once all elements in array[p..r-1] 25 | // have been compared with array[r], 26 | // swap array[r] with array[q], and return q. 27 | swap(array, j, q); 28 | return q; 29 | }; 30 | 31 | var array = [9, 7, 5, 11, 12, 2, 14, 3, 10, 4, 6]; 32 | var q = partition(array, 0, array.length-1); 33 | println("Array after partitioning: " + array); 34 | Program.assertEqual(q, 4); 35 | Program.assertEqual(array, [5, 2, 3, 4, 6, 7, 14, 9, 10, 11, 12]); 36 | 37 | var array = [9, 7, 5, 11, 13, 2, 14, 3, 10, 4, 6]; 38 | var q = partition(array, 0, array.length-1); 39 | println("Array after partitioning: " + array); 40 | Program.assertEqual(q, 4); 41 | Program.assertEqual(array, [5, 2, 3, 4, 6, 7, 14, 9, 10, 11, 13]); 42 | -------------------------------------------------------------------------------- /leetcode/reverseInPlace.js: -------------------------------------------------------------------------------- 1 | // naive solution 2 | // function reverseWords(str) { 3 | // var newStr = str.split(' '); 4 | // var length = str.length; 5 | // for (var i = newStr.length - 1; i >= 0; i--){ 6 | // newStr.push(newStr[i]); 7 | // } 8 | // newStr = newStr.join(' ').slice(length); 9 | // } 10 | 11 | // in place I 12 | // var reverseWords = function(words) { 13 | // words = words.reverse(); 14 | 15 | // var start = 0; 16 | // var val; 17 | // for (var i = 0; i < words.length; i ++) { 18 | // val = words[i]; 19 | // if (val === ' ') { 20 | // reverseWord(words, start, i - 1); 21 | // start = i + 1; 22 | // } 23 | // } 24 | // reverseWord(words, start, i - 1); 25 | // } 26 | 27 | // function reverseWord(arr, start, end) { 28 | // if (start >= end || end >= arr.length) return; 29 | 30 | // while (start < end) { 31 | // tmp = arr[start]; 32 | // arr[start] = arr[end]; 33 | // arr[end] = tmp; 34 | // start ++; 35 | // end --; 36 | // } 37 | // } 38 | 39 | // in place II 40 | function reverseWords(str) { 41 | var index = [0]; 42 | var idx = 0; 43 | var length = str.length; 44 | while((idx = str.indexOf(' ', idx + 1)) > 0) { 45 | index.push(idx); 46 | } 47 | 48 | index.push(length); 49 | var p1 = index.length - 1; 50 | var p2 = p1 - 1; 51 | while (p2 >= 0){ 52 | if (p2 === 0){ 53 | str = str + ' ' + str.slice(index[p2], index[p1]); 54 | } else { 55 | str = str + str.slice(index[p2], index[p1]); 56 | } 57 | p1--; 58 | p2--; 59 | } 60 | str = str.slice(length).trim(); 61 | return str; 62 | } 63 | 64 | console.log(reverseWords("the sky is blue")); 65 | -------------------------------------------------------------------------------- /HackerRank/Algorithm/Graph Theory/event_tree.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const processData = input => { 4 | let lines = input.split('\n'); 5 | let counts = lines[0].split(" ").map(i => parseInt(i)); 6 | let vertices = counts[0]; 7 | let edges = counts[1]; 8 | let edgesDesc = lines.slice(1); 9 | 10 | let tree = new Array(vertices + 1, 0); 11 | let map = {}; 12 | 13 | for(let i = 0; i < edges; i++) { 14 | let splits = edgesDesc[i].split(' ').map(i => parseInt(i)); 15 | let connected = splits[0]; 16 | let parent = splits[1]; 17 | tree[connected] = parent; 18 | 19 | if(!map[parent]){ 20 | map[parent] = 1; 21 | } 22 | if(!map[connected]) { 23 | map[connected] = 1; 24 | } 25 | 26 | let count = map[parent]; 27 | map[parent] = ++count; 28 | } 29 | 30 | let result = 0; 31 | for(let nodeIndex = tree.length - 1; nodeIndex > 1; nodeIndex--) { 32 | if(map[nodeIndex] % 2 === 0) { 33 | let hasEven = false; 34 | for(let i = tree.length - 1; i > 1; i--) { 35 | if(tree[i] == nodeIndex) { 36 | let node = i; 37 | if(map[node] % 2 == 0) { 38 | hasEven = true; 39 | } 40 | } 41 | } 42 | if(!hasEven) { 43 | result++; 44 | let parent = tree[nodeIndex]; 45 | tree[nodeIndex] = 0; 46 | let count = map[parent]; 47 | map[parent] = --count; 48 | } 49 | } 50 | } 51 | console.log(result); 52 | }; 53 | 54 | process.stdin.resume(); 55 | process.stdin.setEncoding("ascii"); 56 | 57 | var _input = ""; 58 | process.stdin.on("data", input => _input += input); 59 | process.stdin.on("end", () => processData(_input)); 60 | -------------------------------------------------------------------------------- /KhanAcademy/Merge Sort/mergeSortLinear.js: -------------------------------------------------------------------------------- 1 | // Takes in an array that has two sorted subarrays, 2 | // from [p..q] and [q+1..r], and merges the array 3 | var merge = function(array, p, q, r) { 4 | var lowHalf = []; 5 | var highHalf = []; 6 | 7 | var k = p; 8 | var i; 9 | var j; 10 | for (i = 0; k <= q; i++, k++) { 11 | lowHalf[i] = array[k]; 12 | } 13 | for (j = 0; k <= r; j++, k++) { 14 | highHalf[j] = array[k]; 15 | } 16 | 17 | k = p; 18 | i = 0; 19 | j = 0; 20 | 21 | // Repeatedly compare the lowest untaken element in 22 | // lowHalf with the lowest untaken element in highHalf 23 | // and copy the lower of the two back into array 24 | while(i < lowHalf.length && j < highHalf.length) { 25 | if(lowHalf[i] < highHalf[j]) { 26 | array[k] = lowHalf[i]; 27 | i++; 28 | } else { 29 | array[k] = highHalf[j]; 30 | j++; 31 | } 32 | k++; 33 | } 34 | 35 | // Once one of lowHalf and highHalf has been fully copied 36 | // back into array, copy the remaining elements from the 37 | // other temporary array back into the array 38 | while(j < highHalf.length) { 39 | array[k] = highHalf[j]; 40 | j++; 41 | k++; 42 | } 43 | while(i < lowHalf.length) { 44 | array[k] = lowHalf[i]; 45 | i++; 46 | k++; 47 | } 48 | }; 49 | 50 | // var array = [3, 7, 12, 14, 2, 6, 9, 11]; 51 | // merge(array, 0, 52 | // Math.floor((0 + array.length-1) / 2), 53 | // array.length-1); 54 | // println("Array after merging: " + array); 55 | // Program.assertEqual(array, [2, 3, 6, 7, 9, 11, 12, 14]); 56 | 57 | // var array = [2,5,1,4,6,20]; 58 | // merge(array, 0, 59 | // Math.floor((0 + array.length-1) / 2), 60 | // array.length-1); 61 | // println("Array after merging: " + array); 62 | // Program.assertEqual(array, [2,4,5,1,6,20]); 63 | -------------------------------------------------------------------------------- /KhanAcademy/Selection Sort/selectionSortVisualizer.js: -------------------------------------------------------------------------------- 1 | // space between arrays on each line 2 | var swapNumber = 1; 3 | 4 | // Display line and array 5 | var drawLine = function(array, horizontalPos, verticalPos) { 6 | line(horizontalPos, 12 + 50*swapNumber, verticalPos, 50*(swapNumber + 1)); 7 | }; 8 | 9 | var displayArray = function(array, horizontal, vertical) { 10 | textFont(createFont("monospace"), 12); 11 | fill(0,0,0); 12 | text(array, horizontal, vertical); 13 | }; 14 | 15 | 16 | // Selection Sort 17 | var swap = function(array, secondIndex, firstIndex) { 18 | if(swapNumber < array.length) { 19 | drawLine(array, 15 + firstIndex * 21, 15 + secondIndex * 21); 20 | } 21 | displayArray(array, 10, 10 + 50*swapNumber); 22 | var temp = array[firstIndex]; 23 | array[firstIndex] = array[secondIndex]; 24 | array[secondIndex] = temp; 25 | swapNumber++; 26 | }; 27 | var indexOfMinimum = function(array, startIndex) { 28 | 29 | var minValue = array[startIndex]; 30 | var minIndex = startIndex; 31 | 32 | for(var i = minIndex + 1; i < array.length; i++) { 33 | if(array[i] < minValue) { 34 | minIndex = i; 35 | minValue = array[i]; 36 | } 37 | } 38 | return minIndex; 39 | }; 40 | var selectionSort = function(array) { 41 | var min; 42 | for (var i = 0; i < array.length; i++) { 43 | min = indexOfMinimum(array, i); 44 | swap(array, i, min); 45 | } 46 | swapNumber = 1; //keep it on same row for each iteration 47 | }; 48 | 49 | // Testing Data 50 | var array1 = [40, 23, -1, 0]; 51 | selectionSort(array1); 52 | 53 | var array2 = [40,30,20,10]; 54 | translate(100, 0); // remaps the (100,0) position on the canvas. 55 | selectionSort(array2); 56 | 57 | var array3 = [10,20, 30, 50]; 58 | translate(100, 0); 59 | selectionSort(array3); 60 | 61 | var array4 = [13, 2, 10, 90]; 62 | translate(100, 0); 63 | selectionSort(array4); 64 | -------------------------------------------------------------------------------- /InterviewCake/isBST.js: -------------------------------------------------------------------------------- 1 | function TreeNode(value){ 2 | this.value = value; 3 | this.left = null; 4 | this.right = null; 5 | 6 | } 7 | 8 | function BinaryTree() { 9 | this.root = null; 10 | this.size = 0; 11 | } 12 | 13 | 14 | BinaryTree.prototype.insert = function(insertVal){ 15 | // if the tree is emty 16 | if (this.size === 0){ 17 | this.root = new TreeNode(insertVal); 18 | this.size++; 19 | return; 20 | } else { 21 | 22 | // if the length is more than 0 23 | // if the value adding is smaller than current 24 | var traverse = function(currNode){ 25 | 26 | // right side 27 | if (insertVal > currNode.value){ 28 | if (currNode.right === null){ 29 | currNode.right = new TreeNode(insertVal); 30 | return; 31 | } else { 32 | traverse(currNode.right); 33 | } 34 | 35 | // left side 36 | } else { 37 | if (currNode.left === null){ 38 | currNode.left = new TreeNode(insertVal); 39 | return; 40 | } else { 41 | traverse(currNode.left); 42 | } 43 | } 44 | } 45 | traverse(this.root); 46 | this.size++; 47 | } 48 | } 49 | 50 | 51 | BinaryTree.prototype.isBST = function(){ 52 | var check = true; 53 | // length is 0 54 | if (this.size === 0){ 55 | check = false; 56 | return check; 57 | 58 | // length is 1 59 | } else if (this.size === 1){ 60 | return check; 61 | 62 | // length bigger than 1 63 | } else { 64 | var traverse = function(currNode){ 65 | // best case 66 | if (currNode.left === null || currNode.right === null){ 67 | return; 68 | } 69 | 70 | // recursion case 71 | if (currNode.left.value > currNode.value || currNode.right.value < currNode.value){ 72 | check = false; 73 | return; 74 | } 75 | traverse(currNode.left); 76 | traverse(currNode.right); 77 | 78 | } 79 | traverse(this.root); 80 | } 81 | 82 | return check; 83 | } 84 | 85 | 86 | // Test Data [25, 15, 50, 10, 22, 35, 70] 87 | 88 | var bt = new BinaryTree(); 89 | bt.insert(25); 90 | bt.insert(15); 91 | bt.insert(26); 92 | bt.insert(10); 93 | bt.insert(22); 94 | bt.insert(35); 95 | bt.insert(5); 96 | 97 | console.log(bt); 98 | console.log(bt.isBST()); 99 | -------------------------------------------------------------------------------- /Sort/Basic Sorts/basic_sorts.py: -------------------------------------------------------------------------------- 1 | # /********************************************************************** 2 | # * Homework III * 3 | # * * 4 | # * Problem: Insertion Sort * 5 | # * * 6 | # * Prompt: Given an unsorted array of numbers, * 7 | # * return a sorted array using insertion sort. * 8 | # * * 9 | # * Input: An unsorted array * 10 | # * Output: A sorted array * 11 | # * * 12 | # * Example: input = [3,9,1,4,7] , output = [1,3,4,7,9] * 13 | # * * 14 | # * What are the time and auxilliary space complexity? * 15 | # * * 16 | # **********************************************************************/ 17 | 18 | # /********************************************************** 19 | # * * 20 | # * Problem: Selection Sort * 21 | # * * 22 | # * Prompt: Given an unsorted array of numbers, * 23 | # * return a sorted array using insertion sort. * 24 | # * * 25 | # * Input: An unsorted array * 26 | # * Output: A sorted array * 27 | # * * 28 | # * Example: input = [8,3,2,10] output = [2,3,8,10] * 29 | # * * 30 | # * What are the time and auxilliary space complexity? * 31 | # * What is the best case time complexity? * 32 | # * * 33 | # **********************************************************/ 34 | 35 | # /********************************************************** 36 | # * * 37 | # * Problem: Bubble Sort * 38 | # * * 39 | # * Prompt: Given an unsorted array of numbers, * 40 | # * return a sorted array using bubble sort. * 41 | # * * 42 | # * Input: An unsorted array * 43 | # * Output: A sorted array * 44 | # * * 45 | # * Example: input = [8,3,2,10] output = [2,3,8,10] * 46 | # * * 47 | # * What are the time and auxilliary space complexity? * 48 | # * * 49 | # **********************************************************/ 50 | 51 | def insertionSort(input): 52 | for index in range(1,len(input)): 53 | 54 | currentvalue = input[index] 55 | position = index 56 | 57 | while position>0 and input[position-1]>currentvalue: 58 | input[position]=input[position-1] 59 | position = position-1 60 | 61 | input[position]=currentvalue 62 | 63 | def selectionSort(input): 64 | for nums in range(len(input)-1,0,-1): 65 | positionOfMax=0 66 | for location in range(1,nums+1): 67 | if input[location]>input[positionOfMax]: 68 | positionOfMax = location 69 | 70 | temp = input[nums] 71 | input[nums] = input[positionOfMax] 72 | input[positionOfMax] = temp 73 | 74 | def bubbleSort(input): 75 | for num in range(len(input)-1,0,-1): 76 | for i in range(num): 77 | if input[i]>input[i+1]: 78 | temp = input[i] 79 | input[i] = input[i+1] 80 | input[i+1] = temp 81 | 82 | -------------------------------------------------------------------------------- /Data Structures/Linked List/linked_list.py: -------------------------------------------------------------------------------- 1 | # /********************************************************************************** 2 | # * Homework IV * 3 | # * * 4 | # * Problem: Linked List * 5 | # * * 6 | # * Prompt: Create a Linked List class/constructor. * 7 | # * Name it LinkedList (js) or Linked_List(rb/py). * 8 | # * * 9 | # * Part 1: Create a node class for your LinkedList. * 10 | # * Your node class will take an integer value and output * 11 | # * and output and object with the following properties: * 12 | # * * 13 | # * node.value: input value * 14 | # * node.next: a pointer to the next value (initiall null) * 15 | # * * 16 | # * Example: { value: 1, next: null } * 17 | # * * 18 | # * Part 2: Create the LinkedList class. * 19 | # * It should contain the following properties: * 20 | # * * 21 | # * head: pointer to the head node * 22 | # * tail: pointer to the tail node * 23 | # * length: number of nodes in the linked list * 24 | # * * 25 | # * The LinkedList should also contain the following properties * 26 | # * * 27 | # * append: function that adds a node to the tail * 28 | # * * 29 | # * insert: function that takes in two values, one to be inserted * 30 | # * and one to search. It searches the list for the * 31 | # * search value, and if found, adds a new node with the * 32 | # * insert value after the node with the search value. * 33 | # * * 34 | # * delete: function that removes a node at a specified location, * 35 | # * with a default action of deleting the head * 36 | # * * 37 | # * contains: function that checks to see if a value is contained * 38 | # * in the list * 39 | # * * 40 | # * Input: N/A * 41 | # * Output: A LinkedList instance * 42 | # * * 43 | # * What are the time and auxilliary space complexities of the various methods? * 44 | # * Append: T: S: * 45 | # * Insert: * 46 | # * Delete: * 47 | # * Contains: * 48 | # **********************************************************************************/ 49 | 50 | class Node: 51 | def __init__(self, data = 0): 52 | self.value = data 53 | self.next = None 54 | 55 | class Linked_List: 56 | def __init__(self): 57 | self.head = None 58 | self.tail = None 59 | self.length = 0 60 | 61 | def append(self, val=None): 62 | if (self.length == 0): 63 | self.head = new Linked_List(val) 64 | self.tail = self.head 65 | else: 66 | self.tail = new Linked_List(val) 67 | self.tail = self.tail.next 68 | 69 | self.length += 1 70 | 71 | def insert(self, insertVal=None, searchVal=None): 72 | work = self.head 73 | 74 | while (work.next != None): 75 | if work.value == searchVal: 76 | reference = work.next 77 | work.next = new Linked_List(insertVal) 78 | work.next.next = reference 79 | 80 | if reference == null: 81 | self.tail = work.next 82 | 83 | self.length += 1 84 | return 85 | 86 | def delete(self, loc=None): 87 | # 1) When there is one element in linked list 88 | if loc == 0 && self.length == 0: 89 | self.head = None 90 | self.tail = None 91 | self.length -= 1 92 | return 93 | else: 94 | # 2) when there are more than one but we are removing the first element 95 | self.head = self.head.next 96 | self.length -= 1 97 | return 98 | 99 | work = self.head 100 | counter = 0 101 | while work.next != None: 102 | # 3) when we are removing the last element 103 | if counter == (loc - 1) && work.next != None && work.next = self.tail: 104 | work.next = work.next.next 105 | self.tail = work 106 | self.length -= 1 107 | return 108 | else if counter == (loc - 1) && work.next != None: 109 | # 4) when removing any element but head or tail 110 | work.next = work.next.next 111 | self.length -= 1 112 | return 113 | 114 | work = work.next 115 | counter += 1 116 | 117 | print('The location ' + loc + ' is out of the range') 118 | 119 | def contains(self, searchVal=None): 120 | work = self.head 121 | while work.next != None: 122 | if work.value == searchVal: 123 | return True 124 | 125 | work = work.next 126 | 127 | return False 128 | -------------------------------------------------------------------------------- /Sort/sortingIII.js: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Homework XI * 3 | **********************************************************************/ 4 | 5 | /********************************************************************** 6 | * Problem 1: Bucket Sort * 7 | * * 8 | * Prompt: Given an unsorted array of numbers which are in the range * 9 | * of 0.0 to 1.0, and are uniformly distributed across the * 10 | * range, sort the numbers efficiently. * 11 | * * 12 | * Input: Unsorted array of numbers in range of 0.0 to 1.0 * 13 | * Output: A sorted array * 14 | * * 15 | * Example: input = [0.897, 0.565, 0.656, 0.1234, 0.665, 0.3434] * 16 | * output = [0.1234, 0.3434, 0.565, 0.656, 0.665, 0.897] * 17 | * * 18 | * What are the time and auxilliary space complexity? * 19 | * * 20 | **********************************************************************/ 21 | 22 | /********************************************************************** 23 | * Problem 2: Kth Smallest Element in a Range * 24 | * * 25 | * Prompt: Given an unsorted array of whole integers in the range * 26 | * 1000 to 9000, find the Kth smallest element in linear time* 27 | * The array can have duplicates. * 28 | * * 29 | * Input: Unsorted array of whole integers in range of 1000 to 9000 * 30 | * Kth smallest element you want to find * 31 | * * 32 | * Output: Kth smalest element in the range * 33 | * * 34 | * Example: array = [1984, 1337, 9000, 8304, 5150, 9000, 8304], k=5 * 35 | * output = 8304 * 36 | * * 37 | * What are the time and auxilliary space complexity? * 38 | * * 39 | **********************************************************************/ 40 | 41 | 42 | var countSort = function(input, max){ 43 | var tempArray = Array(max + 1).fill(0); 44 | // var countArray = []; 45 | var sortedArray = []; 46 | // create an array where the numbers 47 | // shows the number of occurrence in the array 48 | for (var i = 0; i < input.length; i++){ 49 | tempArray[input[i]] += 1; 50 | } 51 | 52 | // count and add them up to the countArray 53 | for(var j = 1; j < tempArray.length; j++){ 54 | tempArray[j] += tempArray[j - 1]; 55 | } 56 | 57 | // now sort the array using the bucket and counters 58 | for (var x = tempArray.length + 1; x >= 0; x--){ 59 | var indexToInsert = tempArray[input[x]] - 1; 60 | sortedArray[indexToInsert] = input[x]; 61 | tempArray[input[x]] -= 1; 62 | } 63 | 64 | return sortedArray; 65 | } 66 | // var array = [5,1,4,3,3,2,4,1,6,7]; 67 | // console.log(countSort(array, 7)); 68 | 69 | var insertionSort = function(input){ 70 | for (var j = 1; j < input.length; j++){ 71 | var temp = input[j]; 72 | var i = j - 1; 73 | 74 | while(i >= 0 && input[i] > temp){ 75 | input[i + 1] = input[i] 76 | i--; 77 | } 78 | input[i + 1] = temp; 79 | } 80 | return input; 81 | } 82 | // console.log(insertionSort([6,2,9,1,0,3])); 83 | 84 | var bucketSort = function(input){ 85 | 86 | var placeIntoBuckets = function(pullFrom, LowerRange, UpperRange){ 87 | var buckets = Array(10).fill([]); 88 | var division = (UpperRange - LowerRange) / 10; 89 | 90 | pullFrom.forEach(function(number){ 91 | buckets[Math.floor(number / division)].push(number); 92 | }); 93 | 94 | buckets.forEach(function(bucket){ 95 | input = insertionSort(input); 96 | }); 97 | } 98 | placeIntoBuckets(input, 0, 10000); 99 | return input; 100 | } 101 | // console.log(bucketSort([340, 565, 656, 1234, 665, 3434])); 102 | 103 | var kthSmallest = function(input, k){ 104 | // use bucket sort to sort the array first 105 | var sortedArray = bucketSort(input); 106 | 107 | // then loop take the index of k - 1 from the array 108 | if (k >= input.length) { 109 | console.log('the index is out of the scope'); 110 | } else { 111 | var result = sortedArray[k - 1]; 112 | return result; 113 | } 114 | } 115 | 116 | console.log(kthSmallest([1,6,2,9,0,10,23], 20)); 117 | 118 | //////////////////////////////////////////////////////////// 119 | /////////////// DO NOT TOUCH TEST BELOW!!! /////////////// 120 | //////////////////////////////////////////////////////////// 121 | 122 | var expect = require('chai').expect; 123 | 124 | describe('bucketSort', function(){ 125 | describe('run on example input:', function(){ 126 | it('should return the example output', function(){ 127 | var test = bucketSort([0.897, 0.565, 0.656, 0.1234, 0.665, 0.3434]); 128 | var answer = [0.1234, 0.3434, 0.565, 0.656, 0.665, 0.897]; 129 | 130 | expect(test).to.eql(answer); 131 | }); 132 | }); 133 | 134 | describe('run on empty array', function(){ 135 | it('should return an empty array', function(){ 136 | var test = bucketSort([]); 137 | var answer = []; 138 | 139 | expect(test).to.eql(answer); 140 | }) 141 | }) 142 | 143 | describe('run on large array', function(){ 144 | it('should return a sorted array', function(){ 145 | var testInput = []; 146 | var i = 10000; 147 | while (i--){ 148 | testInput.push(Math.floor(Math.random() * 1000)) 149 | } 150 | 151 | var test = bucketSort(testInput); 152 | var answer = testInput.sort(function(a,b){return a-b}); 153 | 154 | expect(test).to.eql(answer); 155 | }) 156 | }) 157 | }); 158 | 159 | 160 | describe('kthSmallest', function(){ 161 | describe('run on example input', function(){ 162 | it('should return the example output', function(){ 163 | var test = kthSmallest([1984, 1337, 9000, 8304, 5150, 9000, 8304], 5); 164 | var answer = 8304; 165 | 166 | expect(test).to.eql(answer); 167 | }); 168 | }); 169 | 170 | describe('run on [7, 10, 4, 3, 20, 15] and k=3', function(){ 171 | it('should return 7', function(){ 172 | var test = kthSmallest([7, 10, 4, 3, 20, 15], 3); 173 | var answer = 7; 174 | 175 | expect(test).to.eql(answer); 176 | }); 177 | }); 178 | 179 | describe('run on [7, 10, 4, 3, 20, 15] and k=4', function(){ 180 | it('should return 10', function(){ 181 | var test = kthSmallest([7, 10, 4, 3, 20, 15], 4); 182 | var answer = 10; 183 | 184 | expect(test).to.eql(answer); 185 | }); 186 | }); 187 | }) 188 | -------------------------------------------------------------------------------- /Sort/Basic Sorts/basic_sorts.rb: -------------------------------------------------------------------------------- 1 | # /********************************************************************** 2 | # * Homework III * 3 | # * * 4 | # * Problem: Insertion Sort * 5 | # * * 6 | # * Prompt: Given an unsorted array of numbers, * 7 | # * return a sorted array using insertion sort. * 8 | # * * 9 | # * Input: An unsorted array * 10 | # * Output: A sorted array * 11 | # * * 12 | # * Example: input = [3,9,1,4,7] , output = [1,3,4,7,9] * 13 | # * * 14 | # * What are the time and auxiliary space complexity? * 15 | # * * 16 | # **********************************************************************/ 17 | 18 | # /********************************************************** 19 | # * * 20 | # * Problem: Selection Sort * 21 | # * * 22 | # * Prompt: Given an unsorted array of numbers, * 23 | # * return a sorted array using insertion sort. * 24 | # * * 25 | # * Input: An unsorted array * 26 | # * Output: A sorted array * 27 | # * * 28 | # * Example: input = [8,3,2,10] output = [2,3,8,10] * 29 | # * * 30 | # * What are the time and auxiliary space complexity? * 31 | # * What is the best case time complexity? * 32 | # * * 33 | # **********************************************************/ 34 | 35 | # /********************************************************** 36 | # * * 37 | # * Problem: Bubble Sort * 38 | # * * 39 | # * Prompt: Given an unsorted array of numbers, * 40 | # * return a sorted array using bubble sort. * 41 | # * * 42 | # * Input: An unsorted array * 43 | # * Output: A sorted array * 44 | # * * 45 | # * Example: input = [8,3,2,10] output = [2,3,8,10] * 46 | # * * 47 | # * What are the time and auxiliary space complexity? * 48 | # * T: O(n^2) Omega(n^2) S: O(1) * 49 | # **********************************************************/ 50 | # array = [8,3,2,10,0] 51 | def insertionSort(input) 52 | for j in 1..input.length - 1 53 | temp = input[j] 54 | i = j - 1 55 | 56 | while i >= 0 && input[i] > temp 57 | input[i + 1] = input[i] 58 | i -= 1 59 | end 60 | input[i + 1] = temp 61 | end 62 | return input 63 | end 64 | # p insertionSort(array) 65 | 66 | # array = [8,3,2,10,0,-1,-2,-1] 67 | def swap(array, first_index, second_index) 68 | temp = array[first_index] 69 | array[first_index] = array[second_index] 70 | array[second_index] = temp 71 | end 72 | 73 | def find_min_index(array, start_index) 74 | min_index = start_index 75 | min_value = array[start_index] 76 | 77 | for number in start_index + 1..array.length - 1 78 | if array[number] < min_value 79 | min_index = number 80 | min_value = array[number] 81 | # p min_value 82 | end 83 | end 84 | return min_index 85 | end 86 | 87 | def selectionSort(input) 88 | for index in 0..input.length - 1 89 | min = find_min_index(input, index) 90 | swap(input, index, min) 91 | end 92 | return input 93 | end 94 | 95 | # # array = [8,3,2,10,0,-1,-2,-1] 96 | def bubbleSort(input) 97 | swap = true 98 | while swap == true 99 | swap = false 100 | for index in 0..input.length - 2 101 | # p index 102 | if input[index] > input[index + 1] 103 | swap(input, index, index + 1) 104 | swap = true 105 | end 106 | end 107 | end 108 | return input 109 | end 110 | # p bubbleSort(array) 111 | 112 | # ////////////////////////////////////////////////////////// 113 | # /////////////// DO NOT TOUCH TEST BELOW!!! ///////////// 114 | # ////////////////////////////////////////////////////////// 115 | 116 | require 'test/unit' 117 | 118 | class InsertionSortTest < Test::Unit::TestCase 119 | def test_insertionSort_should_handle_example_case 120 | test = insertionSort([3,9,1,4,7]) 121 | answer = [1,3,4,7,9] 122 | 123 | assert_equal(answer, test); 124 | end 125 | 126 | def test_insertionSort_should_handle_empty_input 127 | test = insertionSort([]) 128 | answer = [] 129 | 130 | assert_equal(answer, test); 131 | end 132 | 133 | def test_insertionSort_should_handle_large_input 134 | testInput = [] 135 | $i = 1000000 136 | 137 | while $i > 0 138 | toPush = Random.rand(1000000) 139 | testInput.push(toPush) 140 | $i = $i - 1 141 | end 142 | 143 | test = insertionSort(testInput) 144 | assert_equal(testInput.sort, test) 145 | end 146 | end 147 | 148 | class SelectionSortTest < Test::Unit::TestCase 149 | def test_selectionSort_should_handle_example_case 150 | test = selectionSort([8,3,2,10]) 151 | answer = [2,3,8,10] 152 | 153 | assert_equal(answer, test); 154 | end 155 | 156 | def test_selectionSort_should_handle_empty_input 157 | test = selectionSort([]) 158 | answer = [] 159 | 160 | assert_equal(answer, test); 161 | end 162 | 163 | def test_selectionSort_should_handle_large_input 164 | testInput = [] 165 | $i = 1000000 166 | 167 | while $i > 0 168 | toPush = Random.rand(1000000) 169 | testInput.push(toPush) 170 | $i = $i - 1 171 | end 172 | 173 | test = selectionSort(testInput) 174 | assert_equal(testInput.sort, test) 175 | end 176 | 177 | end 178 | 179 | class BubbleSortTest < Test::Unit::TestCase 180 | def test_bubbleSort_should_handle_example_case 181 | test = bubbleSort([8,3,2,10]) 182 | answer = [2,3,8,10] 183 | 184 | assert_equal(answer, test); 185 | end 186 | 187 | def test_bubbleSort_should_handle_empty_input 188 | test = bubbleSort([]) 189 | answer = [] 190 | 191 | assert_equal(answer, test); 192 | end 193 | 194 | def test_bubbleSort_should_handle_large_input 195 | testInput = [] 196 | $i = 1000000 197 | 198 | while $i > 0 199 | toPush = Random.rand(1000000) 200 | testInput.push(toPush) 201 | $i = $i - 1 202 | end 203 | 204 | test = bubbleSort(testInput) 205 | assert_equal(testInput.sort, test) 206 | end 207 | end 208 | -------------------------------------------------------------------------------- /Sort/Basic Sorts/basicSorts.js: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * * 3 | * Problem: Insertion Sort * 4 | * * 5 | * Prompt: Given an unsorted array of numbers, * 6 | * return a sorted array using insertion sort. * 7 | * * 8 | * Input: An unsorted array * 9 | * Output: A sorted array * 10 | * * 11 | * Example: input = [3,9,1,4,7] , output = [1,3,4,7,9] * 12 | * * 13 | * What are the time and auxiliary space complexity? * 14 | * T: O(n^2) S: O(1) * 15 | **********************************************************************/ 16 | var insertionSort = function(input){ 17 | for (var j = 1; j < input.length; j++) { 18 | var temp = input[j]; 19 | var i = j - 1; 20 | while (i >= 0 && input[i] > temp) { 21 | input[i + 1] = input[i]; 22 | i--; 23 | } 24 | input[i + 1] = temp; 25 | } 26 | return input; 27 | } 28 | // console.log(insertionSort([8,3,2,10,0])); 29 | /********************************************************** 30 | * * 31 | * Problem: Selection Sort * 32 | * * 33 | * Prompt: Given an unsorted array of numbers, * 34 | * return a sorted array using insertion sort. * 35 | * * 36 | * Input: An unsorted array * 37 | * Output: A sorted array * 38 | * * 39 | * Example: input = [8,3,2,10] output = [2,3,8,10] * 40 | * * 41 | * What are the time and auxiliary space complexity? * 42 | * What is the best case time complexity? * 43 | * T: (O^2) at all times, S: O(1) * 44 | **********************************************************/ 45 | var swap = function(array, firstIndex, secondIndex) { 46 | var temp = array[firstIndex]; 47 | array[firstIndex] = array[secondIndex]; 48 | array[secondIndex] = temp; 49 | }; 50 | 51 | var indexOfMinimum = function(array, startIndex) { 52 | var minIndex = startIndex; 53 | var minValue = array[startIndex]; 54 | 55 | for (var i = minIndex + 1; i < array.length; i++ ) { 56 | if (array[i] < minValue) { 57 | minIndex = i; 58 | minValue = array[i]; 59 | } 60 | } 61 | return minIndex; 62 | }; 63 | 64 | var selectionSort = function(input){ 65 | var min; 66 | for (var i = 0; i < input.length -1; i++) { 67 | min = indexOfMinimum(input, i); 68 | swap(input, i, min); 69 | } 70 | }; 71 | // console.log(selectionSort([8,3,2,10])); 72 | // var array = [8,3,9,-1] 73 | // swap(array,1,3); 74 | // console.log(indexOfMinimum(array, 0)); 75 | // selectionSort(array); 76 | // console.log(array); 77 | /********************************************************** 78 | * * 79 | * Problem: Bubble Sort * 80 | * * 81 | * Prompt: Given an unsorted array of numbers, * 82 | * return a sorted array using bubble sort. * 83 | * * 84 | * Input: An unsorted array * 85 | * Output: A sorted array * 86 | * * 87 | * Example: input = [8,3,2,10] output = [2,3,8,10] * 88 | * * 89 | * What are the time and auxiliary space complexity? * 90 | * T: O(n^2) S:O(n) * 91 | **********************************************************/ 92 | 93 | var bubbleSort = function(input){ 94 | var swap = true; 95 | while (swap === true) { 96 | swap = false; 97 | for (var i = 0; i < input.length; i++) { 98 | var temp = 0; 99 | if (input[i] > input[i + 1]) { 100 | temp = input[i]; 101 | input[i] = input[i+1]; 102 | input[i+1] = temp; 103 | swap = true; 104 | } 105 | } 106 | } 107 | return input; 108 | } 109 | // console.log(bubbleSort([1,3,5,8])); 110 | 111 | //////////////////////////////////////////////////////////// 112 | /////////////// DO NOT TOUCH TEST BELOW!!! /////////////// 113 | //////////////////////////////////////////////////////////// 114 | 115 | var expect = require('chai').expect; 116 | 117 | describe('INSERTION SORT ', function(){ 118 | 119 | describe("RUN ON [8, 3, 2, 10]: ", function(){ 120 | it("should return [2, 3, 8, 10]", function(){ 121 | var test = insertionSort([3,9,1,4,7]); 122 | var answer = [1,3,4,7,9]; 123 | 124 | expect(test).to.eql(answer); 125 | }); 126 | }); 127 | 128 | describe("RUN ON EMPTY INPUT []: ", function(){ 129 | it("should return []", function(){ 130 | var test = insertionSort([]); 131 | var answer = []; 132 | 133 | expect(test).to.eql(answer); 134 | }); 135 | }); 136 | 137 | describe("RUN ON LARGE INPUT: ", function(){ 138 | it("should complete", function(){ 139 | var testInput = []; 140 | var i = 1000000; 141 | while (i--){ 142 | testInput.push(Math.floor(Math.random() * 1000000)) 143 | } 144 | var test = insertionSort(testInput); 145 | 146 | expect(testInput.sort(function(a, b){return a-b})).to.eql(test); 147 | }) 148 | }) 149 | }); 150 | 151 | 152 | describe('SELECTION SORT ', function(){ 153 | 154 | describe("RUN ON [8, 3, 2, 10]: ", function(){ 155 | it("should return [2, 3, 8, 10]", function(){ 156 | var test = selectionSort([8,3,2,10]); 157 | var answer = [2,3,8,10]; 158 | 159 | expect(test).to.eql(answer); 160 | }); 161 | }); 162 | 163 | describe("RUN ON EMPTY INPUT []: ", function(){ 164 | it("should return []", function(){ 165 | var test = selectionSort([]); 166 | var answer = []; 167 | 168 | expect(test).to.eql(answer); 169 | }); 170 | }); 171 | 172 | describe("RUN ON LARGE INPUT: ", function(){ 173 | it("should complete", function(){ 174 | var testInput = []; 175 | var i = 1000000; 176 | while (i--){ 177 | testInput.push(Math.floor(Math.random() * 1000000)) 178 | } 179 | var test = selectionSort(testInput); 180 | 181 | expect(testInput.sort(function(a, b){return a-b})).to.eql(test); 182 | }) 183 | }) 184 | 185 | }); 186 | 187 | describe('BUBBLE SORT ', function(){ 188 | 189 | describe("RUN ON [8, 3, 2, 10]: ", function(){ 190 | it("should return [2, 3, 8, 10]", function(){ 191 | var test = bubbleSort([8,3,2,10]); 192 | var answer = [2,3,8,10]; 193 | 194 | expect(test).to.eql(answer); 195 | }); 196 | }); 197 | 198 | describe("RUN ON EMPTY INPUT []: ", function(){ 199 | it("should return []", function(){ 200 | var test = bubbleSort([]); 201 | var answer = []; 202 | 203 | expect(test).to.eql(answer); 204 | }); 205 | }); 206 | 207 | describe("RUN ON LARGE INPUT: ", function(){ 208 | it("should complete", function(){ 209 | var testInput = []; 210 | var i = 1000000; 211 | while (i--){ 212 | testInput.push(Math.floor(Math.random() * 1000000)) 213 | } 214 | var test = bubbleSort(testInput); 215 | 216 | expect(testInput.sort(function(a, b){return a-b})).to.eql(test); 217 | }) 218 | }) 219 | 220 | }); 221 | -------------------------------------------------------------------------------- /Data Structures/Trees/BST-Traverse.js: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Sprint IV * 3 | * * 4 | * Traversals Pt. 1 * 5 | * * 6 | * Instructions: One of the most fundamental components of working * 7 | * with trees and graphs is traversals. We will * 8 | * focus primarily on this piece to build your * 9 | * foundation of these data structures. * 10 | * * 11 | *********************************************************************/ 12 | 13 | /*** First we need a binary search tree. Use an existing binary search tree class that you have built. ***/ 14 | 15 | var node = function(value) { 16 | this.value = value; 17 | this.leftChild = null; 18 | this.rightChild = null; 19 | } 20 | 21 | var binarySearchTree = function() { 22 | this.root = null; 23 | this.size = 0; 24 | } 25 | 26 | binarySearchTree.prototype.insert = function(insertVal) { 27 | if (this.root === null) { 28 | this.root = new node(insertVal); 29 | this.size++; 30 | return; 31 | } else { 32 | var traverse = function(currentNode) { 33 | if (insertVal > currentNode.value) { 34 | if (currentNode.rightChild === null) { 35 | currentNode.rightChild = new node(insertVal); 36 | return; 37 | } else { 38 | traverse(currentNode.rightChild); 39 | } 40 | } else { 41 | if (currentNode.leftChild === null) { 42 | currentNode.leftChild = new node(insertVal); 43 | return; 44 | } else { 45 | traverse(currentNode.leftChild); 46 | } 47 | } 48 | } 49 | traverse(this.root); 50 | this.size++; 51 | } 52 | } 53 | 54 | binarySearchTree.prototype.search = function(searchVal) { 55 | var check = false; 56 | var traverse = function(currentNode) { 57 | if (currentNode === null) { 58 | return; 59 | } else if (currentNode.value === searchVal) { 60 | check = true; 61 | return; 62 | } 63 | 64 | traverse(currentNode.rightChild); 65 | traverse(currentNode.leftChild); 66 | } 67 | traverse(this.root); 68 | return check; 69 | } 70 | 71 | binarySearchTree.prototype.delete = function(removeVal) { 72 | var temp = []; 73 | 74 | var traverse = function(currentNode) { 75 | if (currentNode === null) { 76 | return; 77 | } else if (currentNode.value !== removeVal) { 78 | temp.push(currentNode.value); 79 | } 80 | traverse(currentNode.rightChild); 81 | traverse(currentNode.leftChild); 82 | } 83 | traverse(this.root); 84 | 85 | // error checking: if size of temp and tree is the same 86 | // then it means there is no such value to remove 87 | if (temp.lenght === this.size) { 88 | console.log("there is no such value to delete"); 89 | return; 90 | } 91 | 92 | this.root = null; 93 | this.size = 0; 94 | var toInsert; 95 | 96 | for (var i = 0; i < temp.length; i++) { 97 | toInsert = temp[i]; 98 | this.insert(toInsert); 99 | } 100 | return temp; 101 | } 102 | /** 103 | * 1. Write a function that takes in an array of integers and performs the insert method on each 104 | * item of the array in order. 105 | * 106 | * Input: Array 107 | * Output: Binary Search Tree 108 | * 109 | * Example: [4, 2, 5, 1, 3, 7, 6, 8] 110 | * Output this binary search tree: 111 | * 112 | * 4 113 | * / \ 114 | * 2 5 115 | * / \ \ 116 | * 1 3 7 117 | * / \ 118 | * 6 8 119 | **/ 120 | 121 | 122 | binarySearchTree.prototype.insertMultiple = function(array){ 123 | for (var i = 0; i < array.length; i++){ 124 | this.insert(array[i]); 125 | } 126 | } 127 | 128 | // var test = new binarySearchTree(); 129 | // test.insertMultiple([4, 2, 5, 1, 3, 7, 6, 8]); 130 | 131 | // console.log(test.root); 132 | 133 | 134 | /** 135 | * 2. Given the example output binary search tree from Problem 1, what would the order of values 136 | * printed be if we used: 137 | * 138 | * a. BREADTH FIRST traversal 139 | * [4, 2, 5, 1, 3, 7, 6, 8] 140 | * 141 | * b. PRE-ORDER DEPTH first traversal 142 | * [4, 2, 1, 3, 5, 7, 6, 8] 143 | * 144 | * c. IN-ORDER DEPTH first traversal 145 | * [1, 2, 3, 4, 5, 6, 7, 8] 146 | * 147 | * d. POST-ORDER DEPTH first traversal 148 | * [1, 3, 2, 6, 8, 7, 5, 4] 149 | **/ 150 | 151 | var test = new binarySearchTree(); 152 | test.insertMultiple([4, 2, 5, 1, 3, 7, 6, 8]); 153 | 154 | /** 155 | * 3a. Using a queue, and while loop write a function that takes in a binary search tree and 156 | * outputs an array of values ordered by BREADTH FIRST traversal. 157 | * 158 | * Input: Binary Search Tree 159 | * Output: Array 160 | * 161 | * NOTE: You may use an array or linked list for your queue. 162 | * 163 | * NOTE: Confirm with your answer from problem 2a. 164 | **/ 165 | 166 | binarySearchTree.prototype.breadthFirst = function(){ 167 | 168 | var queue = []; 169 | var result = []; 170 | var cNode; 171 | queue.push(this.root); 172 | 173 | while (queue.length > 0) { 174 | 175 | cNode = queue.shift(); 176 | if (cNode.leftChild !== null) { 177 | queue.push(cNode.leftChild); 178 | } 179 | 180 | if (cNode.rightChild !== null) { 181 | queue.push(cNode.rightChild); 182 | } 183 | 184 | result.push(cNode.value); 185 | } 186 | 187 | return result; 188 | } 189 | 190 | // Test Data 191 | console.log(test.breadthFirst()); 192 | 193 | /** 194 | * 3b. Using recursion, write a function that takes in a binary search tree and 195 | * outputs an array of values ordered by PRE-ORDER DEPTH FIRST traversal. 196 | * 197 | * Input: Binary Search Tree 198 | * Output: Array 199 | * 200 | * NOTE: Confirm with your answer from problem 2b. 201 | **/ 202 | binarySearchTree.prototype.preOrder = function(){ 203 | 204 | var result = []; 205 | var traverse = function(cNode) { 206 | 207 | if (cNode === null) { 208 | return; 209 | } 210 | 211 | result.push(cNode.value); 212 | traverse(cNode.leftChild); 213 | traverse(cNode.rightChild); 214 | 215 | } 216 | traverse(this.root); 217 | return result; 218 | } 219 | 220 | // Test Data 221 | console.log(test.preOrder()); 222 | 223 | /** 224 | * 3c. Using recursion, write a function that takes in a binary search tree and 225 | * outputs an array of values ordered by IN-ORDER DEPTH FIRST traversal. 226 | * 227 | * Input: Binary Search Tree 228 | * Output: Array 229 | * 230 | * NOTE: Confirm with your answer from problem 2c. 231 | **/ 232 | 233 | binarySearchTree.prototype.inOrder = function() { 234 | var result = []; 235 | var traverse = function(cNode){ 236 | 237 | // Best Case 238 | if(cNode === null) { 239 | return; 240 | } 241 | 242 | // Recursion Case 243 | traverse(cNode.leftChild); 244 | result.push(cNode.value); 245 | traverse(cNode.rightChild); 246 | } 247 | traverse(this.root); 248 | return result; 249 | } 250 | 251 | // Test Data 252 | console.log(test.inOrder()); 253 | /** 254 | * 3d. Using recursion, write a function that takes in a binary search tree and 255 | * outputs an array of values ordered by POST-ORDER DEPTH FIRST traversal. 256 | * 257 | * Input: Binary Search Tree 258 | * Output: Array 259 | * 260 | * NOTE: Confirm with your answer from problem 2d. 261 | **/ 262 | 263 | binarySearchTree.prototype.postOrder = function(){ 264 | var result = []; 265 | 266 | var traverse = function(cNode){ 267 | // best case 268 | if (cNode === null) { 269 | return; 270 | } 271 | 272 | //recursion case 273 | traverse(cNode.leftChild); 274 | traverse(cNode.rightChild); 275 | result.push(cNode.value); 276 | 277 | } 278 | traverse(this.root); 279 | return result; 280 | } 281 | 282 | // Test Data 283 | console.log(test.postOrder()); 284 | -------------------------------------------------------------------------------- /Sort/sortingII.js: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Target Practice V * 3 | * * 4 | * Sorting II - Revisted * 5 | * * 6 | * Instructions: To further reinforce understanding of how Merge and * 7 | * Quicksort are implemented, we will be building * 8 | * those functions again. * 9 | * * 10 | * Additionally, we will be using a min heap to build * 11 | * heapsort. Please use your min heap from class. * 12 | * * 13 | * Please do not refer to your homework solutions for * 14 | * Merge Sort or Quicksort. * 15 | * * 16 | **********************************************************************/ 17 | 18 | /** 19 | * 1. Please indicate whether the following sorting algorithms are stable or unstable 20 | * 21 | * Merge Sort: Stable Sort 22 | * 23 | * Quicksort: Not Stable Sort 24 | * 25 | * Heapsort: Not Stable Sort 26 | **/ 27 | 28 | 29 | /** 30 | * 2a. Implement Quicksort in your chosen language, such that given an unsorted array 31 | * of numbers you will return that array sorted. 32 | 33 | * Input: An unsorted array 34 | * Output: A sorted array 35 | * 36 | * Example: quicksort([4,15,16,50,8,23,42,108]) 37 | * // [4,8,15,16,23,42,50,108] 38 | **/ 39 | 40 | var quickSort = function(work) { 41 | 42 | // if array length is less than 1 43 | if (work.length <= 1) { 44 | return work; 45 | } 46 | 47 | // Create the pivot 48 | var pivotIndex = Math.floor(work.length / 2); 49 | var pivot = work[pivotIndex]; 50 | 51 | // create 2 arrays to store before and after elements of pivot 52 | var before = []; 53 | var after = []; 54 | 55 | // fill the above arrays to fill with the numbers 56 | for (var i = 0; i < work.length; i++) { 57 | // make sure is i not on the pivot index 58 | if (i !== pivotIndex) { 59 | if (work[i] <= pivot) { 60 | before.push(work[i]); 61 | } else { 62 | after.push(work[i]); 63 | } 64 | } 65 | } 66 | // recursion call 67 | return quickSort(before).concat(pivot).concat(quickSort(after)); 68 | } 69 | 70 | // var array = [2,1,5,21,3,4,10,6,7,1]; 71 | // console.log(quickSort(array)); 72 | 73 | /** 74 | * 2b. What is the time complexity and auxiliary space complexity of your quicksort? 75 | * 76 | * Time Complexity: O(n^2) 77 | * Auxiliary Space Complexity: O(n) 78 | **/ 79 | 80 | 81 | /** 82 | * 3a. Implement Merge Sort in your chosen language, such that given an unsorted array 83 | * of numbers you will return that array sorted. 84 | * 85 | * Input: An unsorted array 86 | * Output: A sorted array 87 | * 88 | * Example: mergeSort([4,15,16,50,8,23,42,108]) 89 | * // [4,8,15,16,23,42,50,108] 90 | **/ 91 | 92 | // Joining 2 arrays 93 | var joinArrays = function(arr1, arr2){ 94 | // create pointer 1 and 2 and equal to 0 95 | var p1, p2; 96 | p1 = p2 = 0; 97 | // create a result array to put the merged array into 98 | var result = []; 99 | 100 | // check it any of the arrays are undefined 101 | // then push the other array into the result 102 | if (arr1 === undefined) { 103 | return arr2; 104 | } else if (arr2 === undefined) { 105 | return arr1; 106 | } 107 | // iterate through both arrays 108 | // before end of array check to see which element is bigger or smaller 109 | // then add it to result accordingly and increase their pointer 110 | while (arr1[p1] !== undefined && arr2[p2] !== undefined) { 111 | if (arr1[p1] <= arr2[p2]) { 112 | result.push(arr1[p1]); 113 | p1++; 114 | } else { 115 | result.push(arr2[p2]); 116 | p2++; 117 | } 118 | } 119 | // if one of the arrays pointers become undefined 120 | // then push the other array result at the end of result array 121 | if (p1 === arr1.length) { 122 | result = result.concat(arr2.slice(p2)); 123 | } else if (p2 === arr2.length) { 124 | result = result.concat(arr1.slice(p2)); 125 | } 126 | // return final result 127 | return result 128 | } 129 | 130 | // var arr1 = [1,3,5,7,9,11,13] 131 | // var arr2 = [2,4,6,8]; 132 | 133 | // console.log(joinArrays(arr1, arr2)); 134 | // merge sort function 135 | var mergeSort = function(array){ 136 | // if the array length is less than 1 137 | // then return itself since that's sorted 138 | if (array.length <= 1) { 139 | return array; 140 | } 141 | // create middle index 142 | // create left and right arrays 143 | var midIndex = Math.floor(array.length / 2); 144 | // create the left and right arrays 145 | var left = array.slice(0, midIndex); 146 | var right = array.slice(midIndex, array.length); 147 | 148 | // recursion case to return the result while merging and sorting (divide - conquer) 149 | return joinArrays(mergeSort(left), mergeSort(right)); 150 | } 151 | 152 | // var array = [2,1,5,21,3,4,10,6,7,-1,-1]; 153 | // console.log(quickSort(array)); 154 | /** 155 | * 3b. What is the time complexity and auxiliary space complexity of your mergeSort? 156 | * 157 | * Time Complexity: O(n log(n)) 158 | * Auxiliary Space Complexity: O(n) 159 | **/ 160 | 161 | 162 | /** 163 | * 4a. Implement heapsort in your chosen language, such that given an unsorted array 164 | * of numbers you will return that array sorted. 165 | * 166 | * Input: An unsorted array 167 | * Output: A sorted array 168 | * 169 | * Example: heapsort([4,15,16,50,8,23,42,108]) 170 | * // [4,8,15,16,23,42,50,108] 171 | **/ 172 | 173 | 174 | /** 175 | * 4b. What is the time complexity and auxiliary space complexity of your heapsort? 176 | * 177 | * Time Complexity: 178 | * Auxiliary Space Complexity: 179 | **/ 180 | 181 | 182 | // if you do not have your own heap, a min-heap has been provided for your use 183 | function MinHeap(){ 184 | this.storage = []; 185 | } 186 | 187 | MinHeap.prototype.insert = function(value){ 188 | this.storage.push(value); 189 | this.bubbleUp(); 190 | } 191 | 192 | MinHeap.prototype.remove = function(){ 193 | this.swap(0, this.size() - 1); 194 | var result = this.storage.pop(); 195 | this.bubbleDown(); 196 | return result; 197 | } 198 | 199 | MinHeap.prototype.bubbleUp = function(){ 200 | var current = this.size() - 1; 201 | var parent = this.parentIndex(current); 202 | while(current > 0 && this.storage[parent] > this.storage[current]){ 203 | this.swap(parent, current); 204 | current = parent; 205 | parent = this.parentIndex(current); 206 | } 207 | } 208 | 209 | MinHeap.prototype.bubbleDown = function(){ 210 | var current = 0; 211 | var child = this.minChild(current); 212 | while(child !== undefined && this.storage[current] > this.storage[child]){ 213 | this.swap(current, child); 214 | current = child; 215 | child = this.minChild(current); 216 | } 217 | } 218 | 219 | MinHeap.prototype.parentIndex = function(childIndex){ 220 | return Math.floor((childIndex - 1)/2); 221 | } 222 | 223 | MinHeap.prototype.childIndex = function(parentIndex){ 224 | return [2 * parentIndex + 1, 2 * parentIndex + 2]; 225 | } 226 | 227 | MinHeap.prototype.minChild = function(parentIndex){ 228 | var children = this.childIndex(parentIndex); 229 | //if left child is undefined, then both left and right child will be undefined 230 | //default to just returning left index 231 | //if left child is defined however right child is undefined or out of bounds 232 | //return left child index 233 | if(this.storage[children[0]] === undefined || this.storage[children[1]] === undefined){ return children[0];} 234 | 235 | if(this.storage[children[0]] < this.storage[children[1]]){ 236 | return children[0]; 237 | } else { 238 | return children[1]; 239 | } 240 | } 241 | 242 | MinHeap.prototype.swap = function(i, j){ 243 | var temp = this.storage[i]; 244 | this.storage[i] = this.storage[j]; 245 | this.storage[j] = temp; 246 | } 247 | 248 | MinHeap.prototype.size = function(){ 249 | return this.storage.length; 250 | } 251 | 252 | MinHeap.prototype.peak = function(){ 253 | return storage[0]; 254 | } 255 | 256 | var heap = new MinHeap(); 257 | -------------------------------------------------------------------------------- /Data Structures/Linked List/linked_list.rb: -------------------------------------------------------------------------------- 1 | # /********************************************************************************** 2 | # * Homework IV * 3 | # * * 4 | # * Problem: Linked List * 5 | # * * 6 | # * Prompt: Create a Linked List class/constructor. * 7 | # * Name it LinkedList (js) or Linked_List(rb/py). * 8 | # * * 9 | # * Part 1: Create a node class for your LinkedList. * 10 | # * Your node class will take an integer value and output * 11 | # * and output and object with the following properties: * 12 | # * * 13 | # * node.value: input value * 14 | # * node.next: a pointer to the next value (initiall null) * 15 | # * * 16 | # * Example: { value: 1, next: null } * 17 | # * * 18 | # * Part 2: Create the LinkedList class. * 19 | # * It should contain the following properties: * 20 | # * * 21 | # * head: pointer to the head node * 22 | # * tail: pointer to the tail node * 23 | # * length: number of nodes in the linked list * 24 | # * * 25 | # * The LinkedList should also contain the following properties * 26 | # * * 27 | # * append: function that adds a node to the tail * 28 | # * * 29 | # * insert: function that takes in two values, one to be inserted * 30 | # * and one to search. It searches the list for the * 31 | # * search value, and if found, adds a new node with the * 32 | # * insert value after the node with the search value. * 33 | # * * 34 | # * delete: function that removes a node at a specified location, * 35 | # * with a default action of deleting the head * 36 | # * * 37 | # * contains: function that checks to see if a value is contained * 38 | # * in the list * 39 | # * * 40 | # * Input: N/A * 41 | # * Output: A LinkedList instance * 42 | # * * 43 | # * What are the time and auxilliary space complexities of the various methods? * 44 | # * * 45 | # **********************************************************************************/ 46 | 47 | 48 | class Node 49 | 50 | def value 51 | @value 52 | end 53 | def next 54 | @next 55 | end 56 | 57 | def initialize(val) 58 | @value = val 59 | @next = nil 60 | end 61 | 62 | attr_accessor :val 63 | attr_accessor :next 64 | end 65 | 66 | class Linked_List 67 | def initialize() 68 | @head = nil 69 | @tail = nil 70 | @listLength = 0 71 | end 72 | 73 | attr_reader :head 74 | attr_reader :tail 75 | attr_reader :listLength 76 | 77 | def append(val) 78 | if @listLength == 0 79 | @head = Linked_List.new(val) 80 | @tail = @head 81 | return 82 | else 83 | @tail = Linked_List.new(val) 84 | return 85 | end 86 | @listLength++ 87 | end 88 | 89 | def insert(insertVal, searchVal) 90 | work = @head 91 | 92 | while work.next != nil 93 | if work.value == searchVal 94 | reference = work.next 95 | work.next = Linked_List.new(insertVal) 96 | work.next.next = reference 97 | 98 | if reference == nil 99 | @tail = work.next 100 | end 101 | 102 | @listLength++ 103 | end 104 | work = work.next 105 | end 106 | puts "not found" 107 | end 108 | 109 | def delete(location) 110 | # 1) delete first element and linkedlist has no elem 111 | if location == 0 && @listLength == 0 112 | @head = nil 113 | @tail = nil 114 | @listLength-- 115 | return 116 | else 117 | # 2) delete first element but linkedlist has more than one elem 118 | @head = @head.next 119 | @listLength-- 120 | return 121 | end 122 | work = @head 123 | counter = 0 124 | 125 | while work.next != nil 126 | # 3) delete the last element of linkedList 127 | if location = (@listLength - 1) && work.next != nil && work.next == @tails 128 | work.next = work.next.next 129 | @tail = work 130 | @listLength-- 131 | return 132 | # 4) delete neither last or first 133 | elsif location = (@listLength - 1) && work.next != nil 134 | work.next = work.next.next 135 | @listLength-- 136 | return 137 | end 138 | 139 | counter++ 140 | work = work.next 141 | end 142 | puts "Not found" 143 | end 144 | 145 | def contains(val) 146 | work = @head 147 | while work.next != nil 148 | return true if work.value == val 149 | work = work.next 150 | end 151 | return false 152 | end 153 | 154 | end 155 | 156 | 157 | 158 | 159 | 160 | # ////////////////////////////////////////////////////////// 161 | # /////////////// DO NOT TOUCH TEST BELOW!!! ///////////// 162 | # ////////////////////////////////////////////////////////// 163 | 164 | require 'test/unit' 165 | 166 | class LinkedListNodeTest < Test::Unit::TestCase 167 | def test_creation_of_node 168 | test = Node.new(3) 169 | 170 | assert_not_equal(nil, test) 171 | end 172 | def test_encoding_a_value 173 | test = Node.new(5) 174 | 175 | assert_equal(5, test.value) 176 | assert_equal(nil, test.next) 177 | end 178 | def test_pointing_to_another_node 179 | initial = Node.new(5) 180 | target = Node.new(10) 181 | initial.next = target 182 | 183 | assert_equal(5, initial.value) 184 | assert_equal(10, initial.next.value) 185 | end 186 | end 187 | 188 | class LinkedListClassTest < Test::Unit::TestCase 189 | def test_linked_list_properties_existence 190 | test = Linked_List.new() 191 | 192 | assert_respond_to(test, :head) 193 | assert_respond_to(test, :tail) 194 | assert_respond_to(test, :listLength) 195 | 196 | end 197 | 198 | def test_linked_list_methods_existence 199 | test = Linked_List.new() 200 | 201 | assert_respond_to(test, :append) 202 | assert_respond_to(test, :insert) 203 | assert_respond_to(test, :delete) 204 | assert_respond_to(test, :contains) 205 | end 206 | 207 | def test_linked_list_append_method_single_node 208 | test = Linked_List.new() 209 | test.append(5) 210 | 211 | assert_equal(5, test.head.value) 212 | assert_equal(5, test.tail.value) 213 | end 214 | 215 | def test_linked_list_append_method_two_node 216 | test = Linked_List.new() 217 | test.append(5) 218 | test.append(10) 219 | 220 | assert_equal(5, test.head.value) 221 | assert_equal(10, test.tail.value) 222 | end 223 | 224 | def test_linked_list_insert_method_between_nodes 225 | test = Linked_List.new() 226 | test.append(5) 227 | test.append(10) 228 | test.insert(13, 5) 229 | 230 | assert_equal(5, test.head.value) 231 | assert_equal(13, test.head.next.value) 232 | assert_equal(10, test.head.next.next.value) 233 | assert_equal(10, test.tail.value) 234 | end 235 | 236 | def test_linked_list_insert_method_modify_tail 237 | test = Linked_List.new() 238 | test.append(5) 239 | test.append(10) 240 | test.insert(13, 10) 241 | 242 | assert_equal(5, test.head.value) 243 | assert_equal(10, test.head.next.value) 244 | assert_equal(13, test.head.next.next.value) 245 | assert_equal(13, test.tail.value) 246 | end 247 | 248 | def test_linked_list_insert_method_no_searchValue_match 249 | test = Linked_List.new() 250 | test.append(5) 251 | test.append(10) 252 | test.insert(13, 17) 253 | 254 | assert_equal(5, test.head.value) 255 | assert_equal(10, test.head.next.value) 256 | assert_equal(10, test.tail.value) 257 | assert_equal(2, test.listLength) 258 | end 259 | 260 | def test_linked_list_delete_method_delete_middle 261 | test = Linked_List.new() 262 | test.append(5) 263 | test.append(10) 264 | test.append(15) 265 | test.delete(1) 266 | 267 | assert_equal(5, test.head.value) 268 | assert_equal(15, test.tail.value) 269 | assert_equal(15, test.head.next.value) 270 | assert_equal(2, test.listLength) 271 | end 272 | 273 | def test_linked_list_delete_method_delete_head 274 | test = Linked_List.new() 275 | test.append(5) 276 | test.append(10) 277 | test.append(15) 278 | test.delete(0) 279 | 280 | assert_equal(10, test.head.value) 281 | assert_equal(15, test.tail.value) 282 | assert_equal(15, test.head.next.value) 283 | assert_equal(2, test.listLength) 284 | end 285 | 286 | def test_linked_list_delete_method_delete_tail 287 | test = Linked_List.new() 288 | test.append(5) 289 | test.append(10) 290 | test.append(15) 291 | test.delete(2) 292 | 293 | assert_equal(5, test.head.value) 294 | assert_equal(10, test.tail.value) 295 | assert_equal(10, test.head.next.value) 296 | assert_equal(2, test.listLength) 297 | end 298 | 299 | def test_linked_list_delete_method_delete_out_of_range 300 | test = Linked_List.new() 301 | test.append(5) 302 | test.append(10) 303 | test.append(15) 304 | test.delete(5) 305 | 306 | assert_equal(5, test.head.value) 307 | assert_equal(15, test.tail.value) 308 | assert_equal(10, test.head.next.value) 309 | assert_equal(15, test.head.next.next.value) 310 | assert_equal(3, test.listLength) 311 | end 312 | 313 | def test_linked_list_contains_method_when_true 314 | test = Linked_List.new() 315 | test.append(5) 316 | test.append(10) 317 | test.append(15) 318 | 319 | assert_equal(true, test.contains(10)) 320 | end 321 | 322 | def test_linked_list_contains_method_when_false 323 | test = Linked_List.new() 324 | test.append(5) 325 | test.append(10) 326 | test.append(15) 327 | 328 | assert_equal(false, test.contains(75)) 329 | end 330 | end 331 | -------------------------------------------------------------------------------- /Data Structures/Trees/BST.js: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Homework V * 3 | * * 4 | * Problem: Binary Search Tree * 5 | * * 6 | * Prompt: Create a BinarySearchTree class/constructor. * 7 | * Name it binarySearchTree (js) or binary_search_tree (rb/py). * 8 | * * 9 | * Part 1: Create a node class for your binarySearchTree. * 10 | * Your node class will take an integer value and output * 11 | * an object with the following properties: * 12 | * * 13 | * node.value: input value * 14 | * node.leftChild: a pointer to the left child Node * 15 | * node.rightChild: a pointer to the right child Node * 16 | * * 17 | * Example: { value: 1, leftChild: null, rightChild: null } * 18 | * * 19 | * Part 2: Create the BinarySearchTree class. * 20 | * It should contain the following properties: * 21 | * * 22 | * root: pointer to the root node * 23 | * size: number of nodes in the BinarySearchTree * 24 | * * 25 | * The BinarySearchTree will also have the following properties: * 26 | * * 27 | * insert: method that takes takes an input value, and creates a * 28 | * new node with the given input. The method will then * 29 | * find the correct place to add the new node. (Remember * 30 | * that nodes with values larger than the parent node go * 31 | * to the right, and smaller values go to the left.) * 32 | * * 33 | * search: method that will search to see if a node with a * 34 | * specified value exists. If present returns true, * 35 | * else returns false. * 36 | * * 37 | * Input: N/A * 38 | * Output: A BinarySearchTree instance * 39 | * * 40 | * What are the time and auxilliary space complexities of the various methods? * 41 | * * 42 | **********************************************************************************/ 43 | 44 | 45 | /** 46 | * Extra Credit: Remove 47 | * 48 | * Prompt: Create a remove method on your BinarySearchTree that will remove and 49 | * return a given value from the tree and retie the tree so it remains 50 | * properly sorted. 51 | **/ 52 | 53 | 54 | var node = function(value) { 55 | this.value = value; 56 | this.leftChild = null; 57 | this.rightChild = null; 58 | } 59 | 60 | var binarySearchTree = function() { 61 | this.root = null; 62 | this.size = 0; 63 | } 64 | 65 | binarySearchTree.prototype.insert = function(insertVal) { 66 | if (this.root === null) { 67 | this.root = new node(insertVal); 68 | this.size++; 69 | return; 70 | } else { 71 | var traverse = function(currentNode) { 72 | if (insertVal > currentNode.value) { 73 | if (currentNode.rightChild === null) { 74 | currentNode.rightChild = new node(insertVal); 75 | return; 76 | } else { 77 | traverse(currentNode.rightChild); 78 | } 79 | } else { 80 | if (currentNode.leftChild === null) { 81 | currentNode.leftChild = new node(insertVal); 82 | return; 83 | } else { 84 | traverse(currentNode.leftChild); 85 | } 86 | } 87 | } 88 | traverse(this.root); 89 | this.size++; 90 | } 91 | } 92 | 93 | // Testing data 94 | // var test = new binarySearchTree(); 95 | // test.insert(5); 96 | // test.insert(3); 97 | // test.insert(4); 98 | // test.insert(10); 99 | // test.insert(12); 100 | // console.log(JSON.stringify(test.root)); 101 | 102 | binarySearchTree.prototype.search = function(searchVal) { 103 | var check = false; 104 | var traverse = function(currentNode) { 105 | if (currentNode === null) { 106 | return; 107 | } else if (currentNode.value === searchVal) { 108 | check = true; 109 | return; 110 | } 111 | 112 | traverse(currentNode.rightChild); 113 | traverse(currentNode.leftChild); 114 | } 115 | traverse(this.root); 116 | return check; 117 | } 118 | 119 | // Testing data 120 | // var test = new binarySearchTree(); 121 | // test.insert(5); 122 | // test.insert(3); 123 | // test.insert(4); 124 | // test.insert(10); 125 | // test.insert(12); 126 | // console.log(test.search(8)); 127 | 128 | binarySearchTree.prototype.delete = function(removeVal) { 129 | var temp = []; 130 | 131 | var traverse = function(currentNode) { 132 | if (currentNode === null) { 133 | return; 134 | } else if (currentNode.value !== removeVal) { 135 | temp.push(currentNode.value); 136 | } 137 | traverse(currentNode.rightChild); 138 | traverse(currentNode.leftChild); 139 | } 140 | traverse(this.root); 141 | 142 | // error checking: if size of temp and tree is the same 143 | // then it means there is no such value to remove 144 | if (temp.lenght === this.size) { 145 | console.log("there is no such value to delete"); 146 | return; 147 | } 148 | 149 | this.root = null; 150 | this.size = 0; 151 | var toInsert; 152 | 153 | for (var i = 0; i < temp.length; i++) { 154 | toInsert = temp[i]; 155 | this.insert(toInsert); 156 | } 157 | return temp; 158 | } 159 | 160 | // Test data 161 | // var test = new binarySearchTree(); 162 | // test.insert(5); 163 | // test.insert(3); 164 | // test.insert(4); 165 | // test.insert(10); 166 | // test.insert(12); 167 | // test.delete(5); 168 | // test.delete(12); 169 | 170 | // console.log(JSON.stringify(test)); 171 | 172 | //////////////////////////////////////////////////////////// 173 | /////////////// DO NOT TOUCH TEST BELOW!!! /////////////// 174 | //////////////////////////////////////////////////////////// 175 | 176 | var expect = require('chai').expect; 177 | 178 | describe('binary search tree node', function(){ 179 | 180 | describe('creation of a node', function(){ 181 | it('should exist: ', function(){ 182 | var test = new node(); 183 | 184 | expect(test).to.not.equal(undefined); 185 | }); 186 | }); 187 | 188 | describe('encoding a value', function(){ 189 | it('should store a value: ', function(){ 190 | var test = new node(); 191 | 192 | expect(test).to.have.property('value'); 193 | expect(test.value).to.equal(undefined); 194 | 195 | test.value = 3; 196 | 197 | expect(test.value).to.equal(3); 198 | }); 199 | }); 200 | 201 | describe('pointing to another node', function(){ 202 | it('should be able to point to another node: ', function(){ 203 | var initial = new node(5); 204 | var rightTarget = new node(10); 205 | var leftTarget = new node(2); 206 | 207 | expect(initial).to.have.property('value'); 208 | expect(initial).to.have.property('rightChild'); 209 | expect(initial).to.have.property('leftChild'); 210 | expect(initial.rightChild).to.equal(null); 211 | expect(initial.leftChild).to.equal(null); 212 | 213 | initial.rightChild = rightTarget; 214 | initial.leftChild = leftTarget; 215 | 216 | expect(initial.rightChild.value).to.equal(10); 217 | expect(initial.leftChild.value).to.equal(2); 218 | 219 | }) 220 | }) 221 | }) 222 | 223 | describe('binary search tree class ', function(){ 224 | 225 | describe('binarySearchTree properties', function(){ 226 | it('should have properties root and size', function(){ 227 | var test = new binarySearchTree(); 228 | 229 | expect(test).to.have.property('root'); 230 | expect(test).to.have.property('size'); 231 | expect(test.root).to.equal(null); 232 | expect(test.size).to.equal(0); 233 | }); 234 | }); 235 | 236 | describe('binarySearchTree methods existence', function(){ 237 | it('should have methods insert, search, and delete', function(){ 238 | var test = new binarySearchTree(); 239 | 240 | expect(test).to.respondTo('insert'); 241 | expect(test).to.respondTo('search'); 242 | expect(test).to.respondTo('delete'); 243 | }); 244 | }); 245 | 246 | describe('binarySearchTree insert method', function(){ 247 | it('should be able to insert a single node', function(){ 248 | var test = new binarySearchTree(); 249 | 250 | expect(test.root).to.equal(null); 251 | expect(test.size).to.equal(0); 252 | 253 | test.insert(5); 254 | 255 | expect(test.root.value).to.equal(5); 256 | expect(test.root.rightChild).to.equal(null); 257 | expect(test.root.leftChild).to.equal(null); 258 | expect(test.size).to.equal(1); 259 | }); 260 | 261 | it('should be able to insert a second node', function(){ 262 | var test = new binarySearchTree(); 263 | 264 | expect(test.root).to.equal(null); 265 | expect(test.size).to.equal(0); 266 | 267 | test.insert(5); 268 | 269 | expect(test.root.value).to.equal(5); 270 | expect(test.root.rightChild).to.equal(null); 271 | expect(test.root.leftChild).to.equal(null); 272 | expect(test.size).to.equal(1); 273 | 274 | test.insert(10); 275 | 276 | expect(test.root.value).to.equal(5); 277 | expect(test.root.rightChild.value).to.equal(10); 278 | expect(test.root.leftChild).to.equal(null); 279 | expect(test.size).to.equal(2); 280 | }); 281 | }); 282 | 283 | describe('binarySearchTree search method', function(){ 284 | it('should return true when the node exists', function(){ 285 | var test = new binarySearchTree(); 286 | test.insert(5); 287 | test.insert(10); 288 | 289 | expect(test.search(5)).to.equal(true); 290 | }) 291 | 292 | it('should return false when the node does not exist', function(){ 293 | var test = new binarySearchTree(); 294 | test.insert(5); 295 | test.insert(10); 296 | 297 | expect(test.search(17)).to.equal(false); 298 | }) 299 | }) 300 | 301 | describe('binarySearchTree delete method', function(){ 302 | it('should delete a node', function(){ 303 | var test = new binarySearchTree(); 304 | test.insert(5); 305 | test.insert(10); 306 | test.insert(2); 307 | test.insert(7); 308 | test.insert(1); 309 | 310 | expect(test.search(7)).to.equal(true); 311 | 312 | test.delete(7); 313 | 314 | expect(test.search(7)).to.equal(false); 315 | 316 | }); 317 | 318 | it('should modify the size when deleting a node', function(){ 319 | var test = new binarySearchTree(); 320 | test.insert(5); 321 | test.insert(10); 322 | test.insert(2); 323 | test.insert(7); 324 | test.insert(1); 325 | 326 | expect(test.size).to.equal(5); 327 | 328 | test.delete(7); 329 | 330 | expect(test.size).to.equal(4); 331 | }); 332 | 333 | }); 334 | 335 | }) 336 | -------------------------------------------------------------------------------- /Data Structures/Hash Table/hashTable.js: -------------------------------------------------------------------------------- 1 | /********************************************************************************** 2 | * Homework VII * 3 | * * 4 | * Problem: Hash Table * 5 | * * 6 | * Prompt: Create a HashTable class/constructor. * 7 | * Name it HashTable (js) or hash_table (rb/py). Use separate chaining. * 8 | * * 9 | * The HashTable will have the following properties: * 10 | * * 11 | * storage: An array of arrays. * 12 | * * 13 | * buckets: The max number of buckets that your storage can contain. * 14 | * Initialize your "buckets" at 8 buckets. * 15 | * * 16 | * size: The current number (total) of key-value pairs in the storage. * 17 | * Initialize your "size" to 0. * 18 | * * 19 | * The HashTable will also have the following methods: * 20 | * * 21 | * hash: Method that takes a string as an input and outputs a number. * 22 | * We have provided to you the dbjb2 hashing function, so you do * 23 | * not need to write your own. * 24 | * * 25 | * insert: Method that takes a key and a value as inputs, and places a * 26 | * tuple ([key,value]) into the proper bucket. * 27 | * If the key already exists, it should update the value. * 28 | * You should use separate chaining to handle collisions. * 29 | * * 30 | * delete: Method that takes a key as its input, and looks for the * 31 | * [key,value] and removes it from the bucket. * 32 | * * 33 | * retrieve: Method that a key as its input, and returns the value * 34 | * stored at that key, or undefined if the key is not present. * 35 | * * 36 | * Input: N/A * 37 | * Output: A HashTable instance * 38 | * * 39 | * What are the time and auxiliary space complexities of the various methods? * 40 | * * 41 | **********************************************************************************/ 42 | 43 | // hash table 44 | var hashTable = function(){ 45 | this.storage = []; 46 | this.buckets = 8; 47 | this.size = 0; 48 | } 49 | 50 | hashTable.prototype.hash = function(str){ 51 | var hash = 5381; 52 | for (i = 0; i < str.length; i++) { 53 | char = str.charCodeAt(i); 54 | hash = ((hash << 5) + hash) + char; /* hash * 33 + c */ 55 | } 56 | return hash % this.buckets; 57 | } 58 | 59 | 60 | hashTable.prototype.insert = function(key, value){ 61 | var index = this.hash(key); 62 | 63 | if (this.storage[index] === undefined){ 64 | this.storage[index] = []; 65 | this.storage[index].push([key, value]); 66 | this.size++; 67 | } else { 68 | for (var i = 0; i < this.storage[index].length; i++){ 69 | if (this.storage[index][i][0] === key){ 70 | this.storage[index][i][1] = value; 71 | // this.resize(); 72 | return; 73 | } 74 | } 75 | this.storage[index].push([key, value]); 76 | this.size++; 77 | } 78 | this.resize(); 79 | 80 | } 81 | 82 | hashTable.prototype.resizeInsert = function(key, value){ 83 | var index = this.hash(key); 84 | 85 | if (this.storage[index] === undefined){ 86 | this.storage[index] = []; 87 | this.storage[index].push([key, value]); 88 | this.size++; 89 | } else { 90 | for (var i = 0; i < this.storage[index].length; i++){ 91 | if (this.storage[index][i][0] === key){ 92 | this.storage[index][i][1] = value; 93 | // this.resize(); 94 | return; 95 | } 96 | } 97 | this.storage[index].push([key, value]); 98 | this.size++; 99 | } 100 | // this.resize(); 101 | 102 | } 103 | 104 | hashTable.prototype.delete = function(key){ 105 | var index = this.hash(key); 106 | 107 | if (this.storage[index] === undefined){ 108 | console.log('key ==> ' + key + ' <== does not exist in hashTable'); 109 | } else { 110 | for (var i = 0; i < this.storage[index].length; i++){ 111 | if (this.storage[index][i][0] === key){ 112 | var temp = this.storage[index][i][1]; 113 | this.storage[index].splice(i, 1); 114 | this.size--; 115 | console.log(temp); 116 | this.resize(); 117 | return temp; 118 | } 119 | } 120 | console.log('key ==> ' + key + ' <== does not exist in hashTable'); 121 | } 122 | this.resize(); 123 | } 124 | 125 | hashTable.prototype.retrieve = function(key){ 126 | var index = this.hash(key); 127 | 128 | if (this.storage[index] === undefined){ 129 | console.log('key ==> ' + key + ' <== does not exist in hashTable'); 130 | return null; 131 | } else { 132 | for (var i = 0; i < this.storage[index].length; i++){ 133 | if (this.storage[index][i][0] === key){ 134 | return this.storage[index][i][1]; 135 | } 136 | } 137 | console.log('key ==> ' + key + ' <== does not exist in hashTable'); 138 | } 139 | } 140 | 141 | hashTable.prototype.resize = function(){ 142 | var allElements = []; 143 | if (this.size > (0.75 * this.buckets)){ 144 | this.buckets *= 2; 145 | this.storage.forEach(function(bucket){ 146 | if (bucket !== undefined){ 147 | bucket.forEach(function(tuple){ 148 | allElements.push(tuple); 149 | }) 150 | } 151 | }) 152 | 153 | this.storage = []; 154 | this.size = 0; 155 | 156 | allElements.forEach(function(tuple){ 157 | this.resizeInsert(tuple[0], tuple[1]); 158 | }, this) 159 | console.log('HashTable has been doubled in size'); 160 | } else if (this.buckets > 8 && this.size < (0.25 * this.buckets)){ 161 | this.buckets *= 0.5; 162 | this.storage.forEach(function(bucket){ 163 | if (bucket !== undefined){ 164 | bucket.forEach(function(tuple){ 165 | allElements.push(tuple); 166 | }) 167 | } 168 | }) 169 | 170 | this.storage = []; 171 | // this.size = 0; 172 | 173 | allElements.forEach(function(tuple){ 174 | this.resizeInsert(tuple[0], tuple[1]); 175 | }, this) 176 | console.log('HashTable has been halved in size'); 177 | } 178 | } 179 | 180 | 181 | 182 | 183 | //////////////////////////////////////////////////////////// 184 | /////////////// DO NOT TOUCH TEST BELOW!!! /////////////// 185 | //////////////////////////////////////////////////////////// 186 | 187 | var expect = require('chai').expect; 188 | 189 | describe('hash table class', function(){ 190 | 191 | describe('hashTable properties', function(){ 192 | it('should have properties storage, buckets, and size', function(){ 193 | var test = new hashTable(); 194 | 195 | expect(test).to.have.property('storage'); 196 | expect(test).to.have.property('buckets'); 197 | expect(test).to.have.property('size'); 198 | expect(test.storage.length).to.equal(0); 199 | expect(test.size).to.equal(0); 200 | }); 201 | }); 202 | 203 | describe('hashTable methods existence', function(){ 204 | it('should have methods hash, insert, delete, and retrieve', function(){ 205 | var test = new hashTable(); 206 | 207 | expect(test).to.respondTo('hash'); 208 | expect(test).to.respondTo('insert'); 209 | expect(test).to.respondTo('delete'); 210 | expect(test).to.respondTo('retrieve'); 211 | }); 212 | }); 213 | 214 | describe('hashTable hash method', function(){ 215 | it('should return an index from an inputted string', function(){ 216 | var test = new hashTable(); 217 | 218 | var expected = test.hash('hello'); 219 | expect(expected).to.equal(1); 220 | }) 221 | }); 222 | 223 | describe('hashTable insert method', function(){ 224 | it('should be able to insert a key-value pair', function(){ 225 | var test = new hashTable(); 226 | 227 | expect(test.storage.length).to.equal(0); 228 | expect(test.size).to.equal(0); 229 | 230 | test.insert('hello', 5); 231 | 232 | expect(test.size).to.equal(1); 233 | expect(test.storage[1][0][0]).to.equal('hello'); 234 | expect(test.storage[1][0][1]).to.equal(5); 235 | }); 236 | 237 | it('should be able to insert a second key-value pair', function(){ 238 | var test = new hashTable(); 239 | 240 | expect(test.storage.length).to.equal(0); 241 | expect(test.size).to.equal(0); 242 | 243 | test.insert('hello', 5); 244 | 245 | expect(test.size).to.equal(1); 246 | expect(test.storage[1][0][0]).to.equal('hello'); 247 | expect(test.storage[1][0][1]).to.equal(5); 248 | 249 | test.insert('good', 10); 250 | 251 | expect(test.size).to.equal(2); 252 | expect(test.storage[6][0][0]).to.equal('good'); 253 | expect(test.storage[6][0][1]).to.equal(10); 254 | }); 255 | 256 | it('should be able to handle collisions', function(){ 257 | var test = new hashTable(); 258 | 259 | expect(test.storage.length).to.equal(0); 260 | expect(test.size).to.equal(0); 261 | 262 | test.insert('good', 5); 263 | 264 | expect(test.size).to.equal(1); 265 | expect(test.storage[6][0][0]).to.equal('good'); 266 | expect(test.storage[6][0][1]).to.equal(5); 267 | 268 | test.insert('back', 10); 269 | 270 | expect(test.size).to.equal(2); 271 | expect(test.storage[6][1][0]).to.equal('back'); 272 | expect(test.storage[6][1][1]).to.equal(10); 273 | }); 274 | }); 275 | 276 | describe('hashTable delete method', function(){ 277 | it('should delete a key-value pair', function(){ 278 | var test = new hashTable(); 279 | 280 | expect(test.storage.length).to.equal(0); 281 | expect(test.size).to.equal(0); 282 | 283 | test.insert('hello', 5); 284 | 285 | expect(test.size).to.equal(1); 286 | expect(test.storage[1][0][0]).to.equal('hello'); 287 | expect(test.storage[1][0][1]).to.equal(5); 288 | 289 | test.delete('hello'); 290 | 291 | expect(test.size).to.equal(0); 292 | expect(test.storage[1][0]).to.equal(undefined); 293 | expect(test.storage[1][0]).to.equal(undefined); 294 | 295 | }); 296 | 297 | it('should not modify the size when deleting a key-value pair that does not exist', function(){ 298 | var test = new hashTable(); 299 | test.insert('hello', 5); 300 | test.insert('good', 10); 301 | 302 | expect(test.size).to.equal(2); 303 | 304 | test.delete('great'); 305 | 306 | expect(test.size).to.equal(2); 307 | }); 308 | }); 309 | describe('hashTable resize method', function(){ 310 | it('should double the number of buckets when the size exceeds 75% of buckets capacity', function(){ 311 | var test = new hashTable(); 312 | 313 | 314 | describe('hashTable retrieve method', function(){ 315 | it('should return true for a key-value pair that exists', function(){ 316 | var test = new hashTable(); 317 | 318 | test.insert('hello', 5); 319 | 320 | expect(test.retrieve('hello')).to.equal(5); 321 | 322 | 323 | }); 324 | 325 | it('should return false for a key-value pair that does not exist', function(){ 326 | var test = new hashTable(); 327 | 328 | test.insert('hello', 5); 329 | 330 | expect(test.retrieve('good')).to.equal(null); 331 | }); 332 | }); 333 | 334 | test.insert('hello', 5); 335 | test.insert('good', 7); 336 | test.insert('haha', 10); 337 | test.insert('blah', 2); 338 | test.insert('foo', 3); 339 | test.insert('bar', 8); 340 | test.insert('taste', 1); 341 | 342 | expect(test.buckets).to.equal(16); 343 | 344 | }); 345 | 346 | it('should halve the number of buckets when the size drops below 25% of bucket capacity', function(){ 347 | var test = new hashTable(); 348 | 349 | test.insert('hello', 5); 350 | test.insert('good', 7); 351 | test.insert('haha', 10); 352 | test.insert('blah', 2); 353 | test.insert('foo', 3); 354 | test.insert('bar', 8); 355 | test.insert('taste', 1); 356 | 357 | expect(test.buckets).to.equal(16); 358 | 359 | test.delete('hello'); 360 | test.delete('good'); 361 | test.delete('haha'); 362 | test.delete('blah'); 363 | 364 | expect(test.buckets).to.equal(8); 365 | 366 | }); 367 | }); 368 | }) 369 | -------------------------------------------------------------------------------- /Data Structures/Linked List/linkedList.js: -------------------------------------------------------------------------------- 1 | /********************************************************************************** 2 | * Homework IV * 3 | * * 4 | * Problem: Linked List * 5 | * * 6 | * Prompt: Create a Linked List class/constructor. * 7 | * Name it LinkedList (js) or Linked_List(rb/py). * 8 | * * 9 | * Part 1: Create a node class for your LinkedList. * 10 | * Your node class will take an integer value and output * 11 | * and output and object with the following properties: * 12 | * * 13 | * node.value: input value * 14 | * node.next: a pointer to the next value (initiall null) * 15 | * * 16 | * Example: { value: 1, next: null } * 17 | * * 18 | * Part 2: Create the LinkedList class. * 19 | * It should contain the following properties: * 20 | * * 21 | * head: pointer to the head node * 22 | * tail: pointer to the tail node * 23 | * length: number of nodes in the linked list * 24 | * * 25 | * The LinkedList should also contain the following properties * 26 | * * 27 | * append: function that adds a node to the tail * 28 | * * 29 | * insert: function that takes in two values, one to be inserted * 30 | * and one to search. It searches the list for the * 31 | * search value, and if found, adds a new node with the * 32 | * insert value after the node with the search value. * 33 | * * 34 | * delete: function that removes a node at a specified location, * 35 | * with a default action of deleting the head * 36 | * * 37 | * contains: function that checks to see if a value is contained * 38 | * in the list * 39 | * * 40 | * Input: N/A * 41 | * Output: A LinkedList instance * 42 | * * 43 | * What are the time and auxilliary space complexities of the various methods? * 44 | * * 45 | **********************************************************************************/ 46 | 47 | // listNode 48 | var listNode = function(value){ 49 | this.value = value; 50 | this.next = null; 51 | } 52 | 53 | // linkedList 54 | var linkedList = function(){ 55 | this.head = null; 56 | this.tail = null; 57 | this.listLength = 0; 58 | } 59 | 60 | // append method for linkedList 61 | linkedList.prototype.append = function(value) { 62 | // Initialize our linked list 63 | if ( this.listLength === 0) { 64 | this.head = new listNode(value); 65 | this.tail = this.head; 66 | } else { 67 | // adding value to a linked list with one or more 68 | this.tail.next = new listNode(value); 69 | this.tail = this.tail.next; 70 | } 71 | this.listLength++; 72 | } 73 | 74 | // insert method 75 | linkedList.prototype.insert = function(insertValue, searchValue) { 76 | var work = this.head; 77 | while (work !== null) { 78 | if (work.value === searchValue) { 79 | var reference = work.next; 80 | work.next = new listNode(insertValue); 81 | work.next.next = reference; 82 | 83 | if (reference === null) { 84 | // when the search value is the last element 85 | this.tail = work.next; 86 | } 87 | 88 | this.listLength++; 89 | return; 90 | } 91 | work = work.next; 92 | } 93 | console.log("searchValue " + searchValue + " was not found in linkedList"); 94 | } 95 | 96 | // delete method 97 | linkedList.prototype.delete = function(location) { 98 | // 1) when linkedList consists of single element 99 | if (location === 0 && this.listLength === 1) { 100 | this.head = null; 101 | this.tail = null; 102 | this.listLength--; 103 | return; 104 | } else if (location === 0) { 105 | // 2) when linkedList has more than 1 element but 106 | // we're still trying to remove the zeroth element 107 | this.head = this.head.next; 108 | this.listLength--; 109 | return; 110 | } 111 | 112 | var work = this.head; 113 | var counter = 0; 114 | 115 | while (work !== null) { 116 | // 3) when we're removing the last element of the linkedList 117 | if (counter === (location - 1) && work.next !== null && work.next === this.tail) { 118 | work.next = work.next.next; 119 | this.tail = work; 120 | this.listLength--; 121 | return; 122 | } else if (counter === (location - 1) && work.next !== null) { 123 | // 4) case when removing nodes that are neither the head or tail 124 | work.next = work.next.next; 125 | this.listLength--; 126 | return; 127 | } 128 | counter++; 129 | work = work.next; 130 | } 131 | // when location is out of our linkedIist range 132 | console.log('Error: Index ' + "'" + location + "'" + ' falls out of range of the linkedlist'); 133 | } 134 | 135 | // contains method 136 | linkedList.prototype.contains = function(value) { 137 | var work = this.head; 138 | while (work !== null) { 139 | if (work.value === value) { 140 | return true; 141 | } 142 | work = work.next; 143 | } 144 | return false; 145 | } 146 | 147 | //////////////////////////////////////////////////////////// 148 | /////////////// DO NOT TOUCH TEST BELOW!!! /////////////// 149 | //////////////////////////////////////////////////////////// 150 | 151 | var expect = require('chai').expect; 152 | 153 | describe('linked list node', function(){ 154 | 155 | describe('creation of a node', function(){ 156 | it('should exist: ', function(){ 157 | var test = new listNode(); 158 | 159 | expect(test).to.not.equal(undefined); 160 | }); 161 | }); 162 | 163 | describe('encoding a value', function(){ 164 | it('should store a value: ', function(){ 165 | var test = new listNode(); 166 | 167 | expect(test).to.have.property('value'); 168 | expect(test.value).to.equal(undefined); 169 | 170 | test.value = 3; 171 | 172 | expect(test.value).to.equal(3); 173 | }); 174 | }); 175 | 176 | describe('pointing to another node', function(){ 177 | it('should be able to point to another node: ', function(){ 178 | var initial = new listNode(5); 179 | var target = new listNode(10); 180 | 181 | expect(initial).to.have.property('value'); 182 | expect(initial).to.have.property('next'); 183 | expect(initial.next).to.equal(null); 184 | 185 | initial.next = target; 186 | 187 | expect(initial.next.value).to.equal(10); 188 | 189 | }) 190 | }) 191 | }) 192 | 193 | describe('linkedList class ', function(){ 194 | 195 | describe('linkedList properties', function(){ 196 | it('should have properties head, tail, and listLength', function(){ 197 | var test = new linkedList(); 198 | 199 | expect(test).to.have.property('head'); 200 | expect(test).to.have.property('tail'); 201 | expect(test).to.have.property('listLength'); 202 | expect(test.head).to.equal(null); 203 | expect(test.tail).to.equal(null); 204 | expect(test.listLength).to.equal(0); 205 | }); 206 | }); 207 | 208 | describe('linkedList methods existence', function(){ 209 | it('should have methods append, insert, delete, contains', function(){ 210 | var test = new linkedList(); 211 | 212 | expect(test).to.respondTo('append'); 213 | expect(test).to.respondTo('insert'); 214 | expect(test).to.respondTo('delete'); 215 | expect(test).to.respondTo('contains'); 216 | }); 217 | }); 218 | 219 | describe('linkedList append method', function(){ 220 | it('should be able to append a single node', function(){ 221 | var test = new linkedList(); 222 | 223 | expect(test.head).to.equal(null); 224 | expect(test.tail).to.equal(null); 225 | expect(test.listLength).to.equal(0); 226 | 227 | test.append(5); 228 | 229 | expect(test.head.value).to.equal(5); 230 | expect(test.tail.value).to.equal(5); 231 | expect(test.listLength).to.equal(1); 232 | }); 233 | 234 | it('should be able to append a second node', function(){ 235 | var test = new linkedList(); 236 | 237 | expect(test.head).to.equal(null); 238 | expect(test.tail).to.equal(null); 239 | expect(test.listLength).to.equal(0); 240 | 241 | test.append(5); 242 | 243 | expect(test.head.value).to.equal(5); 244 | expect(test.tail.value).to.equal(5); 245 | expect(test.listLength).to.equal(1); 246 | 247 | test.append(10); 248 | 249 | expect(test.head.value).to.equal(5); 250 | expect(test.tail.value).to.equal(10); 251 | expect(test.listLength).to.equal(2); 252 | }); 253 | }); 254 | 255 | describe('linkedList insert method', function(){ 256 | it('should be able to insert a node between two nodes', function(){ 257 | var test = new linkedList(); 258 | test.append(5); 259 | test.append(10); 260 | test.insert(13, 5); 261 | 262 | expect(test.head.value).to.equal(5); 263 | expect(test.head.next.value).to.equal(13); 264 | expect(test.head.next.next.value).to.equal(10); 265 | expect(test.tail.value).to.equal(10); 266 | }) 267 | 268 | it('should modify the linkedList tail if the search value is the tail value', function(){ 269 | var test = new linkedList(); 270 | test.append(5); 271 | test.append(10); 272 | test.insert(17, 10); 273 | 274 | expect(test.head.value).to.equal(5); 275 | expect(test.head.next.value).to.equal(10); 276 | expect(test.head.next.next.value).to.equal(17); 277 | expect(test.tail.value).to.equal(17); 278 | }) 279 | 280 | it('should not insert the value if the search value is not found', function(){ 281 | var test = new linkedList(); 282 | test.append(5); 283 | test.append(10); 284 | test.insert(12, 4); 285 | 286 | expect(test.head.value).to.equal(5); 287 | expect(test.head.next.value).to.equal(10); 288 | expect(test.tail.value).to.equal(10); 289 | expect(test.listLength).to.equal(2); 290 | }) 291 | }) 292 | 293 | describe('linkedList delete method', function(){ 294 | it('should delete a node in the middle of the linked list', function(){ 295 | var test = new linkedList(); 296 | test.append(5); 297 | test.append(10); 298 | test.append(15); 299 | test.delete(1); 300 | 301 | expect(test.head.value).to.equal(5); 302 | expect(test.tail.value).to.equal(15); 303 | expect(test.head.next.value).to.equal(15); 304 | expect(test.listLength).to.equal(2); 305 | }); 306 | 307 | it('should handle deleting the head value of the linked list', function(){ 308 | var test = new linkedList(); 309 | test.append(5); 310 | test.append(10); 311 | test.append(15); 312 | test.delete(0); 313 | 314 | expect(test.head.value).to.equal(10); 315 | expect(test.tail.value).to.equal(15); 316 | expect(test.head.next.value).to.equal(15); 317 | expect(test.listLength).to.equal(2); 318 | }); 319 | 320 | it('should handle deleting the tail value of the linked list', function(){ 321 | var test = new linkedList(); 322 | test.append(5); 323 | test.append(10); 324 | test.append(15); 325 | test.delete(2); 326 | 327 | expect(test.head.value).to.equal(5); 328 | expect(test.tail.value).to.equal(10); 329 | expect(test.head.next.value).to.equal(10); 330 | expect(test.listLength).to.equal(2); 331 | }); 332 | 333 | it('should not modify the linked list when attempting to delete a nonexistant node', function(){ 334 | var test = new linkedList(); 335 | test.append(5); 336 | test.append(10); 337 | test.append(15); 338 | test.delete(3); 339 | 340 | expect(test.head.value).to.equal(5); 341 | expect(test.tail.value).to.equal(15); 342 | expect(test.head.next.value).to.equal(10); 343 | expect(test.listLength).to.equal(3); 344 | }); 345 | }); 346 | 347 | describe('linkedList contains method', function(){ 348 | it('should return true when the target value exists in the linked list', function(){ 349 | var test = new linkedList(); 350 | test.append(5); 351 | test.append(109); 352 | 353 | expect(test.contains(5)).to.equal(true); 354 | }) 355 | 356 | it('should return false when the target value does not exist in the linked list', function(){ 357 | var test = new linkedList(); 358 | test.append(5); 359 | test.append(109); 360 | 361 | expect(test.contains(13)).to.equal(false); 362 | }) 363 | }) 364 | 365 | }) 366 | -------------------------------------------------------------------------------- /Data Structures/Graphs/graph.js: -------------------------------------------------------------------------------- 1 | /********************************************************************************** 2 | * Homework VIII * 3 | * * 4 | * Problem: Graph * 5 | * * 6 | * Prompt: Create a Graph class/constructor. * 7 | * Name it Graph (js) or graph (rb/py). * 8 | * * 9 | * The Graph will have the following properties: * 10 | * * 11 | * vertices: A hash/dictionary/object to store vertices. * 12 | * * 13 | * totalVertices: The total vertices in your Graph. * 14 | * * 15 | * totalEdges: The total edges among all vertices in your Graph. * 16 | * * 17 | * The Graph will also have the following methods: * 18 | * * 19 | * addVertex: Method that accepts an id (int/str), and creates an object * 20 | * with a "value" of id, and a property called "edges" which * 21 | * will store the edges of the vertex. If a vertex with the id* 22 | * already exists, then do not create a new vertex. * 23 | * * 24 | * getVertex: Method that takes an id, and outputs the vertex with the * 25 | * matching id, if it exists. * 26 | * * 27 | * removeVertex: Method that takes an id as its input, and removes the * 28 | * vertex with the matching id. * 29 | * * 30 | * addEdge: Method that accepts two different id's as its input, and * 31 | * creates an edge between both vertices. * 32 | * (This edge may look like [id1,id2]) * 33 | * * 34 | * removeEdge: Method that accepts two different id's as its input, and * 35 | * removes the edge between the two vertices if it exists. * 36 | * * 37 | * findNeighbors: Method that accepts an id as its input, and returns * 38 | * all of the edges of that vertex. * 39 | * * 40 | * forEachVertex: Method that accepts an operation, and performs that * 41 | * operation on each vertex in the Graph. * 42 | * * 43 | * Input: N/A * 44 | * Output: A Graph instance * 45 | * * 46 | * What are the time and auxilliary space complexities of the various methods? * 47 | * * 48 | **********************************************************************************/ 49 | 50 | 51 | /** 52 | * Extra Credit: forEachEdge 53 | * 54 | * Prompt: Method that accepts an operation, and performs that operation on each 55 | * edge in the Graph. 56 | **/ 57 | 58 | 59 | 60 | 61 | var Vertex = function(id){ 62 | this.value = id; 63 | this.edges = {}; 64 | } 65 | 66 | var Graph = function(){ 67 | this.vertices = {}; 68 | this.totalVertices = 0; 69 | this.totalEdges = 0; 70 | } 71 | 72 | Graph.prototype.addVertex = function(id) { 73 | // find out if the id does not exist 74 | if ( this.vertices[id] === undefined ){ 75 | var newVertex = new Vertex(id); 76 | this.vertices[id] = newVertex; 77 | this.totalVertices++; 78 | } 79 | } 80 | 81 | Graph.prototype.getVertex = function(id) { 82 | // find out if the id is defined 83 | if (this.vertices[id] !== undefined) { 84 | return this.vertices[id]; 85 | } else { 86 | console.log("The ID " + id + " does not exist"); 87 | } 88 | } 89 | 90 | Graph.prototype.addEdge = function(id1, id2){ 91 | // 1) check to see both id1 and id2 are not undefined 92 | if (this.vertices[id1] !== undefined && this.vertices[id2] !== undefined){ 93 | // 2) make sure the edge does not exist already 94 | if (this.vertices[id1].edges[id2] === undefined & this.vertices[id2].edges[id1] === undefined){ 95 | this.vertices[id1].edges[id2] = id2; 96 | this.vertices[id2].edges[id1] = id1; 97 | this.totalEdges++; 98 | } else { 99 | console.log("Edge already exists"); 100 | } 101 | } else { 102 | console.log("Either id1 or id2 or both doesn't exist in graph"); 103 | } 104 | } 105 | 106 | Graph.prototype.removeEdge = function(id1, id2){ 107 | // 1) check to see both id1 and id2 are not undefined 108 | if (this.vertices[id1] !== undefined && this.vertices[id2] !== undefined){ 109 | // 2) make sure the edge does exist already 110 | if (this.vertices[id1].edges[id2] !== undefined & this.vertices[id2].edges[id1] !== undefined){ 111 | delete this.vertices[id1].edges[id2]; 112 | delete this.vertices[id2].edges[id1]; 113 | this.totalEdges--; 114 | } else { 115 | console.log("Edge does not exists"); 116 | } 117 | } else { 118 | console.log("Either id1 or id2 or both doesn't exist in graph"); 119 | } 120 | } 121 | 122 | Graph.prototype.removeVertex = function(id) { 123 | // check the id exists 124 | if (this.vertices[id] !== undefined) { 125 | // delete the edges first 126 | var toDelete = this.vertices[id]; 127 | for (var edge in toDelete){ 128 | this.removeEdge(id, edge); 129 | } 130 | // delete the vertex 131 | delete this.vertices[id]; 132 | this.totalVertices--; 133 | } else { 134 | console.log("Vertex does not exists"); 135 | } 136 | } 137 | 138 | Graph.prototype.findNeighbors = function(id) { 139 | var neighbors = []; 140 | // check to make id exists 141 | if (this.vertices[id] !== undefined) { 142 | var edges = this.vertices[id].edges; 143 | for (var edge in edges) { 144 | neighbors.push(edge); 145 | } 146 | return neighbors; 147 | } else { 148 | console.log("Id does not exists"); 149 | } 150 | } 151 | 152 | Graph.prototype.forEachVertex = function(func){ 153 | for (vertexKey in this.vertices){ 154 | func(this.vertices[vertexKey]); 155 | } 156 | } 157 | 158 | Graph.prototype.forEachEdge = function(func) { 159 | for (vertexKey in this.vertices){ 160 | var vertex = this.vertices[vertexKey]; 161 | for (var edge in vertex.edges) { 162 | func(edge, vertex.value); 163 | } 164 | } 165 | } 166 | 167 | //////////////////////////////////////////////////////////// 168 | /////////////// DO NOT TOUCH TEST BELOW!!! /////////////// 169 | //////////////////////////////////////////////////////////// 170 | 171 | var expect = require('chai').expect; 172 | 173 | describe('graph class', function(){ 174 | 175 | describe('graph properties', function(){ 176 | it('should have properties vertices, totalVertices, and totalEdges', function(){ 177 | var test = new Graph(); 178 | 179 | expect(test).to.have.property('vertices'); 180 | expect(test).to.have.property('totalVertices'); 181 | expect(test).to.have.property('totalEdges'); 182 | expect(test.totalVertices).to.equal(0); 183 | expect(test.totalEdges).to.equal(0); 184 | }) 185 | }) 186 | 187 | describe('graph methods existence', function(){ 188 | it('should have methods addVertex, getVertex, removeVertex, addEdge, removeEdge, findNeighbors, and forEachVertex', function(){ 189 | var test = new Graph(); 190 | 191 | expect(test).to.respondTo('addVertex'); 192 | expect(test).to.respondTo('getVertex'); 193 | expect(test).to.respondTo('removeVertex'); 194 | expect(test).to.respondTo('addEdge'); 195 | expect(test).to.respondTo('removeEdge'); 196 | expect(test).to.respondTo('findNeighbors'); 197 | expect(test).to.respondTo('forEachVertex'); 198 | }) 199 | }) 200 | 201 | describe('graph addVertex method', function(){ 202 | it('should add a single vertex', function(){ 203 | var test = new Graph(); 204 | expect(test.vertices['hello']).to.equal(undefined); 205 | 206 | test.addVertex('hello'); 207 | expect(test.vertices['hello'].value).to.equal('hello'); 208 | expect(test.totalVertices).to.equal(1); 209 | }) 210 | 211 | it('should add two vertices', function(){ 212 | var test = new Graph(); 213 | expect(test.vertices['hello']).to.equal(undefined); 214 | 215 | test.addVertex('hello'); 216 | expect(test.vertices['hello'].value).to.equal('hello'); 217 | expect(test.totalVertices).to.equal(1); 218 | 219 | test.addVertex('good'); 220 | expect(test.vertices['good'].value).to.equal('good'); 221 | expect(test.totalVertices).to.equal(2); 222 | }) 223 | 224 | it('should not increase the totalVertices count when the vertex already exists', function(){ 225 | var test = new Graph(); 226 | expect(test.vertices['hello']).to.equal(undefined); 227 | 228 | test.addVertex('hello'); 229 | expect(test.vertices['hello'].value).to.equal('hello'); 230 | expect(test.totalVertices).to.equal(1); 231 | 232 | test.addVertex('hello'); 233 | expect(test.totalVertices).to.equal(1); 234 | }) 235 | }) 236 | 237 | describe('graph getVertex method', function(){ 238 | it('should return the entire vertex of the queried ID', function(){ 239 | var test = new Graph(); 240 | 241 | test.addVertex('hello'); 242 | var result = test.getVertex('hello'); 243 | 244 | expect(result.value).to.equal('hello'); 245 | expect(result).to.have.property('value'); 246 | expect(result).to.have.property('edges'); 247 | }) 248 | 249 | it('should return undefined when the vertex ID doesn not exist', function(){ 250 | var test = new Graph(); 251 | 252 | var result = test.getVertex('notHere'); 253 | 254 | expect(result).to.equal(undefined); 255 | }) 256 | }) 257 | 258 | describe('graph removeVertex method', function(){ 259 | it('should remove a vertex when deleted', function(){ 260 | var test = new Graph(); 261 | 262 | test.addVertex('hello'); 263 | expect(test.vertices['hello'].value).to.equal('hello'); 264 | expect(test.totalVertices).to.equal(1); 265 | 266 | test.removeVertex('hello'); 267 | expect(test.vertices['hello']).to.equal(undefined); 268 | }) 269 | }) 270 | 271 | describe('graph addEdge method', function(){ 272 | it('should create an edge between two vertices', function(){ 273 | var test = new Graph(); 274 | 275 | test.addVertex('hello'); 276 | test.addVertex('goodbye'); 277 | 278 | test.addEdge('hello', 'goodbye'); 279 | 280 | expect(test.vertices['hello'].edges['goodbye']).to.equal('goodbye'); 281 | expect(test.vertices['goodbye'].edges['hello']).to.equal('hello'); 282 | }) 283 | 284 | it('should increase the edge counter', function(){ 285 | var test = new Graph(); 286 | 287 | test.addVertex('hello'); 288 | test.addVertex('goodbye'); 289 | 290 | test.addEdge('hello', 'goodbye'); 291 | expect(test.totalEdges).to.equal(1); 292 | }) 293 | }) 294 | 295 | describe('graph removeEdge method', function(){ 296 | it('should remove an edge between two vertices', function(){ 297 | var test = new Graph(); 298 | 299 | test.addVertex('hello'); 300 | test.addVertex('goodbye'); 301 | 302 | test.addEdge('hello', 'goodbye'); 303 | 304 | expect(test.vertices['hello'].edges['goodbye']).to.equal('goodbye'); 305 | expect(test.vertices['goodbye'].edges['hello']).to.equal('hello'); 306 | 307 | test.removeEdge('hello', 'goodbye'); 308 | expect(test.vertices['hello'].edges['goodbye']).to.equal(undefined); 309 | expect(test.vertices['goodbye'].edges['hello']).to.equal(undefined); 310 | expect(test.totalEdges).to.equal(0); 311 | }) 312 | it('should not decrease the totalEdges counter when an edge does not exist between two vertices', function(){ 313 | var test = new Graph(); 314 | 315 | test.addVertex('hello'); 316 | test.addVertex('goodbye'); 317 | test.addVertex('blah'); 318 | 319 | test.addEdge('hello', 'goodbye'); 320 | 321 | expect(test.vertices['hello'].edges['goodbye']).to.equal('goodbye'); 322 | expect(test.vertices['goodbye'].edges['hello']).to.equal('hello'); 323 | 324 | test.removeEdge('hello', 'blah'); 325 | expect(test.totalEdges).to.equal(1); 326 | }) 327 | }) 328 | 329 | describe('graph findNeighbors method', function(){ 330 | it("should return an array of the neighbors' IDs", function(){ 331 | var test = new Graph(); 332 | 333 | test.addVertex('hello'); 334 | test.addVertex('goodbye'); 335 | test.addVertex('blah'); 336 | test.addVertex('haha'); 337 | 338 | test.addEdge('hello', 'goodbye'); 339 | test.addEdge('hello', 'blah'); 340 | 341 | expect(test.vertices['hello'].edges['goodbye']).to.equal('goodbye'); 342 | expect(test.vertices['goodbye'].edges['hello']).to.equal('hello'); 343 | expect(test.vertices['hello'].edges['blah']).to.equal('blah'); 344 | expect(test.vertices['blah'].edges['hello']).to.equal('hello'); 345 | 346 | var result = test.findNeighbors('hello'); 347 | expect(result).to.include('goodbye'); 348 | expect(result).to.include('blah'); 349 | }) 350 | 351 | it("should return an empty array when there's no edges", function(){ 352 | var test = new Graph(); 353 | 354 | test.addVertex('hello'); 355 | test.addVertex('goodbye'); 356 | test.addVertex('blah'); 357 | test.addVertex('haha'); 358 | 359 | test.addEdge('hello', 'goodbye'); 360 | test.addEdge('hello', 'blah'); 361 | 362 | var result = test.findNeighbors('haha'); 363 | expect(result.length).to.equal(0); 364 | }) 365 | }) 366 | 367 | describe('graph forEachNode method', function(){ 368 | it('should perform the callback on all of the nodes', function(){ 369 | // insert test here 370 | }) 371 | }) 372 | }) 373 | --------------------------------------------------------------------------------