├── faq.md ├── .gitignore ├── algos ├── .gitignore ├── level1 │ ├── week4 │ │ ├── gzan.index.js │ │ ├── katamatata_week4.index.js │ │ ├── KeepHydrated.md │ │ ├── katamatata_week4.test.js │ │ └── gzan.test.js │ ├── week5 │ │ ├── gzan.index.js │ │ ├── InvertValues.md │ │ └── gzan.test.js │ ├── week6 │ │ ├── gzan.index.js │ │ ├── gzan.test.js │ │ └── GenerateRangeOfIntegers.md │ ├── week11 │ │ ├── gzan.index.js │ │ ├── UnluckyDays.md │ │ └── gzan.test.js │ ├── week10 │ │ ├── ShortestWord.md │ │ ├── gzan.index.js │ │ └── gzan.test.js │ ├── week18 │ │ ├── gzan.index.js │ │ ├── FizzBuzz.md │ │ └── gzan.test.js │ ├── week7 │ │ ├── gzan.index.js │ │ ├── ValidSpacing.md │ │ └── gzan.test.js │ ├── week17 │ │ ├── MaxChar.md │ │ ├── gzan.test.js │ │ └── gzan.index.js │ ├── week3 │ │ ├── gzan.index.js │ │ ├── FillingAnArray.md │ │ └── gzan.test.js │ ├── week13 │ │ ├── gzan.index.js │ │ ├── StonesOnTheTable.md │ │ └── gzan.test.js │ ├── week16 │ │ ├── gzan.index.js │ │ ├── IntegerReversal.md │ │ └── gzan.test.js │ ├── week14 │ │ ├── StringReversal.md │ │ ├── gzan.test.js │ │ └── gzan.index.js │ ├── week2 │ │ ├── gzan.index.js │ │ ├── CelciusConverter.md │ │ └── gzan.test.js │ ├── week19 │ │ ├── ArrayChunk.md │ │ ├── gzan.index.js │ │ └── gzan.test.js │ ├── week20 │ │ ├── gzan.index.js │ │ ├── Anagrams.md │ │ └── gzan.test.js │ ├── week1 │ │ ├── gzan.index.js │ │ ├── AreaOrParameter.md │ │ └── gzan.test.js │ ├── week15 │ │ ├── gzan.index.js │ │ ├── Palindromes.md │ │ └── gzan.test.js │ ├── week8 │ │ ├── gzan.index.js │ │ ├── UglifyWord.md │ │ └── gzan.test.js │ ├── week12 │ │ ├── gzan.index.js │ │ ├── DuplicateSandwich.md │ │ └── gzan.test.js │ └── week9 │ │ ├── gzan.index.js │ │ ├── WhoIsTheKiller.md │ │ └── gzan.test.js ├── level2 │ ├── week1 │ │ ├── leli_week1.test.js │ │ ├── gzan.index.js │ │ ├── gzan.test.js │ │ ├── leli_week1.js │ │ └── DryingPotatoes.md │ ├── week16 │ │ ├── gzan.index.js │ │ ├── gzan.test.js │ │ └── Stack.md │ ├── week19 │ │ ├── robert.index.js │ │ ├── gzan.index.js │ │ ├── MidpointLinkedList.md │ │ ├── gzan.test.js │ │ ├── robert.test.js │ │ └── LinkedList.js │ ├── week11 │ │ ├── gzan.index.js │ │ ├── gzan.test.js │ │ └── SumOfParts.md │ ├── week12 │ │ ├── gzan.index.js │ │ ├── robert.index.js │ │ ├── robert.test.js │ │ ├── gzan.test.js │ │ └── Dubstep.md │ ├── week14 │ │ ├── gzan.index.js │ │ ├── robert.index.js │ │ ├── gzan.test.js │ │ ├── TheQueue.md │ │ └── robert.test.js │ ├── week3 │ │ ├── gzan.index.js │ │ ├── gzan.test.js │ │ └── TetrisScoringSystem.md │ ├── week8 │ │ ├── SortTheOdd.md │ │ ├── gzan.index.js │ │ └── gzan.test.js │ ├── week20 │ │ ├── gzan.index.js │ │ ├── robert.index.js │ │ ├── CircularList.md │ │ ├── gzan.test.js │ │ ├── robert.test.js │ │ └── LinkedList.js │ ├── week2 │ │ ├── gzan.index.js │ │ ├── leli_week2.test.js │ │ ├── BusTimer.md │ │ ├── gzan.test.js │ │ └── leli_week2.js │ ├── week17 │ │ ├── QueueFromStack.md │ │ ├── gzan.index.js │ │ ├── gzan.test.js │ │ ├── robert.index.js │ │ └── robert.test.js │ ├── week15 │ │ ├── gzan.queue.js │ │ ├── gzan.index.js │ │ ├── gzan.test.js │ │ └── UnderwaterQueueWeaving.md │ ├── week7 │ │ ├── gzan.index.js │ │ ├── robert.test.js │ │ ├── WordToInitialNumber.md │ │ ├── gzan.test.js │ │ └── robert.index.js │ ├── week6 │ │ ├── gzan.index.js │ │ ├── gzan.test.js │ │ └── MidtownNavigator.md │ ├── week5 │ │ ├── gzan.index.js │ │ ├── EncryptThis.md │ │ └── gzan.test.js │ ├── week9 │ │ ├── gzan.test.js │ │ ├── LoneliestCharacter.md │ │ └── gzan.index.js │ ├── week4 │ │ ├── gzan.index.js │ │ ├── gzan.test.js │ │ ├── FindCracker.md │ │ ├── robert.index.js │ │ └── robert.test.js │ ├── week13 │ │ ├── gzan.index.js │ │ ├── gzan.test.js │ │ └── CustomChristmasTree.md │ ├── week10 │ │ ├── gzan.index.js │ │ ├── gzan.test.js │ │ └── EliminationTournament.md │ └── week18 │ │ ├── LinkedList.md │ │ ├── gzan.index.js │ │ ├── robert.index.js │ │ ├── robert.test.js │ │ └── gzan.test.js ├── package.json └── README.md ├── timeline.md ├── student.md ├── weekly-scrum.md ├── course-map.md ├── README.md ├── cohort2020.md └── LICENSE.md └── LICENSE.md /faq.md: -------------------------------------------------------------------------------- 1 | tbd -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea/ 2 | -------------------------------------------------------------------------------- /algos/.gitignore: -------------------------------------------------------------------------------- 1 | **/node_modules -------------------------------------------------------------------------------- /algos/level1/week4/gzan.index.js: -------------------------------------------------------------------------------- 1 | function litres(time) { 2 | return Math.floor(time * 0.5); 3 | } 4 | 5 | module.exports = litres -------------------------------------------------------------------------------- /timeline.md: -------------------------------------------------------------------------------- 1 | # Timeline 2 | _newest event on top_ 3 | 4 | * #### 2020-08-11 Kick-Off Workshop 6:30 PM UTC+2 5 | 6 | * #### 2020-08-10 On-boarding and Q&A for students 7:00 PM UTC+2 7 | 8 | -------------------------------------------------------------------------------- /algos/level2/week1/leli_week1.test.js: -------------------------------------------------------------------------------- 1 | const potatoes = require('./leli_week1') 2 | 3 | describe('drying potatos', () => { 4 | test('example given', () => { 5 | expect(potatoes(99,100,98)).toBe(50) 6 | }) 7 | }) -------------------------------------------------------------------------------- /algos/level1/week5/gzan.index.js: -------------------------------------------------------------------------------- 1 | function invert(array) { 2 | //if number is zero return the number as itself if not multiply it with minus one 3 | return array.map(num => num !== 0 ? num * -1 : num); 4 | } 5 | 6 | module.exports = invert; -------------------------------------------------------------------------------- /algos/level1/week6/gzan.index.js: -------------------------------------------------------------------------------- 1 | function generateRange(min, max, step) { 2 | const arr = [] 3 | let i = min; 4 | while (i <= max) { 5 | arr.push(i); 6 | i = i + step; 7 | } 8 | return arr; 9 | } 10 | 11 | module.exports = generateRange -------------------------------------------------------------------------------- /algos/level1/week4/katamatata_week4.index.js: -------------------------------------------------------------------------------- 1 | const calculateNumberOfLiters = (time = 0) => { 2 | const totalLiters = time * 0.5; 3 | const roundedLiters = Math.floor(totalLiters); 4 | 5 | return roundedLiters; 6 | } 7 | 8 | module.exports = calculateNumberOfLiters; -------------------------------------------------------------------------------- /algos/level1/week11/gzan.index.js: -------------------------------------------------------------------------------- 1 | function unluckyDays(year) { 2 | let count = 0; 3 | for (let i = 0; i < 12; i++) { 4 | let date = new Date(year, i, 12); 5 | if (date.getDay() === 4) count++; 6 | } 7 | return count; 8 | } 9 | 10 | module.exports = unluckyDays 11 | 12 | -------------------------------------------------------------------------------- /algos/level1/week10/ShortestWord.md: -------------------------------------------------------------------------------- 1 | ### SHORTEST WORD 2 | 3 | Simple, given a string of words, return the length of the shortest word(s). 4 | 5 | String will never be empty and you do not need to account for different data types. 6 | 7 | #### Source: https://www.codewars.com/kata/57cebe1dc6fdc20c57000ac9 -------------------------------------------------------------------------------- /algos/level1/week18/gzan.index.js: -------------------------------------------------------------------------------- 1 | function fizzBuzz(n) { 2 | for (let i = 1; i <= n; i++) { 3 | if (i % 15 === 0) console.log("fizzbuzz") 4 | else if (i % 5 === 0) console.log("buzz") 5 | else if (i % 3 === 0) console.log("fizz") 6 | else console.log(i) 7 | } 8 | } 9 | 10 | module.exports = fizzBuzz -------------------------------------------------------------------------------- /algos/level1/week7/gzan.index.js: -------------------------------------------------------------------------------- 1 | function validSpacing(s) { 2 | const length = s.length; 3 | if (s[0] === ' ' || s[length - 1] === ' ') return false 4 | for (let i = 0; i < length; i++) { 5 | if (s[i] === ' ' && s[i + 1] === ' ') return false 6 | } 7 | return true 8 | } 9 | 10 | module.exports = validSpacing -------------------------------------------------------------------------------- /algos/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "algos", 3 | "version": "1.0.0", 4 | "description": "algorithmic problem solving", 5 | "main": "index.js", 6 | "dependencies": { 7 | "jest": "^26.4.2" 8 | }, 9 | "devDependencies": {}, 10 | "scripts": { 11 | "test": "jest" 12 | }, 13 | "author": "", 14 | "license": "ISC" 15 | } 16 | -------------------------------------------------------------------------------- /algos/level1/week17/MaxChar.md: -------------------------------------------------------------------------------- 1 | ### MAX CHAR 2 | 3 | #### Directions 4 | Given a string, return the character that is most commonly used in the string. 5 | 6 | 7 | #### Examples 8 | maxChar("abcccccccd") === "c" 9 | maxChar("apple 1231111") === "1" 10 | 11 | #### Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level1/week3/gzan.index.js: -------------------------------------------------------------------------------- 1 | //if the argument exists return an array with size of N and the keys spared for each element as the actual elements of the array 2 | //The keys will start from 0 and end with size-1, which applies the criteria given 3 | //if the arguments doesn't exist return a blank array 4 | const arr = N => N ? [...Array(N).keys()] : []; 5 | 6 | module.exports = arr; -------------------------------------------------------------------------------- /algos/level2/week16/gzan.index.js: -------------------------------------------------------------------------------- 1 | class Stack { 2 | constructor() { 3 | this.data = []; 4 | } 5 | 6 | push(record) { 7 | this.data.push(record); 8 | } 9 | 10 | pop() { 11 | return this.data.pop(); 12 | } 13 | 14 | peek() { 15 | return this.data[this.data.length - 1] 16 | } 17 | 18 | } 19 | 20 | const s = new Stack(); 21 | 22 | module.exports = Stack; -------------------------------------------------------------------------------- /algos/level1/week13/gzan.index.js: -------------------------------------------------------------------------------- 1 | function solve(stones) { 2 | let count = 0 3 | const length = stones.length 4 | for (let i = 1; i <= length; i++) { 5 | if (stones[i] === stones[i - 1]) count++ 6 | } 7 | return count 8 | } 9 | 10 | const solveWithRegEx = stones => stones.length - stones.replace(/(\w)(?=\1)/g, ``).length 11 | 12 | module.exports = { solve, solveWithRegEx }; -------------------------------------------------------------------------------- /algos/level2/week1/gzan.index.js: -------------------------------------------------------------------------------- 1 | function potatoes(waterP0, totalWeight0, waterP1) { 2 | // P0 for initial percentage, P1 for final percentage 3 | const dryMatterP0 = 100 - waterP0; 4 | const dryMatterP1 = 100 - waterP1; 5 | const totalWeight1 = totalWeight0 * dryMatterP0 / dryMatterP1; 6 | return Math.trunc(totalWeight1); 7 | } 8 | 9 | module.exports = potatoes; 10 | -------------------------------------------------------------------------------- /algos/level2/week19/robert.index.js: -------------------------------------------------------------------------------- 1 | let midpoint = (list) =>{ 2 | if(!list.head){ 3 | return null 4 | } 5 | let middleNode = list.head 6 | let lastNode = list.head 7 | while(lastNode.next && lastNode.next.next){ 8 | middleNode = middleNode.next 9 | lastNode = lastNode.next.next 10 | } 11 | return {data: middleNode.data} 12 | } 13 | 14 | module.exports = midpoint 15 | -------------------------------------------------------------------------------- /algos/level1/week16/gzan.index.js: -------------------------------------------------------------------------------- 1 | function reverseInt(n) { 2 | const reversed = n 3 | .toString() 4 | .split('') 5 | .reverse() 6 | .join(''); 7 | return parseInt(reversed) * Math.sign(n); 8 | } 9 | 10 | module.exports = reverseInt; 11 | 12 | 13 | 14 | //Source of the above solutions : The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level2/week11/gzan.index.js: -------------------------------------------------------------------------------- 1 | function partsSums(ls) { 2 | let sum = ls.reduce((a, b) => a + b, 0) 3 | console.log("sum", sum) 4 | let sums = [] 5 | sums.push(sum) 6 | let length = ls.length 7 | for (let i = 0; i < length; i++) { 8 | sum = sum - ls[i] 9 | sums.push(sum) 10 | console.log("sum", sum) 11 | } 12 | return sums 13 | } 14 | 15 | module.exports = partsSums 16 | -------------------------------------------------------------------------------- /algos/level1/week14/StringReversal.md: -------------------------------------------------------------------------------- 1 | ### REVERSE STRING 2 | 3 | #### Directions 4 | Given a string, return a new string with the reversed order of characters 5 | 6 | 7 | #### Examples 8 | reverse('apple') === 'leppa' 9 | reverse('hello') === 'olleh' 10 | reverse('Greetings!') === '!sgniteerG' 11 | 12 | #### Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level2/week12/gzan.index.js: -------------------------------------------------------------------------------- 1 | function songDecoder(song) { 2 | //apply regEx 3 | //replace WUB globally with space -> replace(/WUB/g, ' ') 4 | //when there is more then one space next to eachother, make it globally one in total -> replace(/ +/g, ' ') 5 | //remove heading and trailing spaces -> trim() 6 | return song.replace(/(WUB)+/g, ' ').trim() 7 | } 8 | 9 | module.exports = songDecoder 10 | 11 | -------------------------------------------------------------------------------- /algos/level1/week2/gzan.index.js: -------------------------------------------------------------------------------- 1 | function weatherInfo(temp) { 2 | var c = convertToCelsius(temp) 3 | if (c <= 0) 4 | return (c + " is freezing temperature") 5 | else 6 | return (c + " is above freezing temperature") 7 | } 8 | 9 | function convertToCelsius(temperature) { 10 | var celsius = (temperature - 32) * (5 / 9) 11 | return celsius 12 | } 13 | 14 | module.exports = { weatherInfo, convertToCelsius }; -------------------------------------------------------------------------------- /algos/level1/week3/FillingAnArray.md: -------------------------------------------------------------------------------- 1 | ## Filling An Array 2 | 3 | We want an array, but not just any old array, an array with contents! 4 | 5 | Write a function that produces an array with the numbers 0 to N-1 in it. 6 | 7 | For example, the following code will result in an array containing the numbers 0 to 4: 8 | 9 | `arr(5) // => [0,1,2,3,4]` 10 | 11 | #### Source: https://www.codewars.com/kata/571d42206414b103dc0006a1 12 | -------------------------------------------------------------------------------- /algos/level1/week19/ArrayChunk.md: -------------------------------------------------------------------------------- 1 | ### ARRAY CHUNK 2 | 3 | #### Directions 4 | Given an array and chunk size, divide the array into many subarrays 5 | where each subarray is of length size 6 | 7 | 8 | #### Examples 9 | chunk([1,2,3,4], 2) === [[1,2], [3,4]] 10 | chunk([1,2,3,4, 5], 2) === [[1,2], [3,4], [5]] 11 | 12 | 13 | 14 | #### Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level2/week14/gzan.index.js: -------------------------------------------------------------------------------- 1 | 2 | class Queue { 3 | constructor() { 4 | this.data = []; 5 | } 6 | add(record) { 7 | this.data.unshift(record); 8 | } 9 | remove() { 10 | //add return to be able to work with remove method 11 | return this.data.pop(); 12 | } 13 | 14 | } 15 | 16 | module.exports = Queue; 17 | 18 | //Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level1/week20/gzan.index.js: -------------------------------------------------------------------------------- 1 | function anagrams(stringA, stringB) { 2 | return cleanString(stringA) === cleanString(stringB); 3 | } 4 | 5 | function cleanString(str) { 6 | return str 7 | .replace(/[^\w]/g, '') 8 | .toLowerCase() 9 | .split('') 10 | .sort() 11 | .join(''); 12 | } 13 | 14 | module.exports = anagrams; 15 | 16 | //Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level1/week1/gzan.index.js: -------------------------------------------------------------------------------- 1 | function areaOrParameterLong(l, w) { 2 | if (l === w) { 3 | return l * w; 4 | } else { 5 | return (l + w) * 2; 6 | } 7 | } 8 | 9 | function areaOrParameterShort(l, w) { 10 | // if/else in JavaScript ES6 style 11 | // if length is equal to width, return the area, else the parameter 12 | return (l === w) ? l * w : (l + w) * 2; 13 | } 14 | 15 | module.exports = areaOrParameterShort; -------------------------------------------------------------------------------- /algos/level1/week16/IntegerReversal.md: -------------------------------------------------------------------------------- 1 | ### INTEGER REVERSAL 2 | 3 | #### Directions 4 | Given a string, return an integer that is the reverse ordering of numbers. 5 | 6 | 7 | #### Examples 8 | reverseInt(15) === 51 9 | reverseInt(981) === 189 10 | reverseInt(500) === 5 11 | reverseInt(-15) === -51 12 | reverseInt(-90) === -9 13 | 14 | 15 | #### Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level2/week19/gzan.index.js: -------------------------------------------------------------------------------- 1 | const List = require('./LinkedList') 2 | 3 | function midpoint(list) { 4 | let slow = list.getFirst(); 5 | let fast = list.getFirst(); 6 | 7 | while (fast.next && fast.next.next) { 8 | slow = slow.next; 9 | fast = fast.next.next; 10 | } 11 | 12 | return slow; 13 | } 14 | 15 | module.exports = midpoint; 16 | 17 | //Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level2/week3/gzan.index.js: -------------------------------------------------------------------------------- 1 | function getScore(arr) { 2 | let score = 0; 3 | let level = 0; 4 | let totalLines = 0; 5 | let points = { "0": 0, "1": 40, "2": 100, "3": 300, "4": 1200 } 6 | 7 | for (let lines of arr) { 8 | score += points[lines] * (level + 1) 9 | totalLines += lines 10 | if (totalLines >= 10) { 11 | level++ 12 | totalLines -= 10 13 | } 14 | } 15 | return score; 16 | } 17 | 18 | module.exports = getScore; -------------------------------------------------------------------------------- /algos/level2/week1/gzan.test.js: -------------------------------------------------------------------------------- 1 | const potatoes = require('./gzan.index.js'); 2 | 3 | test('potatoes function exists', () => { 4 | expect(typeof potatoes).toEqual('function'); 5 | }); 6 | 7 | describe('Logic', function () { 8 | it('should find the correct result', () => { 9 | expect(potatoes(99, 100, 98)).toEqual(50); 10 | expect(potatoes(82, 127, 80)).toEqual(114); 11 | expect(potatoes(93, 129, 91)).toEqual(100); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /algos/level1/week15/gzan.index.js: -------------------------------------------------------------------------------- 1 | // here one can use every solution we used for string reversal. 2 | // to check them out, go to the file algos/level1/week14/gzan.index.js 3 | 4 | function palindrome(str) { 5 | const reversed = str.split('').reverse().join(''); 6 | return str === reversed; 7 | } 8 | 9 | 10 | module.exports = palindrome 11 | 12 | 13 | //Source of the above solutions : The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level1/week17/gzan.test.js: -------------------------------------------------------------------------------- 1 | const maxChar = require('./gzan.index') 2 | 3 | test('maxChar function exists', () => { 4 | expect(maxChar).toBeDefined(); 5 | }); 6 | 7 | test('maxChar finds the character that is most commonly used in the string', () => { 8 | expect(maxChar("abcccccccd")).toEqual("c"); 9 | expect(maxChar("apple 1231111")).toEqual("1"); 10 | expect(maxChar("klmnhhhhzukskakuk")).toEqual("k"); 11 | expect(maxChar("12133333141")).toEqual("3"); 12 | }); -------------------------------------------------------------------------------- /algos/level2/week8/SortTheOdd.md: -------------------------------------------------------------------------------- 1 | ### SORT THE ODD 2 | 3 | You have an array of numbers. 4 | Your task is to sort ascending odd numbers but even numbers must be on their places. 5 | 6 | Zero isn't an odd number and you don't need to move it. If you have an empty array, you need to return it. 7 | 8 | #### Examples 9 | 10 | ```` 11 | sortArray([5, 3, 2, 8, 1, 4]) == [1, 3, 2, 8, 5, 4] 12 | 13 | ```` 14 | 15 | #### Source: https://www.codewars.com/kata/578aa45ee9fd15ff4600090d -------------------------------------------------------------------------------- /algos/level1/week5/InvertValues.md: -------------------------------------------------------------------------------- 1 | ### INVERT VALUES 2 | 3 | Given a set of numbers, return the additive inverse of each. Each positive becomes negatives, and the negatives become positives. 4 | 5 | ```` 6 | invert([1,2,3,4,5]) == [-1,-2,-3,-4,-5] 7 | invert([1,-2,3,-4,5]) == [-1,2,-3,4,-5] 8 | invert([]) == [] 9 | ```` 10 | 11 | You can assume that all values are integers. Do not mutate the input array/list. 12 | 13 | #### Source: https://www.codewars.com/kata/5899dc03bc95b1bf1b0000ad -------------------------------------------------------------------------------- /algos/level2/week20/gzan.index.js: -------------------------------------------------------------------------------- 1 | 2 | function circular(list) { 3 | let slow = list.getFirst(); 4 | let fast = list.getFirst(); 5 | 6 | while (fast.next && fast.next.next) { 7 | slow = slow.next; 8 | fast = fast.next.next; 9 | 10 | if (slow === fast) { 11 | return true; 12 | } 13 | } 14 | 15 | return false; 16 | } 17 | 18 | module.exports = circular; 19 | 20 | //Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level1/week8/gzan.index.js: -------------------------------------------------------------------------------- 1 | function uglifyWord(s) { 2 | let flag = true; 3 | let uglified = '' 4 | for (let char of s) { 5 | if (isLetter(char)) { 6 | uglified += flag ? char.toUpperCase() : char.toLowerCase() 7 | flag = !flag 8 | } else { 9 | uglified += char 10 | flag = true 11 | } 12 | } 13 | return uglified 14 | } 15 | 16 | function isLetter(char) { 17 | return (/[a-zA-Z]/).test(char) 18 | } 19 | 20 | module.exports = { uglifyWord, isLetter } -------------------------------------------------------------------------------- /algos/level1/week15/Palindromes.md: -------------------------------------------------------------------------------- 1 | ### PALINDROMES 2 | 3 | #### Directions 4 | Given a string, return true if the string is a palindrome or false if it is not. Palindromes are strings that form the same word if it is reversed. *Do* include spaces and punctuation in determining if the string is a palindrome. 5 | 6 | 7 | #### Examples 8 | palindrome("abba") === true 9 | palindrome("abcdefg") === false 10 | 11 | #### Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level1/week1/AreaOrParameter.md: -------------------------------------------------------------------------------- 1 | AREA OR PARAMETER 2 | 3 | You are given the length and width of a 4-sided polygon. The polygon can either be a rectangle or a square. 4 | If it is a square, return its area. If it is a rectangle, return its perimeter. 5 | 6 | area_or_perimeter(6, 10) --> 32 7 | area_or_perimeter(4, 4) --> 16 8 | 9 | Note: You will assume that it is a square if its length and width are equal, otherwise it is a rectangle. 10 | 11 | 12 | Source: https://www.codewars.com/kata/5ab6538b379d20ad880000ab -------------------------------------------------------------------------------- /algos/level1/week10/gzan.index.js: -------------------------------------------------------------------------------- 1 | //solution 1 2 | function findShortestWordLength(str) { 3 | const words = str.split(' ') 4 | let min = 0 5 | let length = 0 6 | for (let word of words) { 7 | length = word.length 8 | if (length < min || min === 0) min = length 9 | } 10 | return min 11 | } 12 | 13 | //solution 2 14 | 15 | function findShortest(str) { 16 | return Math.min.apply(null, str.split(' ').map(word => word.length)); 17 | } 18 | 19 | module.exports = { findShortestWordLength, findShortest } -------------------------------------------------------------------------------- /algos/level1/week3/gzan.test.js: -------------------------------------------------------------------------------- 1 | const arr = require('./gzan.index.js'); 2 | 3 | test('arr', () => { 4 | expect(arr).toBeDefined(); 5 | }); 6 | 7 | describe('arr', function () { 8 | it('should get correct array', function () { 9 | expect(arr(5)).toEqual([0, 1, 2, 3, 4]); 10 | expect(arr(0)).toEqual([]); 11 | expect(arr()).toEqual([]); 12 | expect(arr(14)).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]); 13 | expect(arr(1)).toEqual([0]); 14 | expect(arr(3)).toEqual([0, 1, 2]); 15 | }) 16 | }) -------------------------------------------------------------------------------- /algos/level2/week2/gzan.index.js: -------------------------------------------------------------------------------- 1 | function busTimer(time) { 2 | let [hours, minutes] = time.split(':').map(Number) 3 | let minuteDiff = 15 - minutes % 15 4 | if (hours < 6) { 5 | if (hours === 5 && minutes > 55) { 6 | return minuteDiff + 15 - 5 7 | } 8 | return (6 - hours) * 60 - minutes - 5 9 | } 10 | if (hours === 23 && minutes > 55) { 11 | return 6 * 60 + minuteDiff - 5 12 | } 13 | if (minuteDiff < 5) minuteDiff += 15 14 | return minuteDiff - 5 15 | } 16 | 17 | module.exports = busTimer 18 | -------------------------------------------------------------------------------- /algos/level1/week4/KeepHydrated.md: -------------------------------------------------------------------------------- 1 | ### KEEP HYDRATED! 2 | 3 | Nathan loves cycling. 4 | 5 | Because Nathan knows it is important to stay hydrated, he drinks 0.5 litres of water per hour of cycling. 6 | 7 | You get given the time in hours and you need to return the number of litres Nathan will drink, rounded to the smallest value. 8 | 9 | For example: 10 | 11 | `time = 3 ----> litres = 1` 12 | 13 | `time = 6.7---> litres = 3` 14 | 15 | `time = 11.8--> litres = 5` 16 | 17 | #### Source: https://www.codewars.com/kata/582cb0224e56e068d800003c -------------------------------------------------------------------------------- /algos/level1/week4/katamatata_week4.test.js: -------------------------------------------------------------------------------- 1 | const calculateNumberOfLiters = require('./katamatata_week4.index'); 2 | 3 | describe('calculateNumberOfLiters', () => { 4 | test('function is defined', () => { 5 | expect(typeof calculateNumberOfLiters).toEqual('function'); 6 | }) 7 | test('calculate the number of liters rounded to the smallest value', () => { 8 | expect(calculateNumberOfLiters(3)).toEqual(1); 9 | expect(calculateNumberOfLiters(6.7)).toEqual(3); 10 | expect(calculateNumberOfLiters(11.8)).toEqual(5); 11 | }); 12 | }); -------------------------------------------------------------------------------- /algos/level1/week16/gzan.test.js: -------------------------------------------------------------------------------- 1 | const reverseInt = require('./gzan.index') 2 | 3 | 4 | 5 | test('reverseInt function exists', () => { 6 | expect(reverseInt).toBeDefined(); 7 | }); 8 | 9 | test('reverseInt reverses n integer', () => { 10 | expect(reverseInt(123)).toEqual(321); 11 | expect(reverseInt(-51)).toEqual(-15); 12 | expect(reverseInt(500)).toEqual(5); 13 | expect(reverseInt(-940000)).toEqual(-49); 14 | }); 15 | 16 | //Source of the above solutions : The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level1/week11/UnluckyDays.md: -------------------------------------------------------------------------------- 1 | ### UNLUCKY DAYS 2 | 3 | Friday 13th or Black Friday is considered as unlucky day. Calculate how many unlucky days are in the given year. 4 | 5 | Find the number of Friday 13th in the given year. 6 | 7 | Input: Year as an integer. 8 | 9 | Output: Number of Black Fridays in the year as an integer. 10 | 11 | ### Examples: 12 | 13 | ```` 14 | unluckyDays(2015) == 3 15 | unluckyDays(1986) == 1 16 | Note: In Ruby years will start from 1593. 17 | ```` 18 | 19 | #### Source: https://www.codewars.com/kata/56eb0be52caf798c630013c0 -------------------------------------------------------------------------------- /algos/level1/week13/StonesOnTheTable.md: -------------------------------------------------------------------------------- 1 | ### STONES ON THE TABLE 2 | 3 | There are some stones on Bob's table in a row, and each of them can be red, green or blue, indicated by the characters R, G, and B. 4 | 5 | Help Bob find the minimum number of stones he needs to remove from the table so that the stones in each pair of adjacent stones have different colours. 6 | 7 | #### Examples: 8 | 9 | ```` 10 | "RGBRGBRGGB" => 1 11 | "RGGRGBBRGRR" => 3 12 | "RRRRGGGGBBBB" => 9 13 | ```` 14 | 15 | #### Source: https://www.codewars.com/kata/5f70e4cce10f9e0001c8995a -------------------------------------------------------------------------------- /algos/level1/week18/FizzBuzz.md: -------------------------------------------------------------------------------- 1 | ### FIZBUZZ 2 | 3 | #### Directions 4 | Write a program that console logs the numbers from 1 to n. 5 | But for multiples of **three**, print "fizz" instead of the number 6 | and for the multiples of **five**, print "buzz". 7 | For numbers which are multiples of **both three and five**, print "fizzbuzz" 8 | 9 | 10 | #### Examples 11 | fizzBuzz(5) returns 12 | 13 | ```` 14 | 1 15 | 2 16 | fizz 17 | 4 18 | buzz 19 | ```` 20 | 21 | 22 | #### Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level2/week17/QueueFromStack.md: -------------------------------------------------------------------------------- 1 | ### QUEUE FROM STACK 2 | 3 | #### Instructions: 4 | 5 | Implement a Queue data structure using two stacks 6 | 7 | - **Do not** create an array inside of the 'Queue' class. 8 | - The Queue should implement the methods 'add', 'remove' and 'peek' 9 | 10 | 11 | #### Example 12 | 13 | ```` 14 | const q = new Queue(); 15 | q.add(1); 16 | q.add(2); 17 | q.peek(); // returns 1 18 | q.remove(); // returns 1 19 | q.remove(); // returns 2 20 | 21 | ```` 22 | #### Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level2/week15/gzan.queue.js: -------------------------------------------------------------------------------- 1 | class Queue { 2 | constructor() { 3 | this.data = []; 4 | } 5 | add(record) { 6 | this.data.unshift(record); 7 | } 8 | remove() { 9 | return this.data.pop(); 10 | } 11 | peek() { 12 | return this.data[this.data.length - 1]; 13 | } 14 | 15 | } 16 | 17 | const uzu = new Queue() 18 | uzu.add(10); 19 | uzu.add(20); 20 | uzu.add(30); 21 | console.log(uzu.peek()) //10 22 | console.log(uzu) // [30,20,10] 23 | 24 | module.exports = Queue; 25 | 26 | //Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level1/week4/gzan.test.js: -------------------------------------------------------------------------------- 1 | const litres = require('./gzan.index.js'); 2 | 3 | test('litres function is defined', () => { 4 | expect(typeof litres).toEqual('function'); 5 | }); 6 | 7 | test('calculates the right amount of litres water from the hours given', () => { 8 | expect(litres(1.4)).toEqual(0); 9 | expect(litres(6.7)).toEqual(3); 10 | expect(litres(11.8)).toEqual(5); 11 | expect(litres(0.82)).toEqual(0); 12 | expect(litres(1787)).toEqual(893); 13 | expect(litres(12.3)).toEqual(6); 14 | expect(litres(0)).toEqual(0); 15 | expect(litres(12.3)).toEqual(6); 16 | }); 17 | 18 | 19 | -------------------------------------------------------------------------------- /algos/level2/week3/gzan.test.js: -------------------------------------------------------------------------------- 1 | const getScore = require('./gzan.index.js'); 2 | 3 | test('getScore', () => { 4 | expect(getScore).toBeDefined(); 5 | }); 6 | 7 | describe('getScore', function () { 8 | it('should get correct array', function () { 9 | expect(getScore([4, 2, 2, 3, 3, 4, 2])).toEqual(4900); 10 | expect(getScore([0, 1, 2, 3, 4])).toEqual(1640); 11 | expect(getScore([0, 1, 1, 3, 0, 2, 1, 2])).toEqual(620); 12 | expect(getScore([2, 0, 4, 2, 2, 3, 0, 0, 3, 3])).toEqual(3300); 13 | expect(getScore([0])).toEqual(0); 14 | expect(getScore([])).toEqual(0); 15 | 16 | }) 17 | }) -------------------------------------------------------------------------------- /algos/level1/week12/gzan.index.js: -------------------------------------------------------------------------------- 1 | function duplicateSandwich(a) { 2 | const length = a.length 3 | //save every item's index in itemMap 4 | let itemMap = {} 5 | for (let i = 0; i < length; i++) { 6 | //if this item already exists 7 | //the value of it will be the first index of the duplciate item 8 | // and i will be the last index 9 | //else save index of the item as its value 10 | if (a[i] in itemMap) { 11 | return a.slice(itemMap[a[i]] + 1, i, a) 12 | } else { 13 | itemMap[a[i]] = i 14 | } 15 | } 16 | } 17 | 18 | 19 | module.exports = duplicateSandwich 20 | 21 | -------------------------------------------------------------------------------- /algos/level2/week20/robert.index.js: -------------------------------------------------------------------------------- 1 | //DETERMINE IF A LINKED LIST IS A CYCLE OR NOT, SOLUTION WITH FLOYD'S CYCLE 2 | const circular = (list) =>{ 3 | if(!list.head){ 4 | return false 5 | } 6 | let slowPointer = list.head 7 | let fastPointer = list.head 8 | while(fastPointer.next && fastPointer.next.next){ 9 | slowPointer = slowPointer.next 10 | fastPointer = fastPointer.next.next 11 | if(slowPointer === fastPointer){ 12 | return true 13 | } 14 | } 15 | return false 16 | } 17 | 18 | module.exports = { 19 | circular 20 | } -------------------------------------------------------------------------------- /algos/level2/week11/gzan.test.js: -------------------------------------------------------------------------------- 1 | const partsSums = require('./gzan.index.js'); 2 | 3 | describe('Type', function () { 4 | it('should give function as type', () => { 5 | expect(typeof partsSums).toEqual('function'); 6 | }); 7 | }); 8 | 9 | describe('Logic', function () { 10 | it('should find the correct results', () => { 11 | expect(partsSums([0, 1, 3, 6, 10])).toEqual([20, 20, 19, 16, 10, 0]); 12 | expect(partsSums([])).toEqual([0]); 13 | expect(partsSums([1, 2, 3, 4, 5, 6])).toEqual([21, 20, 18, 15, 11, 6, 0]); 14 | expect(partsSums([3, 5, 15])).toEqual([23, 20, 15, 0]); 15 | }); 16 | }); -------------------------------------------------------------------------------- /algos/level2/week12/robert.index.js: -------------------------------------------------------------------------------- 1 | //WOULD HAVE BEEN A LOT EASIER IF I HAD JUST USED ".split()" ON THE STRING 2 | const songDecoder = (song) => { 3 | let outPut = '' 4 | let stringTobeChecked = song 5 | do { 6 | let i = stringTobeChecked.indexOf('WUB') 7 | if (i === -1) { 8 | outPut = outPut.trim() + ' ' + stringTobeChecked 9 | break 10 | } 11 | outPut = outPut.trim() + ' ' + stringTobeChecked.slice(0, i) 12 | stringTobeChecked = stringTobeChecked.slice(i + 3) 13 | } while (stringTobeChecked !== '') 14 | return outPut.trim() 15 | } 16 | module.exports = songDecoder 17 | -------------------------------------------------------------------------------- /algos/level1/week20/Anagrams.md: -------------------------------------------------------------------------------- 1 | ### ANAGRAMS 2 | 3 | #### Directions 4 | Check to see if two provided strigns are anagrams of each other. 5 | One string is an anagram of another if it uses the same characters in the same quantity. 6 | 7 | - Only consider characters, not spaces or punctuation 8 | - Consider capital letters to be the same as lower case 9 | 10 | 11 | #### Examples 12 | anagrams("rail safety", "fairy tales) === true 13 | anagrams("RAIL! SAFETY!", "fairy tales") === true 14 | anagrams("Hi there", "Bye there") === false 15 | 16 | #### Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level1/week5/gzan.test.js: -------------------------------------------------------------------------------- 1 | const invert = require('./gzan.index.js'); 2 | 3 | test('invert', () => { 4 | expect(invert).toBeDefined(); 5 | }); 6 | 7 | test('inverts an arr with mixed integers', () => { 8 | expect(invert([-1, 5, 10, -20, 30])).toEqual([1, -5, -10, 20, -30]); 9 | }); 10 | 11 | test('inverts an arr with mixed integers 2', () => { 12 | expect(invert([-100, -25, 0, 13])).toEqual([100, 25, 0, -13]); 13 | }); 14 | 15 | test('zero is returned as zero', () => { 16 | expect(invert([0])).toEqual([0]); 17 | }); 18 | 19 | test('empty arr is returned also as empty', () => { 20 | expect(invert([])).toEqual([]); 21 | }); 22 | 23 | 24 | -------------------------------------------------------------------------------- /algos/level2/week7/gzan.index.js: -------------------------------------------------------------------------------- 1 | function convert(s) { 2 | if (s === '') return 0 3 | const lowerS = s.toLowerCase() 4 | const letterMap = {} 5 | let nextDigit = 1; 6 | let result = '' 7 | for (let letter of lowerS) { 8 | if (letterMap[letter] !== undefined) { 9 | result += letterMap[letter] 10 | } 11 | else { 12 | letterMap[letter] = nextDigit 13 | result += nextDigit 14 | if (nextDigit !== 1 && nextDigit !== 0) nextDigit++ 15 | else if (nextDigit === 1) nextDigit = 0 16 | else if (nextDigit === 0) nextDigit = 2 17 | } 18 | 19 | } 20 | return parseInt(result) 21 | 22 | } 23 | module.exports = convert -------------------------------------------------------------------------------- /algos/level2/week14/robert.index.js: -------------------------------------------------------------------------------- 1 | class Queue { 2 | constructor(arrayOfValues) { 3 | this.values = arrayOfValues ? arrayOfValues : [] 4 | } 5 | add(value) { 6 | return this.values = [value, ...this.values] 7 | } 8 | remove() { 9 | const valueToBeDeleted = this.oldest() 10 | this.values = this.values.slice(0, this.values.length - 1); 11 | return valueToBeDeleted 12 | } 13 | oldest(){ 14 | return this.values[this.values.length - 1] 15 | } 16 | newest(){ 17 | return this.values[0] 18 | } 19 | size(){ 20 | return this.values.length 21 | } 22 | } 23 | module.exports = Queue; -------------------------------------------------------------------------------- /algos/level2/week6/gzan.index.js: -------------------------------------------------------------------------------- 1 | // more readable 2 | function midtownNav(start, end) { 3 | const startArr = start.split(' ') 4 | const endArr = end.split(' ') 5 | const streets = [parseInt(startArr[4]), parseInt(endArr[4])] 6 | const avenues = [parseInt(startArr[0]), parseInt(endArr[0])] 7 | const stCount = Math.abs(streets[0] - streets[1]) 8 | const avCount = Math.abs(avenues[0] - avenues[1]) 9 | const stDirection = streets[0] > streets[1] ? 'south' : 'north' 10 | const avDirection = avenues[0] > avenues[1] ? 'east' : 'west' 11 | return `Walk ${stCount} blocks ${stDirection}, and ${avCount} blocks ${avDirection}` 12 | } 13 | 14 | module.exports = midtownNav 15 | -------------------------------------------------------------------------------- /algos/level2/week5/gzan.index.js: -------------------------------------------------------------------------------- 1 | var encryptThis = function (text) { 2 | //convert string into array taking spaces as divisors 3 | const words = text.split(' '); 4 | let encrypted = ''; 5 | for (let word of words) { 6 | let code = '' 7 | if (word.length > 2) { 8 | let second = word[1] 9 | let last = word.slice(-1) 10 | code = word.charCodeAt(0) + last + word.slice(2, -1) + second 11 | } else if (word.length === 2) { 12 | code = word.charCodeAt(0) + word[1] 13 | } else { 14 | code = word.charCodeAt(0) || '' 15 | } 16 | encrypted += ' ' + code 17 | } 18 | return encrypted.slice(1); 19 | } 20 | 21 | module.exports = encryptThis -------------------------------------------------------------------------------- /algos/level1/week17/gzan.index.js: -------------------------------------------------------------------------------- 1 | function maxChar(str) { 2 | const charMap = {} 3 | let max = 0 4 | let maxChar = '' 5 | 6 | for (let char of str) { 7 | //if the next char already exits in charMap then increase its value by 1 8 | //if not, then assign 1 as its value 9 | charMap[char] = charMap[char] ? charMap[char] + 1 : 1 10 | } 11 | 12 | for (let char in charMap) { 13 | if (charMap[char] > max) { 14 | max = charMap[char] 15 | maxChar = char 16 | } 17 | } 18 | 19 | return maxChar 20 | } 21 | 22 | module.exports = maxChar 23 | 24 | //Source of the above solutions : The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level1/week6/gzan.test.js: -------------------------------------------------------------------------------- 1 | const generateRange = require('./gzan.index.js'); 2 | 3 | test('generateRange', () => { 4 | expect(generateRange).toBeDefined(); 5 | }); 6 | 7 | test('test 1', () => { 8 | expect(generateRange(2, 10, 2)).toEqual([2, 4, 6, 8, 10]); 9 | }); 10 | 11 | test('test 2', () => { 12 | expect(generateRange(1, 10, 5)).toEqual([1, 6]); 13 | }); 14 | 15 | test('test 3', () => { 16 | expect(generateRange(11, 44, 8)).toEqual([11, 19, 27, 35, 43]); 17 | }); 18 | 19 | test('test 4', () => { 20 | expect(generateRange(12, 130, 4)).toEqual([12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124, 128]); 21 | }); -------------------------------------------------------------------------------- /algos/level2/week19/MidpointLinkedList.md: -------------------------------------------------------------------------------- 1 | ### MIDPOINT OF A LINKED LIST 2 | 3 | #### Instructions: 4 | 5 | Return the 'middle' node of a linked list. 6 | If the list has an even number of elements, return the node at the end of the first half of the list. 7 | **Do not** use a counter variable, **do not** retrieve the size of the list 8 | and only iterate through the list one time 9 | 10 | 11 | #### Examples 12 | ```` 13 | const l = new LinkedList(); 14 | // l.insertLast('a') 15 | // l.insertLast('b') 16 | // l.insertLast('c') 17 | // midpoint(l); // returns { data: 'b' } 18 | 19 | ```` 20 | 21 | #### Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level1/week1/gzan.test.js: -------------------------------------------------------------------------------- 1 | const areaOrParameterShort = require('./gzan.index.js'); 2 | 3 | test('areaOrParameterShort function is defined', () => { 4 | expect(typeof areaOrParameterShort).toEqual('function'); 5 | }); 6 | 7 | test('calculates the area for squares', () => { 8 | expect(areaOrParameterShort(4, 4)).toEqual(16); 9 | expect(areaOrParameterShort(6, 6)).toEqual(36); 10 | expect(areaOrParameterShort(16, 16)).toEqual(256); 11 | }); 12 | 13 | test('calculates the parameter for rectangulars', () => { 14 | expect(areaOrParameterShort(6, 10)).toEqual(32); 15 | expect(areaOrParameterShort(10, 15)).toEqual(50); 16 | expect(areaOrParameterShort(80, 70)).toEqual(300); 17 | }); 18 | -------------------------------------------------------------------------------- /algos/level1/week6/GenerateRangeOfIntegers.md: -------------------------------------------------------------------------------- 1 | ### Generate Range of Integers 2 | 3 | Implement a function named generateRange(min, max, step), which takes three arguments and generates a range of integers from min to max, with the step. The first integer is the minimum value, the second is the maximum of the range and the third is the step. (min < max) 4 | 5 | Task 6 | Implement a function named 7 | ```` 8 | generateRange(2, 10, 2) // should return array of [2,4,6,8,10] 9 | generateRange(1, 10, 3) // should return array of [1,4,7,10] 10 | ```` 11 | 12 | Note 13 | - min < max 14 | - step > 0 15 | - the range does not HAVE to include max (depending on the step) 16 | 17 | #### Source: https://www.codewars.com/kata/55eca815d0d20962e1000106 -------------------------------------------------------------------------------- /algos/level1/week15/gzan.test.js: -------------------------------------------------------------------------------- 1 | const palindrome = require('./gzan.index') 2 | 3 | 4 | test('Check if function exists', () => { 5 | expect(palindrome).toBeDefined(); 6 | }); 7 | 8 | test('palindrome returns true if a string is a palindrome', () => { 9 | expect(palindrome('abba')).toBeTruthy(); 10 | expect(palindrome('aba')).toBeTruthy(); 11 | expect(palindrome('aba ')).toBeFalsy(); 12 | expect(palindrome('abcdefg')).toBeFalsy(); 13 | expect(palindrome('10000001')).toBeTruthy(); 14 | expect(palindrome('Fish hsif')).toBeFalsy(); 15 | expect(palindrome('pennep')).toBeTruthy(); 16 | }); 17 | 18 | 19 | //Source of the above solutions : The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy 20 | -------------------------------------------------------------------------------- /algos/level1/week12/DuplicateSandwich.md: -------------------------------------------------------------------------------- 1 | ### DUPLICATE SANDWICH 2 | 3 | #### Task 4 | You will be given a list consisting of unique elements except for one thing that appears twice. 5 | 6 | Your task is to output a list of everything inbetween both occurrences of this element in the list. 7 | 8 | #### Examples: 9 | 10 | ```` 11 | [0, 1, 2, 3, 4, 5, 6, 1, 7, 8] => [2, 3, 4, 5, 6] 12 | ["None", "Hello", "Example", "hello", "None", "Extra"] => ["Hello", "Example", "hello"] 13 | [0, 0] => [] 14 | [true, false, true] => [false] 15 | "example" => "xampl" 16 | ```` 17 | 18 | #### Notes 19 | All elements will be the same datatype. 20 | All used elements will be primitive. 21 | 22 | #### Source: https://www.codewars.com/kata/5f8a15c06dbd530016be0c19 -------------------------------------------------------------------------------- /algos/level2/week2/leli_week2.test.js: -------------------------------------------------------------------------------- 1 | const busTimer = require('./leli_week2') 2 | 3 | describe("week2: bus timer", () => { 4 | test("5:00 => 55", () => { 5 | expect(busTimer("05:00")).toBe(55) 6 | }) 7 | test("10:00 => 10", () => { 8 | expect(busTimer("10:00")).toBe(10) 9 | }) 10 | test("12:10 => 0", () => { 11 | expect(busTimer("12:10")).toBe(0) 12 | }) 13 | test("12:11 => 14", () => { 14 | expect(busTimer("12:11")).toBe(14) 15 | }) 16 | test("23:55 => 0", () => { 17 | expect(busTimer("23:55")).toBe(0) 18 | }) 19 | test("23:56 => 359", () => { 20 | expect(busTimer("23:56")).toBe(359) 21 | }) 22 | test("34:44", () =>{ 23 | expect(busTimer("34:44")).toBe("You have to give a valid time") 24 | }) 25 | }) -------------------------------------------------------------------------------- /algos/level2/week5/EncryptThis.md: -------------------------------------------------------------------------------- 1 | ### Encrypt this! 2 | 3 | You want to create secret messages which can be deciphered by the Decipher this! kata. Here are the conditions: 4 | 5 | 1. Your message is a string containing space separated words. 6 | 2. You need to encrypt each word in the message using the following rules: 7 | - The first letter needs to be converted to its ASCII code. 8 | - The second letter needs to be switched with the last letter 9 | 3. Keepin' it simple: There are no special characters in input. 10 | 11 | ''' 12 | encryptThis("Hello") === "72olle" 13 | encryptThis("good") === "103doo" 14 | encryptThis("hello world") === "104olle 119drlo" 15 | ''' 16 | 17 | #### Source: https://www.codewars.com/kata/5848565e273af816fb000449 18 | 19 | -------------------------------------------------------------------------------- /algos/level2/week9/gzan.test.js: -------------------------------------------------------------------------------- 1 | const loneliest = require('./gzan.index.js') 2 | 3 | describe('Type', function () { 4 | it('should give function as type', () => { 5 | expect(typeof loneliest).toEqual('function'); 6 | }); 7 | }); 8 | 9 | describe('Logic loneliest', function () { 10 | it('should give an array of letters with the max distance in boths sides ignoring leading and trailing spaces', () => { 11 | expect(loneliest('abc d ef g h i j ')).toEqual(['g']) 12 | expect(loneliest(' abc d z f gk s ')).toEqual(['z']) 13 | expect(loneliest('a b c ')).toEqual(['b']) 14 | expect(loneliest('a b c de ').sort()).toEqual(['b', 'c']) 15 | expect(loneliest('abc').sort()).toEqual(['a', 'b', 'c']) 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /algos/level2/week15/gzan.index.js: -------------------------------------------------------------------------------- 1 | const Queue = require('./gzan.queue'); 2 | 3 | function weave(sourceOne, sourceTwo) { 4 | const q = new Queue(); 5 | 6 | //iterate as long as one of the queues able to return an element 7 | while (sourceOne.peek() || sourceTwo.peek()) { 8 | //check if there is still element in the q through peek method 9 | //if yes, get the element at the beginning of the sourceOne queue and add it to the q 10 | //do the same for the source two 11 | if (sourceOne.peek()) q.add(sourceOne.remove()) 12 | if (sourceTwo.peek()) q.add(sourceTwo.remove()) 13 | } 14 | return q; 15 | } 16 | 17 | 18 | module.exports = weave; 19 | 20 | //Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level1/week9/gzan.index.js: -------------------------------------------------------------------------------- 1 | //long way 2 | function killerLong(suspectInfo, dead) { 3 | let suspects = Object.keys(suspectInfo) 4 | let countDead = dead.length 5 | let countMatch = 0 6 | for (let suspect of suspects) { 7 | if (suspectInfo[suspect].length > 0) { 8 | for (let name of dead) { 9 | if (suspectInfo[suspect].indexOf(name) === -1) { 10 | break 11 | } else { 12 | countMatch++ 13 | } 14 | } 15 | } 16 | if (countDead === countMatch) return suspect 17 | } 18 | } 19 | 20 | // short way 21 | function killerShort(suspectInfo, dead) { 22 | return Object.keys(suspectInfo).find(x => dead.every(y => suspectInfo[x].includes(y))) 23 | } 24 | 25 | 26 | 27 | module.exports = { killerShort, killerLong } 28 | -------------------------------------------------------------------------------- /algos/level2/week12/robert.test.js: -------------------------------------------------------------------------------- 1 | const songDecoder = require('./robert.index.js') 2 | 3 | describe('To ensure correct behaviour of the \"songDecoder\" function',()=>{ 4 | test('Function should be defined', () => { 5 | expect(songDecoder).toBeDefined(); 6 | }); 7 | test('that correct name is returned', () => { 8 | expect(songDecoder('WUBWUBIWUBBELIEVEWUBWUBIWUBCANWUBWUBFLY')).toEqual('I BELIEVE I CAN FLY') 9 | expect(songDecoder('WUBYOU\'REWUBWUBNEVERWUBFULLYWUBDRESSEDWUBWITHOUTWUBWUBWUBAWUBSMILE')).toEqual('YOU\'RE NEVER FULLY DRESSED WITHOUT A SMILE') 10 | expect(songDecoder('WUBWUBRADIOACTIVE')).toEqual('RADIOACTIVE') 11 | expect(songDecoder('NO WuB')).toEqual('NO WuB') 12 | expect(songDecoder('WUB')).toEqual('') 13 | }) 14 | }) -------------------------------------------------------------------------------- /algos/level1/week2/CelciusConverter.md: -------------------------------------------------------------------------------- 1 | Debug celsius converter 2 | 3 | Your friend is traveling abroad to the United States so he wrote a program to convert fahrenheit to celsius. Unfortunately his code has some bugs. 4 | 5 | Find the errors in the code to get the celsius converter working properly. 6 | 7 | To convert fahrenheit to celsius: 8 | 9 | celsius = (fahrenheit - 32) * (5/9) 10 | 11 | Remember that typically temperatures in the current weather conditions are given in whole numbers. It is possible for temperature sensors to report temperatures with a higher accuracy such as to the nearest tenth. Instrument error though makes this sort of accuracy unreliable for many types of temperature measuring sensors. 12 | 13 | Source: https://www.codewars.com/kata/55cb854deb36f11f130000e1 14 | 15 | -------------------------------------------------------------------------------- /algos/level2/week4/gzan.index.js: -------------------------------------------------------------------------------- 1 | function findHack(records) { 2 | const points = { "A": 30, "B": 20, "C": 10, "D": 5 } 3 | const highGrades = ["A", "B"] 4 | let names = []; 5 | 6 | for (let record of records) { 7 | let name = record[0] 8 | let total = record[1] 9 | let scores = record[2] 10 | if (total >= 200) { 11 | names.push(name); 12 | continue; 13 | } 14 | let realPoint = 0; 15 | let award = true; 16 | 17 | for (let score of scores) { 18 | if (points[score]) realPoint += points[score]; 19 | if (!highGrades.includes(score)) award = false; 20 | } 21 | 22 | if (award && scores.length >= 5) realPoint += 20; 23 | if (realPoint !== total) names.push(name); 24 | 25 | } 26 | return names; 27 | } 28 | 29 | module.exports = findHack; -------------------------------------------------------------------------------- /algos/level1/week9/WhoIsTheKiller.md: -------------------------------------------------------------------------------- 1 | ### Who is the killer? 2 | 3 | Some people have been killed! 4 | You have managed to narrow the suspects down to just a few. Luckily, you know every person who those suspects have seen on the day of the murders. 5 | 6 | #### Task. 7 | Given a dictionary with all the names of the suspects and everyone that they have seen on that day which may look like this: 8 | 9 | ```` 10 | {'James': ['Jacob', 'Bill', 'Lucas'], 11 | 'Johnny': ['David', 'Kyle', 'Lucas'], 12 | 'Peter': ['Lucy', 'Kyle']} 13 | ```` 14 | and also a list of the names of the dead people: 15 | 16 | ```` 17 | ['Lucas', 'Bill'] 18 | ```` 19 | return the name of the one killer, in our case 'James' because he is the only person that saw both 'Lucas' and 'Bill' 20 | 21 | #### Source: https://www.codewars.com/kata/5f709c8fb0d88300292a7a9d 22 | 23 | -------------------------------------------------------------------------------- /algos/level2/week4/gzan.test.js: -------------------------------------------------------------------------------- 1 | const findHack = require('./gzan.index.js'); 2 | 3 | test('findHack', () => { 4 | expect(findHack).toBeDefined(); 5 | }); 6 | 7 | test('findHack', () => { 8 | expect(findHack([ 9 | ["name1", 150, ["B", "A", "A", "C", "A", "A"]], 10 | ["name2", 120, ["B", "A", "A", "A"]], 11 | ["name3", 160, ["B", "A", "A", "A", "A"]], 12 | ["name4", 140, ["B", "A", "A", "C", "A"]] 13 | ])).toEqual(["name2", "name4"]); 14 | }); 15 | 16 | test('findHack 2', () => { 17 | expect(findHack([ 18 | ["udo", 85, ["C", "D", "F", "B", "B", "A"]], 19 | ["jacqueline", 120, ["B", "B", "B", "B", "B"]], 20 | ["volkan", 110, ["A", "A", "A"]], 21 | ["judith", 200, ["A", "A", "A", "A", "A", "A"]], 22 | ["merve", 105, ["B", "D", "A", "A", "B"]] 23 | ])).toEqual(["volkan", "judith"]); 24 | }); 25 | 26 | -------------------------------------------------------------------------------- /algos/level2/week1/leli_week1.js: -------------------------------------------------------------------------------- 1 | /* 2 | algoweek etki 3 | leli 4 | */ 5 | 6 | const potatoes = (p0, w0, p1) => { 7 | // percent in decimal numbers 8 | const waterPercent0 = p0 / 100 9 | const waterPercent1 = p1 / 100 10 | const dirtPercent0 = 1 - waterPercent0 11 | const dirtPercent1 = 1 - waterPercent1 12 | 13 | // weight of the water and dirt seperatly for beginning 14 | const waterWeight0 = w0 * waterPercent0 15 | const dirtWeight = w0 * dirtPercent0 16 | 17 | // the dirtweight stays the same since we only evaporate water 18 | // at the end the same amount of dirt makes up a larger percentage of the weight 19 | const weight1 = w0 * dirtPercent0 / dirtPercent1 20 | 21 | return weight1 22 | } 23 | 24 | const potatoesWithoutComments = (p0, w0, p1) => Math.round(w0 * (100 - p0) / (100 - p1)) 25 | module.exports = potatoes -------------------------------------------------------------------------------- /algos/level2/week20/CircularList.md: -------------------------------------------------------------------------------- 1 | ### CIRCULAR LIST 2 | 3 | #### Instructions: 4 | 5 | Given a linked list, return true if list is circular, false if it is not. 6 | As mentioned in earlier exercises, linked list has a head, which is the first node and a tail, which returns to a value of null. 7 | A list is a circular when there is no tail node and the last node points out an earlier node within the linked list isntead to a value of null. 8 | 9 | 10 | #### Examples 11 | ```` 12 | const l = new List(); 13 | // const a = new Node('a'); 14 | // const b = new Node('b'); 15 | // const c = new Node('c'); 16 | // l.head = a; 17 | // a.next = b; 18 | // b.next = c; 19 | // c.next = b; 20 | // circular(l) // true 21 | 22 | ```` 23 | 24 | #### Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level2/week9/LoneliestCharacter.md: -------------------------------------------------------------------------------- 1 | ### LONELIEST CHARACTER 2 | 3 | Complete the function which accepts a string and return an array of character(s) that have the most spaces to their right and left. 4 | 5 | #### Notes: 6 | 7 | the string can have leading/trailing spaces - you should not count them 8 | the strings contain only unique characters from a to z 9 | the order of characters in the returned array doesn"t matter 10 | 11 | #### Examples 12 | 13 | ```` 14 | "a b c" --> ["b"] 15 | "a bcs d k" --> ["d"] 16 | " a b sc p t k" --> ["p"] 17 | "a b c de" --> ["b", "c"] 18 | " a b c de " --> ["b"] 19 | "abc" --> ["a", "b", "c"] 20 | ```` 21 | 22 | #### Source: https://www.codewars.com/kata/5f885fa9f130ea00207c7dc8 -------------------------------------------------------------------------------- /algos/level1/week12/gzan.test.js: -------------------------------------------------------------------------------- 1 | const duplicateSandwich = require('./gzan.index.js') 2 | 3 | 4 | describe('Type', function () { 5 | it('should give function as type', () => { 6 | expect(typeof duplicateSandwich).toEqual('function'); 7 | }); 8 | }); 9 | 10 | describe('Logic', function () { 11 | it('should find the items in between the duplicated items', () => { 12 | expect(duplicateSandwich([0, 1, 2, 3, 4, 5, 6, 1, 7, 8])).toEqual([2, 3, 4, 5, 6]); 13 | expect(duplicateSandwich(["None", "Hello", "Example", "hello", "None", "Extra"])).toEqual(["Hello", "Example", "hello"]); 14 | expect(duplicateSandwich([0, 1, 2, 3, 4, 5, 3])).toEqual([4, 5]); 15 | expect(duplicateSandwich(["item1", "item2", "item3", "item4", "item2", "item5", "item6"])).toEqual(["item3", "item4"]); 16 | expect(duplicateSandwich([5, 3, 5, 6])).toEqual([3]); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /algos/level2/week7/robert.test.js: -------------------------------------------------------------------------------- 1 | const convert = require('./robert.index') 2 | 3 | describe('Check that the function gives the correct output for different test cases', function () { 4 | test('Function should be defined', () => { 5 | expect(convert).toBeDefined(); 6 | }); 7 | test('should return the correct output for a string', () => { 8 | expect(convert('HippoPoPtamus')).toEqual(1022323245678); 9 | }); 10 | test('should return the correct output for an empty string', () => { 11 | expect(convert('')).toEqual(0); 12 | }); 13 | test('should return the correct output for a string with all characters uniform', () => { 14 | expect(convert('cCc')).toEqual(111); 15 | }); 16 | test('should return the correct output for a string with only one character', () => { 17 | expect(convert('a')).toEqual(1); 18 | }); 19 | }) -------------------------------------------------------------------------------- /algos/level2/week7/WordToInitialNumber.md: -------------------------------------------------------------------------------- 1 | ### WORD TO INITIAL NUMBER 2 | 3 | #### Task: 4 | Your task is to write the word to number converter. Digits in the number should match letters in the word. Plus generated number should be the smallest possible number you can get. 5 | 6 | - Words will contain of maximum 10 distinct letters, but word can be any length, even longer than 10 characters long. 7 | - Number can NOT start with 0 8 | - Same letters share the same digit regardless of case 9 | - For empty string return 0 10 | 11 | 12 | Examples: 13 | ```` 14 | "A" -> 1 - OK 15 | 16 | "ABA" -> 353 - WRONG ( number is OK, but it's not the smallest number ) 17 | 18 | "ABA" -> 333 - WRONG ( different letters map to same digits ) 19 | 20 | "ABA" -> 357 - WRONG ( same letters map to different digits ) 21 | 22 | 23 | ````` 24 | 25 | #### Source: https://www.codewars.com/kata/5bb148b840196d1be50000b1 26 | -------------------------------------------------------------------------------- /algos/level1/week14/gzan.test.js: -------------------------------------------------------------------------------- 1 | const reverseSolution1 = require('./gzan.index').reverseSolution1 2 | const reverseSolution2 = require('./gzan.index').reverseSolution2 3 | const reverseSolution3 = require('./gzan.index').reverseSolution3 4 | const reverseSolution3Short = require('./gzan.index').reverseSolution3Short 5 | 6 | 7 | test('Reverse function exists', () => { 8 | expect(reverseSolution1).toBeDefined(); 9 | expect(reverseSolution2).toBeDefined(); 10 | expect(reverseSolution3).toBeDefined(); 11 | expect(reverseSolution3Short).toBeDefined(); 12 | }); 13 | 14 | test('Reverse reverses a string', () => { 15 | expect(reverseSolution1(' abcd')).toEqual('dcba '); 16 | expect(reverseSolution2('reverse')).toEqual('esrever'); 17 | expect(reverseSolution3('123456789')).toEqual('987654321'); 18 | expect(reverseSolution3Short('etki Tech Network')).toEqual('krowteN hceT ikte'); 19 | }); 20 | 21 | -------------------------------------------------------------------------------- /algos/level2/week6/gzan.test.js: -------------------------------------------------------------------------------- 1 | const midtownNav = require('./gzan.index.js') 2 | 3 | 4 | test('midtownNav', () => { 5 | expect(midtownNav).toBeDefined(); 6 | }); 7 | 8 | test('gives the correct direction', () => { 9 | expect(midtownNav('8th Ave and W 38th St', '7th Ave and W 36th St')).toEqual('Walk 2 blocks south, and 1 blocks east'); 10 | }); 11 | 12 | test('gives the correct direction', () => { 13 | expect(midtownNav('5th Ave and W 46th St', '7th Ave and E 58th St')).toEqual('Walk 12 blocks north, and 2 blocks west'); 14 | }); 15 | 16 | test('gives the correct direction', () => { 17 | expect(midtownNav('3th Ave and W 212th St', '11th Ave and W 200th St')).toEqual('Walk 12 blocks south, and 8 blocks west'); 18 | }); 19 | 20 | test('gives the correct direction', () => { 21 | expect(midtownNav('9th Ave and W 23th St', '6th Ave and E 25th St')).toEqual('Walk 2 blocks north, and 3 blocks east'); 22 | }); -------------------------------------------------------------------------------- /algos/level1/week2/gzan.test.js: -------------------------------------------------------------------------------- 1 | const weatherInfo = require('./gzan.index.js').weatherInfo; 2 | const convertToCelsius = require('./gzan.index.js').convertToCelsius; 3 | 4 | test('weatherInfo exists', () => { 5 | expect(weatherInfo).toBeDefined(); 6 | }); 7 | 8 | test('convertToCelsius exists', () => { 9 | expect(convertToCelsius).toBeDefined(); 10 | }); 11 | 12 | describe('weatherInfo', function () { 13 | it('should get correct answer', function () { 14 | expect(convertToCelsius(50)).toEqual(10); 15 | expect(convertToCelsius(23)).toEqual(-5); 16 | }) 17 | }) 18 | 19 | describe('weatherInfo exists', function () { 20 | it('should get correct answer', function () { 21 | expect(weatherInfo(50)).toEqual('10 is above freezing temperature'); 22 | expect(weatherInfo(23)).toEqual('-5 is freezing temperature'); 23 | expect(weatherInfo(95)).toEqual('35 is above freezing temperature'); 24 | }) 25 | }) -------------------------------------------------------------------------------- /algos/level1/week11/gzan.test.js: -------------------------------------------------------------------------------- 1 | const unluckyDays = require('./gzan.index.js'); 2 | 3 | describe('Type', function () { 4 | it('should give function as type', () => { 5 | expect(typeof unluckyDays).toEqual('function'); 6 | }); 7 | }); 8 | 9 | describe('Logic', function () { 10 | it('should find how many unlucky days in the given year', () => { 11 | expect(unluckyDays(2020)).toEqual(2); 12 | expect(unluckyDays(2019)).toEqual(2); 13 | expect(unluckyDays(2016)).toEqual(1); 14 | expect(unluckyDays(2015)).toEqual(3); 15 | expect(unluckyDays(1986)).toEqual(1); 16 | expect(unluckyDays(1985)).toEqual(2); 17 | expect(unluckyDays(1982)).toEqual(1); 18 | expect(unluckyDays(1957)).toEqual(2); 19 | expect(unluckyDays(1948)).toEqual(2); 20 | expect(unluckyDays(1001)).toEqual(3); 21 | expect(unluckyDays(2065)).toEqual(3); 22 | expect(unluckyDays(2021)).toEqual(1); 23 | }); 24 | }); -------------------------------------------------------------------------------- /algos/level2/week14/gzan.test.js: -------------------------------------------------------------------------------- 1 | const Queue = require('./gzan.index'); 2 | 3 | test('Queue is a class', () => { 4 | expect(typeof Queue.prototype.constructor).toEqual('function'); 5 | }); 6 | 7 | test('can add elements to a queue', () => { 8 | const q = new Queue(); 9 | expect(() => { 10 | q.add(1); 11 | }).not.toThrow(); 12 | }); 13 | 14 | test('can remove elements from a queue', () => { 15 | const q = new Queue(); 16 | expect(() => { 17 | q.add(1); 18 | q.remove(); 19 | }).not.toThrow(); 20 | }); 21 | 22 | test('Order of elements is maintained', () => { 23 | const q = new Queue(); 24 | q.add(1); 25 | q.add(2); 26 | q.add(3); 27 | expect(q.remove()).toEqual(1); 28 | expect(q.remove()).toEqual(2); 29 | expect(q.remove()).toEqual(3); 30 | expect(q.remove()).toEqual(undefined); 31 | }); 32 | 33 | //Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level1/week7/ValidSpacing.md: -------------------------------------------------------------------------------- 1 | ### Valid Spacing 2 | 3 | Your task is to write a function called valid_spacing() or validSpacing() which checks if a string has valid spacing. The function should return either True or False. 4 | 5 | For this kata, the definition of valid spacing is one space between words, and no leading or trailing spaces. Below are some examples of what the function should return. 6 | 7 | ```` 8 | 'Hello world' = true 9 | ' Hello world' = false 10 | 'Hello world ' = false 11 | 'Hello world' = false 12 | 'Hello' = true 13 | // Even though there are no spaces, it is still valid because none are needed 14 | 'Helloworld' = true 15 | // true because we are not checking for the validity of words. 16 | ' ' = false 17 | '' = true 18 | ```` 19 | 20 | Note - there will be no punctuation or digits in the input string, only letters. 21 | 22 | #### Source: https://www.codewars.com/kata/5f77d62851f6bc0033616bd8 23 | 24 | -------------------------------------------------------------------------------- /algos/level2/week12/gzan.test.js: -------------------------------------------------------------------------------- 1 | const songDecoder = require('./gzan.index.js') 2 | 3 | 4 | describe('Type', function () { 5 | it('should give function as type', () => { 6 | expect(typeof songDecoder).toEqual('function'); 7 | }); 8 | }); 9 | 10 | describe('Logic', function () { 11 | it('should return a str without "WUB"s amnd multiple/trailing/heading spaces', () => { 12 | expect(songDecoder("WUBAWUBBWUBC")).toEqual("A B C"); 13 | expect(songDecoder("WUBAWUBBWUBCWUB")).toEqual("A B C"); 14 | expect(songDecoder("AWUBWUBWUBBWUBWUBWUBC")).toEqual("A B C"); 15 | expect(songDecoder("WUBWEWUBAREWUBWUBTHEWUBCHAMPIONSWUBMYWUBFRIENDWUB")).toEqual("WE ARE THE CHAMPIONS MY FRIEND"); 16 | expect(songDecoder("WUBWUBWUBANOTHERWUBONEWUBWUBBITESWUBTHEWUBWUBWUBDUST")).toEqual("ANOTHER ONE BITES THE DUST"); 17 | expect(songDecoder("IWUBWUBWANTWUBTOWUBWUBWUBWUBBREAKWUBFREEWUBWUBWUB")).toEqual("I WANT TO BREAK FREE"); 18 | }); 19 | }); -------------------------------------------------------------------------------- /algos/level2/week13/gzan.index.js: -------------------------------------------------------------------------------- 1 | function customChristmasTree(chars, n) { 2 | let tree = '' 3 | let row = 0; 4 | let leave = 1; 5 | let char = 0; 6 | const length = chars.length 7 | //the crown 8 | while (row < n) { 9 | for (let i = 0; i < (n - leave); i++) { 10 | tree += ' ' 11 | } 12 | for (let j = 0; j < leave; j++) { 13 | tree += chars[char] 14 | char++ 15 | if (char === length) char = 0 16 | if (j !== leave - 1) tree += ' ' 17 | } 18 | tree += '\n' 19 | leave++ 20 | row++ 21 | if (leave === n + 1) break; 22 | } 23 | //the trunk 24 | const nOfTrunks = Math.floor(n / 3) 25 | let rowTrunk = 0; 26 | while (rowTrunk < nOfTrunks) { 27 | for (let k = 0; k < n - 1; k++) { 28 | tree += ' ' 29 | 30 | } 31 | tree += rowTrunk < nOfTrunks - 1 ? '|\n' : '|' 32 | rowTrunk++ 33 | } 34 | return tree 35 | } 36 | 37 | module.exports = customChristmasTree; -------------------------------------------------------------------------------- /algos/level2/week11/SumOfParts.md: -------------------------------------------------------------------------------- 1 | ### SUM OF PARTS 2 | 3 | Let us consider this example (array written in general format): 4 | ```` 5 | ls = [0, 1, 3, 6, 10] 6 | ```` 7 | 8 | Its following parts: 9 | ```` 10 | ls = [0, 1, 3, 6, 10] 11 | ls = [1, 3, 6, 10] 12 | ls = [3, 6, 10] 13 | ls = [6, 10] 14 | ls = [10] 15 | ls = [] 16 | The corresponding sums are (put together in a list): [20, 20, 19, 16, 10, 0] 17 | ```` 18 | 19 | The function ```partsSums``` will take as parameter a list ```ls``` and return a list of the sums of its parts as defined above. 20 | 21 | #### Other Examples: 22 | ```` 23 | ls = [1, 2, 3, 4, 5, 6] 24 | partsSums(ls) -> [21, 20, 18, 15, 11, 6, 0] 25 | 26 | ls = [744125, 935, 407, 454, 430, 90, 144, 6710213, 889, 810, 2579358] 27 | partsSums(ls) -> [10037855, 9293730, 9292795, 9292388, 9291934, 9291504, 9291414, 9291270, 2581057, 2580168, 2579358, 0] 28 | ```` 29 | 30 | #### Source: https://www.codewars.com/kata/5ce399e0047a45001c853c2b 31 | -------------------------------------------------------------------------------- /algos/level1/week19/gzan.index.js: -------------------------------------------------------------------------------- 1 | function chunk(array, size) { 2 | const subarrays = []; 3 | let i = 0; 4 | 5 | while (i < array.length) { 6 | subarrays.push(array.slice(i, i + size)); 7 | i += size; 8 | } 9 | 10 | return subarrays; 11 | } 12 | 13 | 14 | 15 | //below is a longer and less efficent way that also works 16 | // function chunk(array, size) { 17 | // let subarrays = []; 18 | // let subarray = []; 19 | // let i = 0; 20 | // while (i < array.length) { 21 | // for (let j = 0; j < size; j++) { 22 | // if (array[i]) { 23 | // subarray.push(array[i]) 24 | // i++ 25 | // } else { 26 | // break 27 | // } 28 | 29 | // } 30 | // subarrays.push(subarray) 31 | // subarray = []; 32 | // } 33 | // return subarrays; 34 | // } 35 | 36 | 37 | module.exports = chunk 38 | 39 | //Source of the above solutions : The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level2/week17/gzan.index.js: -------------------------------------------------------------------------------- 1 | const Stack = require('../week16/gzan.index'); 2 | 3 | 4 | class Queue { 5 | constructor() { 6 | this.first = new Stack() 7 | this.second = new Stack() 8 | } 9 | 10 | add(record) { 11 | this.first.push(record) 12 | } 13 | 14 | remove() { 15 | while (this.first.peek()) { 16 | this.second.push(this.first.pop()) 17 | } 18 | 19 | const removed = this.second.pop() 20 | 21 | while (this.second.peek()) { 22 | this.first.push(this.second.pop()) 23 | } 24 | return removed 25 | } 26 | 27 | peek() { 28 | while (this.first.peek()) { 29 | this.second.push(this.first.pop()) 30 | } 31 | const record = this.second.peek() 32 | while (this.second.peek()) { 33 | this.first.push(this.second.pop()) 34 | } 35 | return record 36 | } 37 | } 38 | 39 | module.exports = Queue 40 | 41 | // Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level2/week2/BusTimer.md: -------------------------------------------------------------------------------- 1 | BUS TIMER 2 | 3 | It's been a tough week at work and you are stuggling to get out of bed in the morning. 4 | 5 | While waiting at the bus stop you realise that if you could time your arrival to the nearest minute you could get valuable extra minutes in bed. 6 | 7 | There is a bus that goes to your office every 15 minute, the first bus is at 06:00, and the last bus is at 00:00. 8 | 9 | Given that it takes 5 minutes to walk from your front door to the bus stop, implement a function that when given the curent time will tell you much time is left, before you must leave to catch the next bus. 10 | 11 | Examples 12 | "05:00" => 55 13 | "10:00" => 10 14 | "12:10" => 0 15 | "12:11" => 14 16 | Notes 17 | Return the number of minutes till the next bus 18 | Input will be formatted as HH:MM (24-hour clock) 19 | The input time might be after the buses have stopped running, i.e. after 00:00 20 | 21 | source: https://www.codewars.com/kata/5736378e3f3dfd5a820000cb -------------------------------------------------------------------------------- /algos/level2/week10/gzan.index.js: -------------------------------------------------------------------------------- 1 | const tourneyLoops = array => { 2 | let allResults = [] 3 | allResults.push(array) 4 | let current = array 5 | //const condition = allResults.length <= (array.length + 1) / 2 6 | while (true) { 7 | let result = [] 8 | let length = current.length 9 | for (let i = 0; i < length; i += 2) { 10 | if (i === length - 1) result.unshift(current[i]) 11 | else { result.push(Math.max(current[i], current[i + 1])) } 12 | } 13 | allResults.push(result) 14 | if (result.length === 1) return allResults 15 | current = result 16 | } 17 | } 18 | 19 | const tourneyRecursive = array => { 20 | if (array.length === 1) 21 | return [array]; 22 | 23 | let next = array.length % 2 ? array.slice(-1) : []; 24 | for (let i = 0; i < array.length - 1; i += 2) 25 | next.push(Math.max(array[i], array[i + 1])); 26 | 27 | return [array].concat(tourneyRecursive(next)); 28 | } 29 | 30 | module.exports = { tourneyLoops, tourneyRecursive } -------------------------------------------------------------------------------- /algos/level1/week7/gzan.test.js: -------------------------------------------------------------------------------- 1 | const validSpacing = require('./gzan.index.js'); 2 | 3 | test('validSpacing', () => { 4 | expect(validSpacing).toBeDefined(); 5 | }); 6 | 7 | test('empty space', () => { 8 | expect(validSpacing(' ')).toBeFalsy(); 9 | }); 10 | test('empty string', () => { 11 | expect(validSpacing('')).toBeTruthy(); 12 | }); 13 | 14 | test('2 words with 1 space in between', () => { 15 | expect(validSpacing('Hello World')).toBeTruthy(); 16 | }); 17 | 18 | test('Space in the wrong place but amount is correct', () => { 19 | expect(validSpacing('HelloW orld')).toBeTruthy(); 20 | }); 21 | 22 | test('meaningless letters', () => { 23 | expect(validSpacing('FIz hH jKS')).toBeTruthy(); 24 | }); 25 | 26 | test('space at the end', () => { 27 | expect(validSpacing('The world is a stage ')).toBeFalsy(); 28 | }); 29 | 30 | test('space at the beginning', () => { 31 | expect(validSpacing(' JavaScript is the world\'s most misunderstood programming language.')).toBeFalsy(); 32 | }); 33 | -------------------------------------------------------------------------------- /algos/level2/week7/gzan.test.js: -------------------------------------------------------------------------------- 1 | const convert = require('./gzan.index.js') 2 | 3 | 4 | test('convert', () => { 5 | expect(convert).toBeDefined(); 6 | }); 7 | 8 | test('example 1', () => { 9 | expect(convert('A')).toEqual(1); 10 | }); 11 | 12 | test('example 2', () => { 13 | expect(convert('ABA')).toEqual(101); 14 | }); 15 | 16 | test('codewars sample test 1', () => { 17 | expect(convert('CodeWars')).toEqual(10234567); 18 | }); 19 | 20 | test('codewars sample test 2', () => { 21 | expect(convert('KATa')).toEqual(1020); 22 | }); 23 | 24 | test('test 1', () => { 25 | expect(convert('JavaScript')).toEqual(1020345678); 26 | }); 27 | 28 | test('test 2', () => { 29 | expect(convert('Hello')).toEqual(10223); 30 | }); 31 | 32 | test('test 3', () => { 33 | expect(convert('World')).toEqual(10234); 34 | }); 35 | 36 | test('test 4', () => { 37 | expect(convert('etki')).toEqual(1023); 38 | }); 39 | 40 | test('test 5', () => { 41 | expect(convert('letter')).toEqual(102203); 42 | }); 43 | 44 | -------------------------------------------------------------------------------- /algos/level2/week17/gzan.test.js: -------------------------------------------------------------------------------- 1 | const Queue = require('./gzan.index') 2 | 3 | test('Queue is a class', () => { 4 | expect(typeof Queue.prototype.constructor).toEqual('function'); 5 | }); 6 | 7 | test('can add elements to a queue', () => { 8 | const q = new Queue(); 9 | expect(() => { 10 | q.add(1); 11 | }).not.toThrow(); 12 | }); 13 | 14 | test('can remove elements from a queue', () => { 15 | const q = new Queue(); 16 | expect(() => { 17 | q.add(1); 18 | q.remove(); 19 | }).not.toThrow(); 20 | }); 21 | 22 | test('Order of elements is maintained', () => { 23 | const q = new Queue(); 24 | q.add(1); 25 | q.add(2); 26 | q.add(3); 27 | expect(q.peek()).toEqual(1); 28 | expect(q.remove()).toEqual(1); 29 | expect(q.peek()).toEqual(2); 30 | expect(q.remove()).toEqual(2); 31 | expect(q.remove()).toEqual(3); 32 | expect(q.remove()).toEqual(undefined); 33 | }); 34 | 35 | //Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy 36 | 37 | -------------------------------------------------------------------------------- /algos/level2/week14/TheQueue.md: -------------------------------------------------------------------------------- 1 | ### THE QUEUE 2 | 3 | #### About the queue: 4 | - a data structure based on FIFO Principle (**F**irst **I**n **F**irst **O**ut) 5 | - **enqueuing:** adding a new record to the beginning of the Queue (first index) 6 | - **dequeuing:** removing the oldest record from the Queue (last index) 7 | 8 | #### Instructions: 9 | 10 | Create a queue data structure (class Queue) 11 | 12 | - The queue should be a class with methods 'add' and 'remove' 13 | - Adding to the queue should store an element until it is removed 14 | 15 | #### Example 16 | 17 | ```` 18 | const q = new Queue(); 19 | q.add(1); 20 | q.remove(); // returns 1 21 | ```` 22 | 23 | #### Here is the basic structure of the class for you to fill in: 24 | ```` 25 | class Queue { 26 | constructor() { 27 | 28 | } 29 | 30 | add(record) { 31 | 32 | 33 | } 34 | 35 | remove() { 36 | 37 | } 38 | 39 | } 40 | ```` 41 | 42 | #### Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level1/week20/gzan.test.js: -------------------------------------------------------------------------------- 1 | const anagrams = require('./gzan.index.js'); 2 | 3 | test('anagrams function exists', () => { 4 | expect(typeof anagrams).toEqual('function'); 5 | }); 6 | 7 | test('"hello" is an anagram of "llohe"', () => { 8 | expect(anagrams('hello', 'llohe')).toBeTruthy(); 9 | }); 10 | 11 | test('"Whoa! Hi!" is an anagram of "Hi! Whoa!"', () => { 12 | expect(anagrams('Whoa! Hi!', 'Hi! Whoa!')).toBeTruthy(); 13 | }); 14 | 15 | test('"One One" is not an anagram of "Two two two"', () => { 16 | expect(anagrams('One One', 'Two two two')).toBeFalsy(); 17 | }); 18 | 19 | test('"One one" is not an anagram of "One one c"', () => { 20 | expect(anagrams('One one', 'One one c')).toBeFalsy(); 21 | }); 22 | 23 | test('"A tree, a life, a bench" is not an anagram of "A tree, a fence, a yard"', () => { 24 | expect( 25 | anagrams('A tree, a life, a bench', 'A tree, a fence, a yard') 26 | ).toBeFalsy(); 27 | }); 28 | 29 | //Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level2/week2/gzan.test.js: -------------------------------------------------------------------------------- 1 | const busTimer = require('./gzan.index.js'); 2 | 3 | test('busTimer function exists', () => { 4 | expect(typeof busTimer).toEqual('function'); 5 | }); 6 | 7 | describe('Logic', function () { 8 | it('should find the correct result', () => { 9 | expect(busTimer('00:00')).toEqual(355); 10 | expect(busTimer('06:10')).toEqual(0); 11 | expect(busTimer('23:57')).toEqual(358); 12 | expect(busTimer('05:59')).toEqual(11); 13 | expect(busTimer('00:15')).toEqual(340); 14 | expect(busTimer('04:30')).toEqual(85); 15 | expect(busTimer('08:00')).toEqual(10); 16 | expect(busTimer('10:06')).toEqual(4); 17 | expect(busTimer('13:33')).toEqual(7); 18 | expect(busTimer('18:57')).toEqual(13); 19 | expect(busTimer('20:05')).toEqual(5); 20 | expect(busTimer('05:22')).toEqual(33); 21 | expect(busTimer('23:48')).toEqual(7); 22 | expect(busTimer('09:29')).toEqual(11); 23 | expect(busTimer('11:01')).toEqual(9); 24 | expect(busTimer('05:41')).toEqual(14); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /algos/level2/week1/DryingPotatoes.md: -------------------------------------------------------------------------------- 1 | DRYING POTATOES 2 | 3 | All we eat is water and dry matter. 4 | 5 | John bought potatoes: their weight is 100 kilograms. Potatoes contain water and dry matter. 6 | 7 | The water content is 99 percent of the total weight. He thinks they are too wet and puts them in an oven - at low temperature - for them to lose some water. 8 | 9 | At the output the water content is only 98%. 10 | 11 | What is the total weight in kilograms (water content plus dry matter) coming out of the oven? 12 | 13 | He finds 50 kilograms and he thinks he made a mistake: "So much weight lost for such a small change in water content!" 14 | 15 | Can you help him? 16 | 17 | Write function potatoes with 18 | 19 | int parameter p0 - initial percent of water- 20 | int parameter w0 - initial weight - 21 | int parameter p1 - final percent of water - 22 | potatoesshould return the final weight coming out of the oven w1 truncated as an int. 23 | 24 | Example: 25 | potatoes(99, 100, 98) --> 50 26 | 27 | Source: https://www.codewars.com/kata/58ce8725c835848ad6000007 28 | -------------------------------------------------------------------------------- /algos/level1/week14/gzan.index.js: -------------------------------------------------------------------------------- 1 | // SOLUTION 1 2 | //// 1. Turn string into an array 3 | //// 2. Reverse the elements within the array 4 | //// 3. Turn the array back into a string 5 | function reverseSolution1(str) { 6 | return str.split('').reverse().join(''); 7 | } 8 | 9 | 10 | // SOLUTION 2 11 | function reverseSolution2(str) { 12 | 13 | let reversed = ''; 14 | for (let char of str) { 15 | reversed = char + reversed; 16 | 17 | } 18 | return reversed; 19 | 20 | } 21 | 22 | // solution with es6 23 | function reverseSolution3(str) { 24 | return str.split('').reduce((reversed, character) => { 25 | return character + reversed 26 | }, '') 27 | } 28 | 29 | 30 | // condensed version of the above solution 31 | function reverseSolution3Short(str) { 32 | return str.split('').reduce((rev, char) => char + rev, '') 33 | } 34 | 35 | module.exports = { reverseSolution1, reverseSolution2, reverseSolution3, reverseSolution3Short }; 36 | 37 | //Source of the above solutions : The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level2/week17/robert.index.js: -------------------------------------------------------------------------------- 1 | const Stack = require('../week16/gzan.index'); 2 | 3 | //CORRECTIONS COPIED FROM GZAN'S 4 | // Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy 5 | 6 | class Queue { 7 | constructor() { 8 | this.first = new Stack() 9 | this.second = new Stack() 10 | } 11 | 12 | add(record) { 13 | this.first.push(record) 14 | } 15 | 16 | remove() { 17 | while (this.first.peek()) { 18 | this.second.push(this.first.pop()) 19 | } 20 | 21 | const removed = this.second.pop() 22 | 23 | while (this.second.peek()) { 24 | this.first.push(this.second.pop()) 25 | } 26 | return removed 27 | } 28 | 29 | peek() { 30 | while (this.first.peek()) { 31 | this.second.push(this.first.pop()) 32 | } 33 | const record = this.second.peek() 34 | while (this.second.peek()) { 35 | this.first.push(this.second.pop()) 36 | } 37 | return record 38 | } 39 | } 40 | 41 | 42 | module.exports = Queue; 43 | 44 | -------------------------------------------------------------------------------- /algos/level1/week13/gzan.test.js: -------------------------------------------------------------------------------- 1 | const solve = require('./gzan.index.js').solve; 2 | const solveWithRegEx = require('./gzan.index.js').solveWithRegEx; 3 | 4 | describe('Type', function () { 5 | it('should give function as type', () => { 6 | expect(typeof solve).toEqual('function'); 7 | expect(typeof solveWithRegEx).toEqual('function'); 8 | }); 9 | }); 10 | 11 | describe('Logic', function () { 12 | it('should find how many chars should be removed', () => { 13 | expect(solve('RRGGBB')).toEqual(3); 14 | expect(solve("RGBRGB")).toEqual(0); 15 | expect(solve("BGRBBGGBRRR")).toEqual(4); 16 | expect(solve("GBBBGGRRGRB")).toEqual(4); 17 | expect(solve("GBRGGRBBBBRRGGGB")).toEqual(7); 18 | }); 19 | }); 20 | 21 | describe('Logic', function () { 22 | it('should find how many chars should be removed', () => { 23 | expect(solveWithRegEx('RRGGBB')).toEqual(3); 24 | expect(solveWithRegEx("RGBRGB")).toEqual(0); 25 | expect(solveWithRegEx("BGRBBGGBRRR")).toEqual(4); 26 | expect(solveWithRegEx("GBBBGGRRGRB")).toEqual(4); 27 | expect(solveWithRegEx("GBRGGRBBBBRRGGGB")).toEqual(7); 28 | }); 29 | }); -------------------------------------------------------------------------------- /algos/level2/week9/gzan.index.js: -------------------------------------------------------------------------------- 1 | function loneliest(str) { 2 | let length = str.length 3 | let count = 0 4 | let dict = {} 5 | let newLetter = '' 6 | for (let i = 0; i < length; i++) { 7 | if (str[i] !== ' ') { 8 | //check if the spaces so far are not leading space, otherwise ignore 9 | if (newLetter !== '') { 10 | //count is the right count of the previous char 11 | //add the count to the value of the char 12 | //if it is the first char, it wouldn' have already been added 13 | //in this case assign the key directly to the count 14 | dict[newLetter] = dict[newLetter] + count || count 15 | } 16 | newLetter = str[i] 17 | //the count is the left count of the next letter 18 | //assign it as its current value 19 | dict[newLetter] = count 20 | count = 0 21 | } else if (newLetter !== '') { 22 | //if next char is a space but not a leading one, increase the count by one 23 | count++ 24 | } 25 | } 26 | const maxSpace = Math.max(...Object.values(dict)) 27 | return Object.keys(dict).filter(key => dict[key] === maxSpace); 28 | } 29 | 30 | module.exports = loneliest -------------------------------------------------------------------------------- /algos/level2/week16/gzan.test.js: -------------------------------------------------------------------------------- 1 | const Stack = require('./gzan.index'); 2 | 3 | 4 | test('Stack is a class', () => { 5 | expect(typeof Stack.prototype.constructor).toEqual('function'); 6 | }); 7 | 8 | test('can push elements to a stack', () => { 9 | const s = new Stack(); 10 | expect(() => { 11 | s.push(1); 12 | }).not.toThrow(); 13 | }); 14 | 15 | test('can remove elements from a Stack', () => { 16 | const s = new Stack(); 17 | expect(() => { 18 | s.push(1); 19 | s.peek(); 20 | }).not.toThrow(); 21 | }); 22 | 23 | test('can show the top element of a Stack', () => { 24 | const s = new Stack(); 25 | expect(() => { 26 | s.push(1); 27 | s.pop(); 28 | }).not.toThrow(); 29 | }); 30 | 31 | test('Order of elements is maintained', () => { 32 | const s = new Stack(); 33 | s.push(1); 34 | s.push(2); 35 | s.push(3); 36 | expect(s.peek()).toEqual(3); 37 | expect(s.pop()).toEqual(3); 38 | expect(s.peek()).toEqual(2); 39 | expect(s.pop()).toEqual(2); 40 | expect(s.pop()).toEqual(1); 41 | expect(s.pop()).toEqual(undefined); 42 | }); 43 | 44 | //Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level2/week4/FindCracker.md: -------------------------------------------------------------------------------- 1 | ### FIND CRACKER 2 | 3 | Someone was hacking the score. Each student's record is given as an array The objects in the array are given again as an array of scores for each name and total score. ex> 4 | 5 | `var array = [ 6 | ["name1", 445, ["B", "A", "A", "C", "A", "A"]], 7 | ["name2", 140, ["B", "A", "A", "A"]], 8 | ["name3", 200, ["B", "A", "A", "C"]] 9 | ];`` 10 | 11 | The scores for each grade is: 12 | 13 | - A: 30 points 14 | - B: 20 points 15 | - C: 10 points 16 | - D: 5 points 17 | - Everything else: 0 points 18 | 19 | If there are 5 or more courses and all courses has a grade of B or above, additional 20 points are awarded. After all the calculations, the total score should be capped at 200 points. 20 | 21 | Returns the name of the hacked name as an array when scoring with this rule. 22 | 23 | `var array = [ 24 | ["name1", 445, ["B", "A", "A", "C", "A", "A"]], // name1 total point is over 200 => hacked 25 | ["name2", 140, ["B", "A", "A", "A"]], // name2 point is right 26 | ["name3", 200, ["B", "A", "A", "C"]] // name3 point is 200 but real point is 90 => hacked 27 | ]; 28 | 29 | return ["name1", "name2"];` 30 | 31 | #### Source: https://www.codewars.com/kata/59f70440bee845599c000085 -------------------------------------------------------------------------------- /algos/level1/week19/gzan.test.js: -------------------------------------------------------------------------------- 1 | 2 | const chunk = require('./gzan.index'); 3 | 4 | test('function chunk exists', () => { 5 | expect(typeof chunk).toEqual('function'); 6 | }); 7 | 8 | test('chunk divides an array of 10 elements with chunk size 2', () => { 9 | const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; 10 | const chunked = chunk(arr, 2); 11 | 12 | expect(chunked).toEqual([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]); 13 | }); 14 | 15 | test('chunk divides an array of 3 elements with chunk size 1', () => { 16 | const arr = [1, 2, 3]; 17 | const chunked = chunk(arr, 1); 18 | 19 | expect(chunked).toEqual([[1], [2], [3]]); 20 | }); 21 | 22 | test('chunk divides an array of 5 elements with chunk size 3', () => { 23 | const arr = [1, 2, 3, 4, 5]; 24 | const chunked = chunk(arr, 3); 25 | 26 | expect(chunked).toEqual([[1, 2, 3], [4, 5]]); 27 | }); 28 | 29 | 30 | test('chunk divides an array of 13 elements with chunk size 5', () => { 31 | const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; 32 | const chunked = chunk(arr, 5); 33 | 34 | expect(chunked).toEqual([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13]]); 35 | }); 36 | 37 | //Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level2/week7/robert.index.js: -------------------------------------------------------------------------------- 1 | function convert(s) { 2 | const string = s.toLowerCase() 3 | //returns 0 for an empty string 4 | if(s.length === 0){ 5 | return 0 6 | } 7 | const output = [] 8 | for(let i = 0; i < string.length; i++){ 9 | //the first character always maps to 1 10 | if ( i === 0){ 11 | output.push(1) 12 | //if all the numbers in the array is of value 1 13 | //and the current charater is different from the characters checked, then map the value to 0 14 | //this is important to make sure that the output is the lowest possible 15 | }else if ( output.find(e => e !== 1 ) === undefined && string[i] !== string[0]){ 16 | output.push(0) 17 | //if the character to be checked has a previous occurence then use the same value as the first time 18 | }else if(string.slice(0, i ).indexOf(string[i])!== -1){ 19 | output.push(output[string.indexOf(string[i])]) 20 | // else push a number higher than the higest number in the array by 1 on 21 | }else{ 22 | output.push(Math.max(...output) + 1) 23 | } 24 | } 25 | return parseInt(output.join('')) 26 | } 27 | 28 | module.exports = convert -------------------------------------------------------------------------------- /algos/level2/week2/leli_week2.js: -------------------------------------------------------------------------------- 1 | // etki code camp algo week 2 | 3 | // bus timer 4 | 5 | const calcTimeInMinutes = (h, min) => h * 60 + min 6 | 7 | const intParse = (str) => parseInt(str, 10) 8 | 9 | 10 | const busTimer = (time) => { 11 | // split the input 12 | const [hStr, minStr] = time.split(":") 13 | // transform into int 14 | const h = intParse(hStr) 15 | const min = intParse(minStr) 16 | // checking the input 17 | if (h > 23 || h < 0 || min < 0 || min > 59) { 18 | return "You have to give a valid time" 19 | } 20 | // calculate the input in minutes plus traveling time 21 | let timeInMinutes = calcTimeInMinutes(h, min) + 5 22 | // change if its after midnight 23 | if (timeInMinutes > 1440){ 24 | timeInMinutes %= 1440 25 | } 26 | console.log(timeInMinutes) 27 | // if before the first bus 28 | if (timeInMinutes <= calcTimeInMinutes(6, 0)){ 29 | return calcTimeInMinutes(6,0) - timeInMinutes 30 | } 31 | else { 32 | // if it is between 6:00 and 00:00 than the buses come every 15 min from ne full hour and modular is the 33 | // best option to check for that. the second modular ist to get 0' instead of 15' when you have to leave now 34 | return (15 - timeInMinutes % 15)%15 35 | } 36 | } 37 | 38 | module.exports = busTimer -------------------------------------------------------------------------------- /algos/level2/week17/robert.test.js: -------------------------------------------------------------------------------- 1 | const Queue = require('./robert.index') 2 | 3 | describe('Test that class is imported/exported correctly',()=>{ 4 | test('Queue should be defined', () => { 5 | expect(Queue).toBeDefined(); 6 | }); 7 | }) 8 | const queue = new Queue(); 9 | describe('The class construction is working well', () =>{ 10 | test('that the queues initial values are as they are expected to be', () => { 11 | expect(queue.values).toEqual(expect.arrayContaining([])) 12 | }) 13 | }) 14 | queue.add(1) 15 | queue.add(2) 16 | describe('The peek method', () =>{ 17 | test('that the method peek returns the first value of the queue', () => { 18 | const value = queue.peek() 19 | expect(value).toEqual(1) 20 | }) 21 | }) 22 | 23 | describe('The remove method', () =>{ 24 | test('that the method removes the first value in the queue', () => { 25 | const value = queue.remove() 26 | expect(value).toBe(1) 27 | }) 28 | }) 29 | 30 | describe('Another remove method', () =>{ 31 | test('that the method removes the first value in the queue', () => { 32 | const value = queue.remove() 33 | expect(value).toBe(2) 34 | }) 35 | }) 36 | -------------------------------------------------------------------------------- /algos/level2/week10/gzan.test.js: -------------------------------------------------------------------------------- 1 | const tourneyRecursive = require('./gzan.index.js').tourneyRecursive; 2 | const tourneyLoops = require('./gzan.index.js').tourneyLoops; 3 | 4 | describe('Type', function () { 5 | it('should give function as type', () => { 6 | expect(typeof tourneyRecursive).toEqual('function'); 7 | expect(typeof tourneyLoops).toEqual('function'); 8 | }); 9 | }); 10 | 11 | describe('Logic', function () { 12 | it('should find the correct results', () => { 13 | expect(tourneyRecursive([9, 5, 4, 7, 6, 3, 8, 2])).toEqual([[9, 5, 4, 7, 6, 3, 8, 2], [9, 7, 6, 8], [9, 8], [9]]); 14 | expect(tourneyRecursive([9, 5, 4, 7, 6, 3, 8])).toEqual([[9, 5, 4, 7, 6, 3, 8], [8, 9, 7, 6], [9, 7], [9]]); 15 | expect(tourneyRecursive([3, 5, 4, 6, 9, 3, 8, 7])).toEqual([[3, 5, 4, 6, 9, 3, 8, 7], [5, 6, 9, 8], [6, 9], [9]]); 16 | }); 17 | }); 18 | 19 | describe('Logic', function () { 20 | it('should find the same correct results', () => { 21 | expect(tourneyLoops([9, 5, 4, 7, 6, 3, 8, 2])).toEqual([[9, 5, 4, 7, 6, 3, 8, 2], [9, 7, 6, 8], [9, 8], [9]]); 22 | expect(tourneyLoops([9, 5, 4, 7, 6, 3, 8])).toEqual([[9, 5, 4, 7, 6, 3, 8], [8, 9, 7, 6], [9, 7], [9]]); 23 | expect(tourneyLoops([3, 5, 4, 6, 9, 3, 8, 7])).toEqual([[3, 5, 4, 6, 9, 3, 8, 7], [5, 6, 9, 8], [6, 9], [9]]); 24 | }); 25 | }); -------------------------------------------------------------------------------- /algos/level2/week5/gzan.test.js: -------------------------------------------------------------------------------- 1 | const encryptThis = require('./gzan.index.js') 2 | 3 | 4 | test('encryptThis', () => { 5 | expect(encryptThis).toBeDefined(); 6 | }); 7 | 8 | test('gives the correct ascii code for the first letter', () => { 9 | expect(encryptThis('A')).toEqual('65'); 10 | }); 11 | 12 | test('returns empty when string is empty', () => { 13 | expect(encryptThis(' ')).toEqual(' '); 14 | }); 15 | 16 | test('gives the correct code for one word', () => { 17 | expect(encryptThis('ABC')).toEqual('65CB'); 18 | }); 19 | 20 | test('gives correct result for a whole sentence', () => { 21 | expect(encryptThis('A wise old owl lived in an oak')).toEqual('65 119esi 111dl 111lw 108dvei 105n 97n 111ka'); 22 | }); 23 | 24 | test('ives correct result for a whole sentence 2', () => { 25 | expect(encryptThis('The less he spoke the more he heard')).toEqual('84eh 108sse 104e 115eokp 116eh 109ero 104e 104dare'); 26 | }); 27 | 28 | test('gives correct result for a whole sentence 3', () => { 29 | expect(encryptThis('Why can we not all be like that wise old bird')).toEqual('87yh 99na 119e 110to 97ll 98e 108eki 116tah 119esi 111dl 98dri'); 30 | }); 31 | 32 | test('ives correct result for a whole sentence 4', () => { 33 | expect(encryptThis('Thank you Piotr for all your help')).toEqual('84kanh 121uo 80roti 102ro 97ll 121ruo 104ple'); 34 | }); -------------------------------------------------------------------------------- /algos/level2/week20/gzan.test.js: -------------------------------------------------------------------------------- 1 | const circular = require('./gzan.index'); 2 | const L = require('./LinkedList'); 3 | const List = L.LinkedList; 4 | const Node = L.Node; 5 | 6 | test('circular function is defined', () => { 7 | expect(typeof circular).toEqual('function'); 8 | }); 9 | 10 | test('circular detects circular linked lists', () => { 11 | const l = new List(); 12 | const a = new Node('a'); 13 | const b = new Node('b'); 14 | const c = new Node('c'); 15 | 16 | l.head = a; 17 | a.next = b; 18 | b.next = c; 19 | c.next = b; 20 | 21 | expect(circular(l)).toEqual(true); 22 | }); 23 | 24 | //Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy 25 | 26 | test('circular detects circular linked lists linked at the head', () => { 27 | const l = new List(); 28 | const a = new Node('a'); 29 | const b = new Node('b'); 30 | const c = new Node('c'); 31 | 32 | l.head = a; 33 | a.next = b; 34 | b.next = c; 35 | c.next = a; 36 | 37 | expect(circular(l)).toEqual(true); 38 | }); 39 | 40 | test('circular detects non-circular linked lists', () => { 41 | const l = new List(); 42 | const a = new Node('a'); 43 | const b = new Node('b'); 44 | const c = new Node('c'); 45 | 46 | l.head = a; 47 | a.next = b; 48 | b.next = c; 49 | c.next = null; 50 | 51 | expect(circular(l)).toEqual(false); 52 | }); -------------------------------------------------------------------------------- /algos/level2/week16/Stack.md: -------------------------------------------------------------------------------- 1 | ### THE STACK 2 | 3 | #### About the stack: 4 | - a data structure based on FILO Principle (**F**irst **I**n **L**ast **O**ut) 5 | - **pushing:** adding a new record to the Stack 6 | - **popping:** removing the top record in the Stack(last added) 7 | 8 | #### Instructions: 9 | 10 | Create a stack data structure (class Stack) 11 | 12 | - The Stack should be a class with methods 'push', 'pop' and 'peek' 13 | - Push method should add a record to the stack 14 | - Pop method should remove the "top" record in the stack (top record = the last added record) 15 | - Peek method should return the "top" record without popping it 16 | - Adding an element to the stack should store it until it is removed 17 | 18 | #### Example 19 | 20 | ```` 21 | const s = new Stack(); 22 | s.push(1); 23 | s.push(2); 24 | s.push(3); 25 | console.log(s) //returns [1,2,3] 26 | s.pop(); // returns 3 27 | console.log(s) //returns [1,2] 28 | s.peek(); // returns 3 29 | console.log(s) //returns [1,2] 30 | ```` 31 | 32 | #### Here is the basic structure of the class for you to fill in: 33 | ```` 34 | class Stack { 35 | constructor() { 36 | 37 | } 38 | 39 | push(record) { 40 | 41 | } 42 | 43 | pop() { 44 | 45 | } 46 | 47 | peek() { 48 | 49 | } 50 | 51 | } 52 | ```` 53 | 54 | #### Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy 55 | -------------------------------------------------------------------------------- /algos/level2/week15/gzan.test.js: -------------------------------------------------------------------------------- 1 | Queue = require('./gzan.queue') 2 | weave = require('./gzan.index') 3 | 4 | test('queues have a peek function', () => { 5 | const q = new Queue(); 6 | expect(typeof q.peek).toEqual('function'); 7 | }); 8 | 9 | test('peek returns, but does not remove, the first value', () => { 10 | const q = new Queue(); 11 | q.add(1); 12 | q.add(2); 13 | expect(q.peek()).toEqual(1); 14 | expect(q.peek()).toEqual(1); 15 | expect(q.remove()).toEqual(1); 16 | expect(q.remove()).toEqual(2); 17 | }); 18 | 19 | test('weave is a function', () => { 20 | expect(typeof weave).toEqual('function'); 21 | }); 22 | 23 | test('weave can combine two queues', () => { 24 | const one = new Queue(); 25 | one.add(1); 26 | one.add(2); 27 | one.add(3); 28 | one.add(4); 29 | const two = new Queue(); 30 | two.add('one'); 31 | two.add('two'); 32 | two.add('three'); 33 | two.add('four'); 34 | 35 | const result = weave(one, two); 36 | expect(result.remove()).toEqual(1); 37 | expect(result.remove()).toEqual('one'); 38 | expect(result.remove()).toEqual(2); 39 | expect(result.remove()).toEqual('two'); 40 | expect(result.remove()).toEqual(3); 41 | expect(result.remove()).toEqual('three'); 42 | expect(result.remove()).toEqual(4); 43 | expect(result.remove()).toEqual('four'); 44 | expect(result.remove()).toBeUndefined(); 45 | }); 46 | 47 | //Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy 48 | -------------------------------------------------------------------------------- /algos/level2/week6/MidtownNavigator.md: -------------------------------------------------------------------------------- 1 | ### Midtown Navigator 2 | 3 | Create a function that tells the user how to get around Midtown in Manhattan. The function should be able to help the user to get from one location in this area to another. 4 | 5 | Streets run east-west. Street numbers increase as they move northward, from 1st street in Greenwich Village to 220th street in the Inwood section. Avenues run south-north, with numbers beginning on the east side of the island and increase to the west. 6 | 7 | "The Encyclopedia of New York City" defines Midtown as extending from 34th Street to 59th Street (going northwards) and from 3rd Avenue to 8th Avenue (going westwards). 8 | 9 | For example: 10 | ``` 11 | midtownNav("8th Ave and W 38th St", "7th Ave and W 36th St"); 12 | ``` 13 | 14 | The code above should tell the user how to get from 8th Ave and W 38th St to 7th Ave and W 36th St. It should then output as a string how many blocks north/south, and then how many blocks east/west the user should travel. 15 | 16 | ``` 17 | midtownNav("8th Ave and W 38th St", "7th Ave and W 36th St") // output => "Walk 2 blocks south, and 1 block east" 18 | midtownNav("5th Ave and W 46th St", "7th Ave and E 58th St") // output => "Walk 12 blocks north, and 2 blocks west" 19 | ``` 20 | 21 | Note: When the avenues are same, the direction of movement should be west and when the streets are same the direction should be north. 22 | 23 | #### Source: https://www.codewars.com/kata/59665001dc23af735700092b 24 | -------------------------------------------------------------------------------- /algos/level1/week10/gzan.test.js: -------------------------------------------------------------------------------- 1 | const findShortest = require('./gzan.index.js').findShortest; 2 | const findShortestWordLength = require('./gzan.index.js').findShortestWordLength; 3 | 4 | describe('Type', function () { 5 | it('should give function as type', () => { 6 | expect(typeof findShortest).toEqual('function'); 7 | expect(typeof findShortestWordLength).toEqual('function'); 8 | }); 9 | }); 10 | 11 | describe('Logic', function () { 12 | it('should find the length of shortest word', () => { 13 | expect(findShortest("What is now proved was once only imagined")).toEqual(2); 14 | expect(findShortest("We are all in the gutter but some of us are looking at the stars")).toEqual(2); 15 | expect(findShortest("Lorem ipsum dolor consectetur adipiscing finibus metus varius")).toEqual(5); 16 | }); 17 | }); 18 | 19 | describe('Logic', function () { 20 | it('should find the length of shortest word', () => { 21 | expect(findShortestWordLength("Neque porro quisquam dolorem ipsum quia consectetur adipisci")).toEqual(4); 22 | expect(findShortestWordLength("consectetur adipiscing Quisque lacinia molestie gravida eleifend mauris libero dapibussagittis sagittis Maecenas")).toEqual(6); 23 | expect(findShortestWordLength("Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium totam rem aperiam eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo Nemo enim ipsam voluptatem r")).toEqual(1); 24 | }); 25 | }); -------------------------------------------------------------------------------- /algos/level1/week8/UglifyWord.md: -------------------------------------------------------------------------------- 1 | ### UGLIFY WORD 2 | 3 | #### Summary 4 | In this kata, you have to make a function named uglify_word (uglifyWord in Java and Javascript). It accepts a string parameter. 5 | 6 | #### What does the uglify_word do? 7 | It checks the char in the given string from the front with an iteration, in the iteration it does these steps: 8 | 9 | 1. There is a flag and it will be started from 1. 10 | 2. Check the current char in the iteration index. 11 | - If it is an alphabet character [a-zA-Z] and the flag value is equal to 1, then change this character to upper case. 12 | - If it is an alphabet character [a-zA-Z] and the flag value is equal to 0, then change this character to lower case. 13 | - Otherwise, if it is not an alphabet character, then set the flag value to 1. 14 | 3. If the current char is an alphabet character, do a boolean not operation to the flag. 15 | After the iteration has done, return the fixed string that might have been changed in such iteration. 16 | 17 | #### Examples 18 | 19 | ```` 20 | uglify_word("aaa") === "AaA" 21 | uglify_word("AAA") === "AaA" 22 | uglify_word("BbB") === "BbB" 23 | uglify_word("aaa-bbb-ccc") === "AaA-BbB-CcC" 24 | uglify_word("AaA-BbB-CcC") === "AaA-BbB-CcC" 25 | uglify_word("eeee-ffff-gggg") === "EeEe-FfFf-GgGg" 26 | uglify_word("EeEe-FfFf-GgGg") === "EeEe-FfFf-GgGg" 27 | uglify_word("qwe123asdf456zxc") === "QwE123AsDf456ZxC" 28 | uglify_word("Hello World") === "HeLlO WoRlD" 29 | ```` 30 | 31 | #### Source: https://www.codewars.com/kata/5ce6cf94cb83dc0020da1929 -------------------------------------------------------------------------------- /algos/level2/week10/EliminationTournament.md: -------------------------------------------------------------------------------- 1 | ### ELIMINATION TOURNAMENT 2 | 3 | You will be given an array representing contestant ranks. You must eliminate contestant in series of rounds comparing consecutive pairs of ranks and store all initial and intermediate results in an array. 4 | 5 | During one round, the lowest rank of a pair is eliminated while the highest proceeds to the next round. This goes on until one contestant only is left. If the number of contestants is odd, the last one of the current array becomes the first of the next round. 6 | 7 | At the end of the competition, return the results of all the rounds in the form of array of arrays: 8 | 9 | ```` 10 | input = [9, 5, 4, 7, 6, 3, 8, 2]; 11 | 12 | tourney(input) === [ 13 | [9, 5, 4, 7, 6, 3, 8, 2], // first round is initial input 14 | [9, 7, 6, 8], // results of 9 vs 5, 4 vs 7, 6 vs 3, and 8 vs 2 15 | [9, 8], // results of 9 vs 7 and 6 vs 8 16 | [9] // results of 9 vs 8 17 | ]; 18 | ```` 19 | 20 | With an odd length: 21 | 22 | ```` 23 | input = [9, 5, 4, 7, 6, 3, 8]; 24 | tourney(input) === [ 25 | [9, 5, 4, 7, 6, 3, 8], 26 | [8, 9, 7, 6], // 8 is now first because it was last in the former round 27 | [9, 7], 28 | [9] 29 | ]; 30 | ```` 31 | 32 | #### Notes: 33 | 34 | - Array length will alway be >= 2 and <= 100 35 | - Elements of the array will always be >=1 and <= 100 36 | - Input must not be altered. 37 | 38 | #### Source: https://www.codewars.com/kata/5f631ed489e0e101a70c70a0 39 | -------------------------------------------------------------------------------- /algos/level1/week9/gzan.test.js: -------------------------------------------------------------------------------- 1 | const killerShort = require('./gzan.index.js').killerShort; 2 | const killerLong = require('./gzan.index.js').killerLong; 3 | 4 | describe('Type', function () { 5 | it('should give function as type', () => { 6 | expect(typeof killerShort).toEqual('function'); 7 | expect(typeof killerLong).toEqual('function'); 8 | }); 9 | }); 10 | 11 | describe('Logic', function () { 12 | it('should find the correct killer', () => { 13 | expect(killerShort({ 'James': ['Jacob', 'Bill', 'Lucas'], 'Johnny': ['David', 'Kyle', 'Lucas'], 'Peter': ['Lucy', 'Kyle'] }, ['Lucas', 'Bill'])).toEqual('James'); 14 | expect(killerShort({ 'Brad': [], 'Megan': ['Ben', 'Kevin'], 'Finn': [] }, ['Ben'])).toEqual('Megan'); 15 | expect(killerShort({ 'Metin': ['Uwe', 'Khodor', 'Jale'], 'Natalie': ['Cem', 'Rafal', 'Kevin', 'Jale'], 'Agata': ['Jale'], 'Mehmet': ['Melissa', 'Lena'] }, ['Rafal', 'Jale', 'Cem'])).toEqual('Natalie'); 16 | }); 17 | }); 18 | 19 | describe('Logic', function () { 20 | it('should find the killer', () => { 21 | expect(killerLong({ 'James': ['Jacob', 'Bill', 'Lucas'], 'Johnny': ['David', 'Kyle', 'Lucas'], 'Peter': ['Lucy', 'Kyle'] }, ['Lucas', 'Bill'])).toEqual('James'); 22 | expect(killerLong({ 'Brad': [], 'Megan': ['Ben', 'Kevin'], 'Finn': [] }, ['Ben'])).toEqual('Megan'); 23 | expect(killerLong({ 'Metin': ['Uwe', 'Khodor', 'Jale'], 'Natalie': ['Cem', 'Rafal', 'Kevin', 'Jale'], 'Agata': ['Jale'], 'Mehmet': ['Melissa', 'Lena'] }, ['Rafal', 'Jale', 'Cem'])).toEqual('Natalie'); 24 | }); 25 | }); -------------------------------------------------------------------------------- /algos/level2/week19/gzan.test.js: -------------------------------------------------------------------------------- 1 | const midpoint = require('./gzan.index'); 2 | const L = require('./linkedlist'); 3 | const Node = L.Node; 4 | const LinkedList = L.LinkedList; 5 | 6 | test('Midpoint is a function', () => { 7 | expect(typeof midpoint).toEqual('function'); 8 | }); 9 | 10 | describe('Midpoint returns the middle node of an odd numbered list', () => { 11 | test('when the list has 3 elements', () => { 12 | const l = new LinkedList(); 13 | l.insertLast('a'); 14 | l.insertLast('b'); 15 | l.insertLast('c'); 16 | expect(midpoint(l).data).toEqual('b'); 17 | }); 18 | 19 | test('when the list has 5 elements', () => { 20 | const l = new LinkedList(); 21 | l.insertLast('a'); 22 | l.insertLast('b'); 23 | l.insertLast('c'); 24 | l.insertLast('d'); 25 | l.insertLast('e'); 26 | expect(midpoint(l).data).toEqual('c'); 27 | }); 28 | }); 29 | 30 | describe('Midpoint returns the middle node of an even numbered list', () => { 31 | test('when the list has 2 elements', () => { 32 | const l = new LinkedList(); 33 | l.insertLast('a'); 34 | l.insertLast('b'); 35 | expect(midpoint(l).data).toEqual('a'); 36 | }); 37 | 38 | test('when the list has 4 elements', () => { 39 | const l = new LinkedList(); 40 | l.insertLast('a'); 41 | l.insertLast('b'); 42 | l.insertLast('c'); 43 | l.insertLast('d'); 44 | expect(midpoint(l).data).toEqual('b'); 45 | }); 46 | }); 47 | 48 | //Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level2/week20/robert.test.js: -------------------------------------------------------------------------------- 1 | const { circular } = require('./robert.index') 2 | const { List, Node } = require('../week18/robert.index') 3 | 4 | describe('Test that class and functions are imported/exported correctly', () => { 5 | test('Classes and function should be defined', () => { 6 | expect(Node).toBeDefined(); 7 | expect(circular).toBeDefined(); 8 | expect(List).toBeDefined(); 9 | }); 10 | }) 11 | 12 | describe('The circular function determines correctly if list is circular or not', () => { 13 | test('when a list is not circular', () => { 14 | const l = new List(); 15 | const a = new Node('a'); 16 | const b = new Node('b'); 17 | const c = new Node('c'); 18 | l.head = a; 19 | a.next = b; 20 | b.next = c; 21 | c.next = null; 22 | //A list with a last node pointing to null is not circular 23 | expect(l.getLast().next).toBe(null) 24 | expect(circular(l)).toBe(false); 25 | }); 26 | test('when a list is circular', () => { 27 | const l = new List(); 28 | const a = new Node('a'); 29 | const b = new Node('b'); 30 | const c = new Node('c'); 31 | l.head = a; 32 | a.next = b; 33 | b.next = c; 34 | c.next = b; 35 | expect(circular(l)).toBe(true) 36 | }); 37 | test('when a list is empty', () => { 38 | const l = new List(); 39 | expect(l.size()).toBe(0) 40 | //An empty list is considered not circular 41 | expect(circular(l)).toBe(false) 42 | }); 43 | }) -------------------------------------------------------------------------------- /algos/level1/week18/gzan.test.js: -------------------------------------------------------------------------------- 1 | const fizzBuzz = require('./gzan.index') 2 | 3 | test('fizzBuzz function is defined', () => { 4 | expect(fizzBuzz).toBeDefined(); 5 | }); 6 | 7 | test('Calling fizzbuzz with `5` prints out 5 statements', () => { 8 | fizzBuzz(5); 9 | 10 | expect(console.log.mock.calls.length).toEqual(5); 11 | }); 12 | 13 | test('Calling fizzbuzz with 15 prints out the correct values', () => { 14 | fizzBuzz(15); 15 | 16 | expect(console.log.mock.calls[0][0]).toEqual(1); 17 | expect(console.log.mock.calls[1][0]).toEqual(2); 18 | expect(console.log.mock.calls[2][0]).toEqual('fizz'); 19 | expect(console.log.mock.calls[3][0]).toEqual(4); 20 | expect(console.log.mock.calls[4][0]).toEqual('buzz'); 21 | expect(console.log.mock.calls[5][0]).toEqual('fizz'); 22 | expect(console.log.mock.calls[6][0]).toEqual(7); 23 | expect(console.log.mock.calls[7][0]).toEqual(8); 24 | expect(console.log.mock.calls[8][0]).toEqual('fizz'); 25 | expect(console.log.mock.calls[9][0]).toEqual('buzz'); 26 | expect(console.log.mock.calls[10][0]).toEqual(11); 27 | expect(console.log.mock.calls[11][0]).toEqual('fizz'); 28 | expect(console.log.mock.calls[12][0]).toEqual(13); 29 | expect(console.log.mock.calls[13][0]).toEqual(14); 30 | expect(console.log.mock.calls[14][0]).toEqual('fizzbuzz'); 31 | }); 32 | 33 | beforeEach(() => { 34 | jest.spyOn(console, 'log').mockImplementation(() => { }); 35 | }); 36 | 37 | afterEach(() => { 38 | console.log.mockRestore(); 39 | }); 40 | 41 | //Source of the above solutions : The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level2/week19/robert.test.js: -------------------------------------------------------------------------------- 1 | const midpoint = require('./robert.index') 2 | const { List } = require('../week18/robert.index') 3 | 4 | describe('Test that class and fuunction are imported/exported correctly', () => { 5 | test('Queue should be defined', () => { 6 | expect(midpoint).toBeDefined(); 7 | expect(List).toBeDefined(); 8 | }); 9 | }) 10 | 11 | describe('The midpoint function finds the correct middle node in different lists', () => { 12 | const list = new List() 13 | list.insertLast('a') 14 | list.insertLast('b') 15 | list.insertLast('c') 16 | list.insertLast('d') 17 | list.insertLast('e') 18 | list.insertLast('f') 19 | list.insertLast('g') 20 | test('the midpoint in an odd number sized list is found', () => { 21 | expect(list.size()).toBe(7) 22 | expect(midpoint(list)).toEqual({data: 'd'}); 23 | //element at the third index is the one at the middle and should be same data 24 | expect(list.getAt(3).data).toBe('d') 25 | }); 26 | test('the midpoint in an even number sized list is found', () => { 27 | list.removeLast() 28 | expect(list.size()).toBe(6) 29 | expect(midpoint(list)).toEqual({data: 'c'}); 30 | //element at the second index is the one at the middle and should be same data 31 | expect(list.getAt(2).data).toBe('c') 32 | }); 33 | test('the function returns null when an empty list is passed to it', () => { 34 | list.clear() 35 | expect(list.size()).toBe(0) 36 | expect(midpoint(list)).toEqual(null); 37 | }); 38 | }) 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /algos/level2/week12/Dubstep.md: -------------------------------------------------------------------------------- 1 | ### DUBSTEP 2 | 3 | Polycarpus works as a DJ in the best Berland nightclub, and he often uses dubstep music in his performance. Recently, he has decided to take a couple of old songs and make dubstep remixes from them. 4 | 5 | Let's assume that a song consists of some number of words (that don't contain WUB). To make the dubstep remix of this song, Polycarpus inserts a certain number of words "WUB" before the first word of the song (the number may be zero), after the last word (the number may be zero), and between words (at least one between any pair of neighbouring words), and then the boy glues together all the words, including "WUB", in one string and plays the song at the club. 6 | 7 | For example, a song with words "I AM X" can transform into a dubstep remix as "WUBWUBIWUBAMWUBWUBX" and cannot transform into "WUBWUBIAMWUBX". 8 | 9 | Recently, Jonny has heard Polycarpus's new dubstep track, but since he isn't into modern music, he decided to find out what was the initial song that Polycarpus remixed. Help Jonny restore the original song. 10 | 11 | #### Input 12 | 13 | The input consists of a single non-empty string, consisting only of uppercase English letters, the string's length doesn't exceed 200 characters 14 | 15 | #### Output 16 | 17 | Return the words of the initial song that Polycarpus used to make a dubsteb remix. Separate the words with a space. 18 | 19 | #### Examples 20 | 21 | ```` 22 | songDecoder("WUBWEWUBAREWUBWUBTHEWUBCHAMPIONSWUBMYWUBFRIENDWUB") 23 | // => WE ARE THE CHAMPIONS MY FRIEND 24 | ```` 25 | 26 | #### Source: https://www.codewars.com/kata/551dc350bf4e526099000ae5 -------------------------------------------------------------------------------- /algos/level2/week8/gzan.index.js: -------------------------------------------------------------------------------- 1 | /// SHORT, ELEGANT WAY WITH ES& 2 | const sortArray = (array) => { 3 | const oddNums = array.filter((num) => num % 2).sort((a, b) => a - b); 4 | return array.map((num) => num % 2 ? oddNums.shift() : num); 5 | }; 6 | 7 | //LONG BUT EASIER TO UNDERSTAND 8 | function sortArrayLong(array) { 9 | if (array === []) return array 10 | let oddNums = [] 11 | let sorted = [] 12 | 13 | //add nums in a seperate array in an ascending order 14 | for (let num of array) { 15 | if (isOdd(num)) { 16 | addNumberSorted(num, oddNums) 17 | } 18 | } 19 | 20 | const length = array.length 21 | let j = 0; 22 | //make a new arr out of the main one 23 | //if odd then put the next num in sorted odd nums arr 24 | //if even put the num that was in that index in the main arr 25 | for (let i = 0; i < length; i++) { 26 | if (isOdd(array[i])) { 27 | sorted.push(oddNums[j]) 28 | j++ 29 | } else { 30 | sorted.push(array[i]) 31 | } 32 | } 33 | return sorted 34 | } 35 | 36 | // a function that returns true if a num is odd 37 | const isOdd = (n) => n % 2 !== 0; 38 | 39 | //a function that add nums in an arr considering the ascending order 40 | function addNumberSorted(n, arr) { 41 | let i = 0; 42 | const length = arr.length; 43 | if (length === 0) arr.push(n) 44 | else if (n > arr[length - 1]) arr.push(n) 45 | else { 46 | while (i < length) { 47 | if (n > arr[i]) { 48 | i++; 49 | } else { 50 | arr.splice(i, 0, n); 51 | return arr; 52 | } 53 | } 54 | } 55 | return arr; 56 | 57 | } 58 | 59 | 60 | 61 | 62 | module.exports = { 63 | sortArray, sortArrayLong, isOdd, addNumberSorted 64 | } -------------------------------------------------------------------------------- /algos/level2/week13/gzan.test.js: -------------------------------------------------------------------------------- 1 | const customChristmasTree = require('./gzan.index.js') 2 | 3 | 4 | describe('Type', function () { 5 | it('should give function as type', () => { 6 | expect(typeof customChristmasTree).toEqual('function'); 7 | }); 8 | }); 9 | 10 | describe('Logic', function () { 11 | it('should return a str without "WUB"s amnd multiple/trailing/heading spaces', () => { 12 | expect(customChristmasTree("123456789", 3)).toEqual(' 1\n 2 3\n4 5 6\n |'); 13 | expect(customChristmasTree("1234", 6)).toEqual(' 1\n 2 3\n 4 1 2\n 3 4 1 2\n 3 4 1 2 3\n4 1 2 3 4 1\n |\n |'); 14 | expect(customChristmasTree("*@o", 3)).toEqual(' *\n @ o\n* @ o\n |'); 15 | expect(customChristmasTree("*@o", 6)).toEqual(' *\n @ o\n * @ o\n * @ o *\n @ o * @ o\n* @ o * @ o\n |\n |'); 16 | expect(customChristmasTree("ruck", 17)).toEqual(' r\n u c\n k r u\n c k r u\n c k r u c\n k r u c k r\n u c k r u c k\n r u c k r u c k\n r u c k r u c k r\n u c k r u c k r u c\n k r u c k r u c k r u\n c k r u c k r u c k r u\n c k r u c k r u c k r u c\n k r u c k r u c k r u c k r\n u c k r u c k r u c k r u c k\n r u c k r u c k r u c k r u c k\nr u c k r u c k r u c k r u c k r\n |\n |\n |\n |\n |'); 17 | expect(customChristmasTree("*\\", 5)).toEqual(' *\n \\ *\n \\ * \\\n * \\ * \\\n* \\ * \\ *\n |'); 18 | expect(customChristmasTree("tjllsj", 7)).toEqual(' t\n j l\n l s j\n t j l l\n s j t j l\n l s j t j l\nl s j t j l l\n |\n |'); 19 | expect(customChristmasTree("ZFRPC", 8)).toEqual(' Z\n F R\n P C Z\n F R P C\n Z F R P C\n Z F R P C Z\n F R P C Z F R\nP C Z F R P C Z\n |\n |'); 20 | }); 21 | }); -------------------------------------------------------------------------------- /algos/level2/week13/CustomChristmasTree.md: -------------------------------------------------------------------------------- 1 | ### CUSTOM CHRISTMAS TREE 2 | 3 | #### Task 4 | Christmas is coming, and your task is to build a custom Christmas tree with the specified characters and the specified height. 5 | 6 | #### Inputs: 7 | chars: the specified characters. 8 | n: the specified height. A positive integer greater than 2. 9 | Output: 10 | A multiline string. Each line is separated by \n. A tree contains two parts: leaves and trunks. 11 | The leaves should be n rows. The first row fill in 1 char, the second row fill in 3 chars, and so on. A single space will be added between two adjust chars, and some of the necessary spaces will be added to the left side, to keep the shape of the tree. No space need to be added to the right side. 12 | 13 | The trunk should be at least 1 unit height, it depends on the value of the n. The minimum value of n is 3, and the height of the tree trunk is 1 unit height. If n increased by 3, and the tree trunk increased by 1 unit. For example, when n is 3,4 or 5, trunk should be 1 row; when n is 6,7 or 8, trunk should be 2 row; and so on. 14 | 15 | Still not understand the task? Look at the following example ;-) 16 | 17 | 18 | #### Examples 19 | 20 | 21 | For `chars = "*@o" and n = 3`, the output should be: 22 | 23 | ```` 24 | * 25 | @ o 26 | * @ o 27 | | 28 | ```` 29 | 30 | For `chars = "*@o" and n = 6`,the output should be: 31 | 32 | ```` 33 | * 34 | @ o 35 | * @ o 36 | * @ o * 37 | @ o * @ o 38 | * @ o * @ o 39 | | 40 | | 41 | ```` 42 | 43 | For `chars = "1234" and n = 6`, the output should be: 44 | 45 | ```` 46 | 1 47 | 2 3 48 | 4 1 2 49 | 3 4 1 2 50 | 3 4 1 2 3 51 | 4 1 2 3 4 1 52 | | 53 | | 54 | ```` 55 | 56 | For `chars = "123456789" and n = 3`, the output should be: 57 | 58 | ```` 59 | 1 60 | 2 3 61 | 4 5 6 62 | | 63 | ```` 64 | 65 | #### Source: https://www.codewars.com/kata/5a405ba4e1ce0e1d7800012e -------------------------------------------------------------------------------- /algos/level1/week8/gzan.test.js: -------------------------------------------------------------------------------- 1 | const uglifyWord = require('./gzan.index.js').uglifyWord; 2 | const isLetter = require('./gzan.index.js').isLetter; 3 | 4 | describe('Type', function () { 5 | it('should give function as type', () => { 6 | expect(typeof uglifyWord).toEqual('function'); 7 | expect(typeof isLetter).toEqual('function'); 8 | }); 9 | }); 10 | 11 | 12 | describe('Logic', function () { 13 | it('should find the correct result', () => { 14 | expect(isLetter('j')).toBeTruthy(); 15 | expect(isLetter('J')).toBeTruthy(); 16 | expect(isLetter('&')).toBeFalsy(); 17 | expect(isLetter('ü')).toBeFalsy(); 18 | expect(isLetter('*')).toBeFalsy(); 19 | expect(isLetter('3')).toBeFalsy(); 20 | expect(isLetter('X')).toBeTruthy(); 21 | expect(isLetter('b')).toBeTruthy(); 22 | expect(isLetter('_')).toBeFalsy(); 23 | expect(isLetter('«')).toBeFalsy(); 24 | expect(isLetter('@')).toBeFalsy(); 25 | expect(isLetter('T')).toBeTruthy(); 26 | expect(isLetter('ß')).toBeFalsy(); 27 | expect(isLetter('0')).toBeFalsy(); 28 | expect(isLetter('O')).toBeTruthy(); 29 | expect(isLetter('+')).toBeFalsy(); 30 | expect(isLetter('>')).toBeFalsy(); 31 | expect(isLetter('w')).toBeTruthy(); 32 | expect(isLetter('.')).toBeFalsy(); 33 | expect(isLetter('Z')).toBeTruthy(); 34 | }); 35 | }); 36 | 37 | describe('Logic', function () { 38 | it('should find the correct result', () => { 39 | expect(uglifyWord("aaa")).toEqual("AaA") 40 | expect(uglifyWord("AAA")).toEqual("AaA") 41 | expect(uglifyWord("BbB")).toEqual("BbB") 42 | expect(uglifyWord("aaa-bbb-ccc")).toEqual("AaA-BbB-CcC") 43 | expect(uglifyWord("AaA-BbB-CcC")).toEqual("AaA-BbB-CcC") 44 | expect(uglifyWord("eeee-ffff-gggg")).toEqual("EeEe-FfFf-GgGg") 45 | expect(uglifyWord("EeEe-FfFf-GgGg")).toEqual("EeEe-FfFf-GgGg") 46 | expect(uglifyWord("qwe123asdf456zxc")).toEqual("QwE123AsDf456ZxC") 47 | expect(uglifyWord("Hello World")).toEqual("HeLlO WoRlD") 48 | }); 49 | }); -------------------------------------------------------------------------------- /algos/level2/week3/TetrisScoringSystem.md: -------------------------------------------------------------------------------- 1 | ### A History Lesson 2 | Tetris is a puzzle video game originally designed and programmed by Soviet Russian software engineer Alexey Pajitnov. The first playable version was completed on June 6, 1984. Pajitnov derived its name from combining the Greek numerical prefix tetra- (the falling pieces contain 4 segments) and tennis, Pajitnov's favorite sport. 3 | 4 | ### About scoring system 5 | The scoring formula is built on the idea that more difficult line clears should be awarded more points. For example, a single line clear is worth 40 points, clearing four lines at once (known as a Tetris) is worth 1200. 6 | 7 | A level multiplier is also used. The game starts at level 0. The level increases every ten lines you clear. Note that after increasing the level, the total number of cleared lines is not reset. 8 | 9 | For our task you can use this [table](https://www.codewars.com/kata/5da9af1142d7910001815d32) 10 | 11 | 12 | ### Task 13 | Calculate the final score of the game using original Nintendo scoring system 14 | 15 | ### Input 16 | Array with cleaned lines. 17 | Example: [4, 2, 2, 3, 3, 4, 2] 18 | Input will always be valid: array of random length (from 0 to 5000) with numbers from 0 to 4. 19 | 20 | ### Ouput 21 | Calculated final score. 22 | `def get_score(arr) -> int: return 0` 23 | 24 | ### Example 25 | `get_score([4, 2, 2, 3, 3, 4, 2]); # returns 4900` 26 | 27 | - Step 1: +1200 points for 4 lines (current level 0). Score: 0+1200=1200; 28 | - Step 2: +100 for 2 lines. Score: 1200+100=1300; 29 | - Step 3: +100. Score: 1300+100=1400; 30 | - Step 4: +300 for 3 lines (current level still 0). Score: 1400+300=1700. 31 | - Total number of cleaned lines 11 (4 + 2 + 2 + 3), so level goes up to 1 (level ups each 10 lines); 32 | - Step 5: +600 for 3 lines (current level 1). Score: 1700+600=2300; 33 | - Step 6: +2400. Score: 2300+2400=4700; 34 | - Step 7: +200. Total score: 4700+200=4900 points. 35 | 36 | #### Source: https://www.codewars.com/kata/5da9af1142d7910001815d32 37 | -------------------------------------------------------------------------------- /student.md: -------------------------------------------------------------------------------- 1 | student.md is the document outlining the processes and environment setup for students. 2 | 3 | ## 1. Slack channels 4 | 5 | #announcements : All announcements of etki_JS Team will be made here. Make sure to enable notifications. 6 | 7 | #etki_JS-team : Contact our team and mentors publicly for any topic you want which aren't covered in other channels. 8 | 9 | #general: Important pinned notes. 10 | 11 | #helpdesk-level1 : Technical coding questions about beginner program. Mentors will check this channel regularly and will try to support you. 12 | 13 | #helpdesk-level2 : Technical coding questions about intermediate program. Mentors will check this channel regularly and will try to support you. 14 | 15 | #introductions : You can get to know each other and contact here. 16 | 17 | #level1 : All topics about beginners program, except help requests. For help requests see #helpdesk-level1. 18 | 19 | #level2 : All topics about intermediate program, except help requests. For help requests see #helpdesk-level2. 20 | 21 | #questions-and-feedback : Organizational questions and feedback. 22 | 23 | #random : Anything irrelevant but may be of interest and/or fun. 24 | 25 | *** 26 | 27 | ## 2. Environment setup 28 | 29 | ### All students 30 | 31 | #### Environment setup 32 | 33 | * [Create Github account](www.github.com) 34 | * [Install Github Desktop](https://desktop.github.com/) 35 | * [Install Chrome](https://www.google.com/chrome/) 36 | * [Install Visual Studio Code Community Edition](https://code.visualstudio.com/) 37 | * [Install Zoom](https://zoom.us/download) 38 | 39 | _**Note:**_Please make sure to post all helpdesk questions directly to the public channels, and do not send direct messages to Mentors. 40 | 41 | ## Intermediate students 42 | #### Before you start the intermediate course in the [Course map](https://github.com/etkitech/etki_JS/blob/master/course-map.md) 43 | 44 | * [What do you need to install/setup](https://fullstackopen.com/en/part0/general_info#before-you-start) 45 | 46 | *** 47 | -------------------------------------------------------------------------------- /algos/level2/week8/gzan.test.js: -------------------------------------------------------------------------------- 1 | const sortArray = require('./gzan.index.js').sortArray; 2 | const sortArrayLong = require('./gzan.index.js').sortArrayLong; 3 | const isOdd = require('./gzan.index.js').isOdd; 4 | const addNumberSorted = require('./gzan.index.js').addNumberSorted; 5 | 6 | describe('Type', function () { 7 | it('should give function as type', () => { 8 | expect(typeof sortArray).toEqual('function'); 9 | expect(typeof sortArrayLong).toEqual('function'); 10 | expect(typeof isOdd).toEqual('function'); 11 | expect(typeof addNumberSorted).toEqual('function'); 12 | }); 13 | }); 14 | 15 | describe('Logic isOdd', function () { 16 | it('should find the correct result', () => { 17 | expect(isOdd(1)).toBeTruthy(); 18 | expect(isOdd(-1)).toBeTruthy(); 19 | expect(isOdd(127)).toBeTruthy(); 20 | expect(isOdd(128)).toBeFalsy(); 21 | expect(isOdd(0)).toBeFalsy(); 22 | expect(isOdd(-4)).toBeFalsy(); 23 | }); 24 | }); 25 | 26 | describe('Logic addNumberSorted', function () { 27 | it('should find the correct result', () => { 28 | expect(addNumberSorted(1, [2, 3])).toEqual([1, 2, 3]); 29 | // expect(addNumberSorted(4, [2, 3])).toEqual([2, 3, 4]); 30 | expect(addNumberSorted(3, [2, 4])).toEqual([2, 3, 4]); 31 | expect(addNumberSorted(21, [1, 2, 30])).toEqual([1, 2, 21, 30]); 32 | expect(addNumberSorted(51, [])).toEqual([51]); 33 | expect(addNumberSorted(51, [52])).toEqual([51, 52]); 34 | expect(addNumberSorted(5, [1, 2, 3, 4, 5, 7, 8, 9, 10, 11])).toEqual([1, 2, 3, 4, 5, 5, 7, 8, 9, 10, 11]); 35 | }); 36 | }); 37 | 38 | describe('Logic sortArray', function () { 39 | it('should find the correct result in both functions', () => { 40 | expect(sortArray([3, 9, 4, 5, 2, 7, 5, 12, 8])).toEqual([3, 5, 4, 5, 2, 7, 9, 12, 8]) 41 | expect(sortArrayLong([3, 9, 4, 5, 2, 7, 5, 12, 8])).toEqual([3, 5, 4, 5, 2, 7, 9, 12, 8]) 42 | expect(sortArray([87, 34, 56, 23, 43, 5, 63, 21])).toEqual([5, 34, 56, 21, 23, 43, 63, 87]) 43 | expect(sortArrayLong([87, 34, 56, 23, 43, 5, 63, 21])).toEqual([5, 34, 56, 21, 23, 43, 63, 87]) 44 | }); 45 | }); -------------------------------------------------------------------------------- /algos/level2/week15/UnderwaterQueueWeaving.md: -------------------------------------------------------------------------------- 1 | ### UNDERWATER QUEUE WEAVING 2 | 3 | #### About the queue: 4 | - a data structure based on FIFO Principle (**F**irst **I**n **F**irst **O**ut) 5 | - **enqueuing:** adding a new record to the beginning of the Queue (first index) 6 | - **dequeuing:** removing the oldest record from the Queue (last index) 7 | 8 | #### Instructions: 9 | 10 | 1. Implement a 'peek' method in the Queue class below. Peek should return the last element (the next one to be returned) from the queue **without** removing it. 11 | 12 | 2. Implement the 'weave' function. Weave receives two queues as arguments and combines the contents of each into a new, third queue. The third queue should contain the **alternating** content of the two queues The function should handle queues of **different lengths** without inserting 'undefined' into the new one. **Do not** access the array inside of any queue, only use the 'add', 'remove', and 'peek' functions. 13 | 14 | #### Example 15 | 16 | ```` 17 | const queueOne = new Queue(); 18 | queueOne.add(1); 19 | queueOne.add(2); 20 | queueOne.add(3); 21 | queueOne.peek(); // returns 1 22 | console.log(queueOne); // returns [3,2,1] 23 | const queueTwo = new Queue(); 24 | queueTwo.add('Hi'); 25 | queueTwo.add('There'); 26 | const q = weave(queueOne, queueTwo); 27 | q.remove() //returns 1 28 | q.remove() //returns 'Hi' 29 | q.remove() //returns 2 30 | q.remove() //returns 'There' 31 | ```` 32 | 33 | #### Here is the basic structure of the class for you to fill peek method: 34 | ```` 35 | class Queue { 36 | constructor() { 37 | this.data = []; 38 | } 39 | add(record) { 40 | this.data.unshift(record); 41 | } 42 | remove() { 43 | return this.data.pop(); 44 | } 45 | peek(){ 46 | 47 | } 48 | 49 | } 50 | ```` 51 | 52 | #### Here is a file example with weave function for you to fill in: 53 | ```` 54 | const Queue = require('./queue'); 55 | 56 | function weave(sourceOne, sourceTwo) { 57 | 58 | } 59 | 60 | module.exports = weave; 61 | ```` 62 | 63 | #### Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy 64 | -------------------------------------------------------------------------------- /weekly-scrum.md: -------------------------------------------------------------------------------- 1 | # Weekly Scrum 2 | 3 | This is an optional side-activity to help students stay in contact and follow their progress. 4 | 5 | *** 6 | 7 | ## What is Scrum? 8 | 9 | * Scrum is one of the largest fundamental practices that occur in an agile scrum process. This is like a scrum meeting also called stand-up meeting 10 | * In real life, it could be a short 15-minute round-table discussion which ensures the entire development team is up to date 11 | * At *etki_JS Remote Code Camp*, we will do a text-based weekly scrum in which students can answer some questions on Slack (like what you’ve done, what are you doing next and if you need help with something) 12 | 13 | ## Why do this? 14 | 15 | For 3 reasons: 16 | 17 | 1) To help students stay on track and be in sync with other students learning the same things 18 | 2) To assist if they get stuck 19 | 3) To gain experience with one of the most used team collaboration techniques in the real world! (yes, this can actually help when interviewing for jobs!) 20 | 21 | ## How does it work? 22 | 23 | Every Monday we’ll post a message on channels #Level1 and #Level2 asking students to answer 3 questions: 24 | 25 | 1. What did you get done last week? (any accomplishments?) 26 | 2. Any blockers where you need help? 27 | 3. What are you getting done this week? 28 | 29 | ## Any examples? 30 | 31 | Students can choose to answer something like this: 32 | 33 | **Level1**: 34 | 1. Continued with the Responsive Web Design Certification 35 | 2. Flexbox was a bit complicated to me, is there any other good source that explains this better? 36 | 3. I want to finish this one and get started with the JS Algorithms and Data Structure 37 | 38 | **Level2**: 39 | 1. Finished Part2 40 | 2. Yes! I struggled with array methods on exercise 2.1 41 | 3. Finish Part2 and start working on Part3 42 | 43 | ## Moving forward 44 | 45 | This activity could be extended to an optional *video* Weekly Scrum in which a host and students could meet through Zoom for about 30 min and respond to these 3 questions. 46 | To be determined depending on students' interaction and through Poll results if there's a need for it. 47 | 48 | -------------------------------------------------------------------------------- /course-map.md: -------------------------------------------------------------------------------- 1 | # Course Map 2 | 3 | Course map is a simple guidance path for _etki_JS Remote Code Camp_, through which students and mentors can follow the progress. 4 | 5 | *** 6 | 7 | ## Beginner (_Level1_) 8 | 9 | ### _Free Code Camp - modules_ 10 | B1. [Basic Javascript](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/) 11 | 12 | B2. [Basic HTML and HTML5](https://www.freecodecamp.org/learn/responsive-web-design/basic-html-and-html5/) 13 | 14 | B3. [Basic CSS](https://www.freecodecamp.org/learn/responsive-web-design/basic-css/) 15 | 16 | ### _Javascript.info - modules_ 17 | B4. [First steps](https://javascript.info/first-steps) 18 | 19 | B5. [Object](https://javascript.info/object) 20 | 21 | B6. [Array](https://javascript.info/array) 22 | 23 | B7. [Array methods](https://javascript.info/array-methods) 24 | 25 | B8. [Destructuring assignment](https://javascript.info/destructuring-assignment) 26 | 27 | 28 | ### _Git_ 29 | 30 | G1. [How to create a GitHub account](https://www.youtube.com/watch?v=ezxRcdJ8glM) 31 | 32 | G2.1 [Connecting to GitHub with SSH](https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh) 33 | 34 | G2.2 [Connecting to GitHub with SSH video](https://www.youtube.com/watch?v=nQDFBd5NFA8) 35 | *** 36 | 37 | ## Intermediate (_Level2_) 38 | 39 | ### _FullStackOpen modules_ 40 | I0. [Fundamentals of Web apps](https://fullstackopen.com/en/part0) 41 | 42 | I1. [Introduction to React](https://fullstackopen.com/en/part1) 43 | 44 | I2. [Communicating with server](https://fullstackopen.com/en/part2) 45 | 46 | I3. [Programming a server with NodeJS and Express](https://fullstackopen.com/en/part3) 47 | 48 | I4. [Testing Express servers, user administration](https://fullstackopen.com/en/part4) 49 | 50 | I5. [Testing React apps](https://fullstackopen.com/en/part5) 51 | 52 | I6. [State management with Redux](https://fullstackopen.com/en/part6) 53 | 54 | I7. [React router, custom hooks, styling app with CSS and webpack](https://fullstackopen.com/en/part7) 55 | 56 | I8. [GraphQL](https://fullstackopen.com/en/part8) 57 | 58 | I9. [Typescript](https://fullstackopen.com/en/part9) 59 | 60 | *** 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /algos/level2/week4/robert.index.js: -------------------------------------------------------------------------------- 1 | // THIS EXERCISE WAS SOLVED USING FUNCTIONAL PROGRAMMING PROCEDURE, 2 | //IT BREAKS DOWN THE TASKS INTO DIFFERENT FUNCTIONS FOR EASY COMPREHENSION 3 | 4 | // function creates an array of grades lower than B, if the array is returned... 5 | // empty, then the person got no grade lower than B 6 | const checkGrades = (arry) =>{ 7 | const lowerGrades = arry.filter(e => e !== "A" && e !== "B" ? e : null ) 8 | return lowerGrades 9 | } 10 | 11 | // funtion checks if the student got a bonus score or not 12 | const checkForBonus = (arry) =>{ 13 | if(arry.length < 5){ 14 | return false 15 | } 16 | let lowerGrades = checkGrades(arry) 17 | if (lowerGrades.length){ 18 | return false 19 | } 20 | return true //if it returns true then the student did over 5 subjects and passed all with grade B or A 21 | } 22 | 23 | // function converts grades to their values in numbers and sums it up 24 | const convertGrades = (arry) =>{ 25 | const scores = arry.map(e =>{ 26 | if(e === "A"){ 27 | return 30 28 | }else if(e === "B"){ 29 | return 20 30 | }else if(e === "C"){ 31 | return 10 32 | }else if(e === "D"){ 33 | return 5 34 | }else { 35 | return 0 36 | } 37 | }) 38 | const absoluteScore = scores.reduce((a, c) => a + c) //summation using a reducer funtion 39 | return absoluteScore 40 | } 41 | 42 | // Bonus score (if any) are added to absolute Scores here 43 | const getTotalScore = (arry) => { 44 | let totalScore = 0 45 | if(checkForBonus(arry)){ 46 | totalScore += 20 47 | } 48 | totalScore += convertGrades(arry) 49 | return totalScore 50 | } 51 | 52 | // Main funtion of the Problem, checks if score tallys with the grades value and then adds the name of the sudent to 53 | //the result 54 | const findCracker = (arr) => { 55 | let result = [] 56 | for(let i = 0; i < arr.length; i++){ 57 | const caltulatedScore = getTotalScore(arr[i][2]) 58 | 59 | if( caltulatedScore >= 200){ 60 | result.push(arr[i][0]) 61 | continue 62 | } else if(caltulatedScore !== arr[i][1]){ 63 | result.push(arr[i][0]) 64 | continue 65 | } 66 | } 67 | return result 68 | } 69 | 70 | module.exports = { 71 | checkGrades, 72 | checkForBonus, 73 | convertGrades, 74 | getTotalScore, 75 | findCracker 76 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # etki_JS Remote Code Camp 2 | 3 | ## Useful links 4 | 5 | * [Course Map](./course-map.md) 6 | * [Student](./student.md) 7 | * [Cohort 2020](./cohort2020.md) 8 | 9 | 10 | ## About 11 | 12 | etki_JS Remote Code Camp is an online program to study, learn and dive deep into modern web development, which is organized by etki Tech Network community together with [ThoughtWorks](https://www.thoughtworks.com) and [University of Helsinki](https://www.helsinki.fi/en). 13 | 14 | As technology stack the students learn the most relevant and up-to-date technologies for modern web development, including Javascript, React, Node.JS, MongoDB, Express and GraphQL. 15 | 16 | In the etki_JS course we run regular co-learning workshops for supporting the students' solo-learning efforts on the structured course material we have selected, in which students can ask their questions on the material to experienced software engineers, or discuss, co-study with their peers. 17 | 18 | etki_JS courses are self-paced, 100% free of charges, and will run fully remote. 19 | 20 | Both intermediate developers who want to dive deep into web development and beginner students are well-served with our selection of learning material. 21 | 22 | Our course is planned to be on-going. Duration of the learning program will depend on the individual student's knowledge level and their pace. 23 | 24 | As course material we follow the open-source programs of University of Helsinki's FullStackOpen, and other high quality learning materials from FreeCodeCamp and Javascript.info. If students follow all the course material of ~100 hours diligently to finish the FullStackOpen program and deliver the course projects on top, they will be presented with an official completion certification from University of Helsinki. 25 | 26 | Our mentors are English or Turkish speakers, students who speak English or Turkish are welcome. Main goal of this course is to provide a free and safe online learning environment for the underrepresented or underprivileged people in technology, and for the people who are looking into transitioning into the technology area. 27 | 28 | As community we follow the [Berlin Code of Conduct](https://berlincodeofconduct.org/), which is based on the [pdx.rb Code of Conduct](https://pdxruby.org/CONDUCT). 29 | 30 | _Please note, our program material is public to everyone, it is a self-paced co-learning program, where students learn by themselves, using the open-source material we curate._ 31 | -------------------------------------------------------------------------------- /algos/level2/week18/LinkedList.md: -------------------------------------------------------------------------------- 1 | ### LINKED LISTS 2 | 3 | #### About the linked lists: 4 | - a linked list is an ordered collection of data. 5 | - The collection contains a number of different nodes. 6 | - Each node contains some amount of data along with a reference to the next node. 7 | - The order is always maintained unless we change it. 8 | 9 | 10 | #### Instructions: 11 | 12 | Implement classes Node and Linked List 13 | 14 | 1. **Create a class instance to represent a node.** The node should have two properties, 'data' and 'next'. Accept both of these as arguments to the 'Node' constructor, then assign them to the instance as properties 'data' and 'next'. If 'next' is not provided to the constructor, then default its value to be 'null'. 15 | 16 | 2. **Create a class to represent a linked list.** When created, a linked list should have *no* head node associated with it. The LinkedList instance will have one property, 'head', which is a reference to the first node of the linked list. By default 'head' should be 'null'. 17 | 18 | 3. add following methods to the linked list: 19 | - **insertFirst** creates a new node from argument 'data' and assigns the resultign node to the 'head' property. Make sure to handle the case in which the linked list already has a node assigned to the 'head' property. 20 | - **insertLast** inserts a new node with provided data at the end of the chain 21 | - **insertAt** inserts a new node at provided index 22 | - **getFirst** returns the first node of the linked list 23 | - **getLast** returns the last node of the linked list 24 | - **getAt** returns the node at the provided index 25 | - **removeFirst** removes only the first node of the linked list. The list's head should now be the second element. 26 | - **removeLast** removes only the last node of the chain. 27 | - **removeAt** removes node at the provided index. 28 | - **size** returns the number of nodes in the linked list. 29 | - **clear** empties the linked list of any nodes. 30 | 31 | #### Examples 32 | 33 | ```` 34 | const n = new Node('There'); 35 | n.data // 'Hi' 36 | n.next // null 37 | const n2 = new Node('Hi', n); 38 | n.next // returns n 39 | ```` 40 | 41 | ```` 42 | const list = new LinkedList(); 43 | list.head // null 44 | 45 | const list = new LinkedList(); 46 | list.insertFirst('a'); // List has one node 47 | list.insertFirst('b') 48 | list.insertFirst('c') 49 | list.size(); // returns 3 50 | list.removeFirst() //removes 'c' 51 | list.removeLast() //removes 'a' 52 | list.size() // returns 1 53 | list.insertFirst('b') 54 | list.insertLast('c') 55 | list.getLast //returns 'c' 56 | list.size() // returns 3 57 | list.clear(); 58 | list.size(); // returns 0 59 | ```` 60 | 61 | 62 | #### Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy 63 | -------------------------------------------------------------------------------- /algos/level2/week4/robert.test.js: -------------------------------------------------------------------------------- 1 | // describe() 2 | 3 | const {checkGrades,checkForBonus,convertGrades, getTotalScore, findCracker} = require('./robert.index.js'); 4 | 5 | const arrayOfstudentResults =[ 6 | ["name1", 180, ["A","B","A","A","A","B"]], 7 | ["name2", 145, ["A","B","A","A","A","D"]], 8 | ["name3", 2000, ["A","B","A","A","A",]] 9 | ] 10 | 11 | 12 | 13 | describe('Check the health and functionality of the helper functions', function () { 14 | test('should return array of grades lower than B', () => { 15 | const arraywithOneLowGrade = ["A","B","A","A","A","D"] 16 | const arraywithTwoLowGrade = ["A","B","C","A","A","D"] 17 | const arraywithNoLowGrade = ["A","B","A","A","A",] 18 | expect(checkGrades(arraywithOneLowGrade)).toEqual(["D"]); 19 | expect(checkGrades(arraywithTwoLowGrade)).toEqual(["C","D"]); 20 | expect(checkGrades(arraywithNoLowGrade)).toEqual([]); 21 | }); 22 | 23 | test('should indicate if student got the bonus score', () => { 24 | const arraywithNoBonusDueToLength = ["A","B","A","A"] 25 | const arraywithNoBonusDueToABadGrade = ["A","B","C","A","A","D"] 26 | const arraywithBonus = ["A","B","A","A","A",] 27 | expect(checkForBonus(arraywithNoBonusDueToLength)).toEqual(false); 28 | expect(checkForBonus(arraywithNoBonusDueToABadGrade)).toEqual(false); 29 | expect(checkForBonus(arraywithBonus)).toEqual(true); 30 | }); 31 | 32 | test('should shows convertGrade Function is in properHealth', () => { 33 | const array1 = ["A","B","A","A"] 34 | const array2 = ["A","B","C","A","A","D"] 35 | const array3 = ["A","B","A","A","A",] 36 | expect(convertGrades(array1)).toEqual(110); 37 | expect(convertGrades(array2)).toEqual(125); 38 | expect(convertGrades(array3)).toEqual(140); 39 | }); 40 | 41 | test('getTotalScore Helper Function calculates the converts grades to scores, sums and gives bonus(if any)', () => { 42 | const array = ["A","B","C","A","A","D"] 43 | const arraywithBonus = ["A","B","A","A","A",] 44 | const arraywithNoBonus = ["A","B","A","A"] 45 | expect(getTotalScore(array)).toEqual(125); 46 | expect(getTotalScore(arraywithBonus)).toEqual(160); 47 | expect(getTotalScore(arraywithNoBonus)).toEqual(110); 48 | }); 49 | }); 50 | 51 | describe('Find Cracker Logic', function () { 52 | test('should always return array of names of student whose results were hacked', () => { 53 | const arrayOfstudentResults =[ 54 | ["Phillip Aguip", 180, ["A","B","A","A","A","B"]], 55 | ["Paula Johannsen", 145, ["A","B","A","A","A","D"]], 56 | ["Jonah Hill", 2000, ["A","B","A","A","A",]] 57 | ] 58 | expect(findCracker(arrayOfstudentResults)).toEqual(['Jonah Hill']) 59 | }); 60 | }); -------------------------------------------------------------------------------- /algos/level2/week14/robert.test.js: -------------------------------------------------------------------------------- 1 | const Queue = require('./robert.index') 2 | 3 | describe('Test that class is imported/exported correctly',()=>{ 4 | test('Queue should be defined', () => { 5 | expect(Queue).toBeDefined(); 6 | }); 7 | }) 8 | const emptyQueue = new Queue(); 9 | const queueWithOneValue = new Queue([1]); 10 | const queueWithSeveralTypes = new Queue([2,3,'etki', true, 5, '2021']); 11 | 12 | describe('The class construction is working well', () =>{ 13 | test('that the queues initial values are as they are expected to be', () => { 14 | expect(emptyQueue.values).toEqual(expect.arrayContaining([])) 15 | expect(queueWithOneValue.values).toEqual(expect.arrayContaining([1])) 16 | expect(queueWithSeveralTypes.values).toEqual(expect.arrayContaining([2,3,'etki', true, 5, '2021'])) 17 | }) 18 | }) 19 | 20 | 21 | describe('The add method', () =>{ 22 | emptyQueue.add('move') 23 | queueWithOneValue.add(2) 24 | queueWithSeveralTypes.add(1) 25 | test('that values can be added to the queues', () => { 26 | expect(emptyQueue.values).toEqual(expect.arrayContaining(['move'])) 27 | expect(queueWithOneValue.values).toEqual(expect.arrayContaining([2,1])) 28 | expect(queueWithSeveralTypes.values).toEqual(expect.arrayContaining([1,2,3,'etki', true, 5, '2021'])) 29 | }) 30 | }) 31 | 32 | describe('The remove method', () =>{ 33 | test('that values can be removed from end of the queue', () => { 34 | emptyQueue.remove() 35 | queueWithOneValue.remove() 36 | queueWithSeveralTypes.remove() 37 | expect(emptyQueue.values).toEqual(expect.arrayContaining([])) 38 | expect(queueWithOneValue.values).toEqual(expect.arrayContaining([2])) 39 | expect(queueWithSeveralTypes.values).toEqual(expect.arrayContaining([1,2,3,'etki', true, 5,])) 40 | }) 41 | }) 42 | 43 | describe('The Oldest method', () =>{ 44 | test('that the method returns the first value in the queue', () => { 45 | expect(emptyQueue.oldest()).toBe(undefined) 46 | expect(queueWithOneValue.oldest()).toBe(2) 47 | expect(queueWithSeveralTypes.oldest()).toBe(5) 48 | }) 49 | }) 50 | 51 | describe('The Newest method', () =>{ 52 | test('that the method returns the last value in the queue', () => { 53 | expect(emptyQueue.newest()).toBe(undefined) 54 | expect(queueWithOneValue.newest()).toBe(2) 55 | expect(queueWithSeveralTypes.newest()).toBe(1) 56 | }) 57 | }) 58 | 59 | describe('The Size method', () =>{ 60 | test('that the method returns the size of the queue', () => { 61 | expect(emptyQueue.size()).toBe(0) 62 | expect(queueWithOneValue.size()).toBe(1) 63 | expect(queueWithSeveralTypes.size()).toBe(6) 64 | }) 65 | }) -------------------------------------------------------------------------------- /algos/level2/week18/gzan.index.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(data, next = null) { 3 | this.data = data; 4 | this.next = next; 5 | } 6 | } 7 | 8 | class LinkedList { 9 | constructor() { 10 | this.head = null; 11 | } 12 | 13 | insertFirst(data) { 14 | this.head = new Node(data, this.head); 15 | } 16 | 17 | insertLast(data) { 18 | const last = this.getLast(); 19 | 20 | if (last) { 21 | // There are some existing nodes in our chain 22 | last.next = new Node(data); 23 | } else { 24 | // The chain is empty! 25 | this.head = new Node(data); 26 | } 27 | } 28 | 29 | insertAt(data, index) { 30 | if (!this.head) { 31 | this.head = new Node(data); 32 | return; 33 | } 34 | 35 | if (index === 0) { 36 | this.head = new Node(data, this.head); 37 | return; 38 | } 39 | 40 | const previous = this.getAt(index - 1) || this.getLast(); 41 | const node = new Node(data, previous.next); 42 | previous.next = node; 43 | } 44 | 45 | getFirst() { 46 | return this.head; 47 | } 48 | 49 | getLast() { 50 | if (!this.head) { 51 | return null; 52 | } 53 | 54 | let node = this.head; 55 | while (node) { 56 | if (!node.next) { 57 | return node; 58 | } 59 | node = node.next; 60 | } 61 | } 62 | 63 | getAt(index) { 64 | let counter = 0; 65 | let node = this.head; 66 | while (node) { 67 | if (counter === index) { 68 | return node; 69 | } 70 | 71 | counter++; 72 | node = node.next; 73 | } 74 | return null; 75 | } 76 | 77 | removeFirst() { 78 | if (!this.head) { 79 | return; 80 | } 81 | 82 | this.head = this.head.next; 83 | } 84 | 85 | removeLast() { 86 | if (!this.head) { 87 | return; 88 | } 89 | 90 | if (!this.head.next) { 91 | this.head = null; 92 | return; 93 | } 94 | 95 | let previous = this.head; 96 | let node = this.head.next; 97 | while (node.next) { 98 | previous = node; 99 | node = node.next; 100 | } 101 | previous.next = null; 102 | } 103 | 104 | removeAt(index) { 105 | if (!this.head) { 106 | return; 107 | } 108 | 109 | if (index === 0) { 110 | this.head = this.head.next; 111 | return; 112 | } 113 | 114 | const previous = this.getAt(index - 1); 115 | if (!previous || !previous.next) { 116 | return; 117 | } 118 | previous.next = previous.next.next; 119 | } 120 | 121 | size() { 122 | let counter = 0; 123 | let node = this.head; 124 | 125 | while (node) { 126 | counter++; 127 | node = node.next; 128 | } 129 | 130 | return counter; 131 | } 132 | 133 | clear() { 134 | this.head = null; 135 | } 136 | 137 | } 138 | 139 | 140 | module.exports = { Node, LinkedList } 141 | 142 | //Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## TO DO 3 | 4 | ### one time 5 | 6 | * fork and clone the repo 7 | * setup environment (npm and jest) 8 | 9 | ### weekly 10 | 11 | 1. fetch and pull the changes in remote to your local 12 | 2. check the latest algo that is added to the repo every Sunday 13 | 3. write unit tests with jest (preferably in a separate file) 14 | 4. write your function(s) to solve the algo 15 | 5. test your code 16 | * if you pass all the tests, try to make your code more efficient and cleaner 17 | * if not, debug and turn back to step 3 or 5 until all tests work 18 | * if stuck, reach out for help 19 | 6. push your solution and make a pull request 20 | 7. check other accepted solutions 21 | 8. discuss the solutions on slack (if necessary) 22 | 9. feel welcome to contact the team for questions and feedback ;) 23 | 24 | ## HOW TO 25 | 26 | ### fork and clone the repo 27 | 1. click 'fork' on the upper left of the github page 28 | 2. go to the forked repo in your repositories 29 | 3. click 'clone or download' button 30 | 4. copy the link 31 | 5. go to your terminal and write this command: `git clone ` 32 | 6. add the original repo as upstream: `git remote add upstream https://github.com/etkitech/etki_JS.git` 33 | 7. go to the directory you will be working in: `cd etki_JS/algos` 34 | 35 | ### use jest 36 | 1. make sure that you are in the correct directory. If not go to algos directory. 37 | 2. install Jest: `npm install -g jest` (if windows: `sudo npm install -g jest`) 38 | 3. run a test: `jest levelFolderName/weekFolderName/yourTestfileName.js` 39 | 4. run all test files `jest` 40 | 5. stop test running: Ctrl + c 41 | 42 | ### update your local repo 43 | 1. make sure you are on the correct branch. If not, type: `git checkout master` 44 | #### checking and integrating the changes in a controlled manner 45 | 2. fetch changes in the original etki repo: `git fetch upstream` 46 | 3. go to your master branch: `git checkout master` 47 | 4. merge changes in the upstream branch (etki repo) to your local master branch: `git merge upstream/master` 48 | #### OR directly getting all the updates in the etki remote 49 | 2. pull all changes and make your local same as etki remote: `git pull upstream master` 50 | 51 | ### Write your code 52 | 1. Go to the relevant week folder: (Ex: Let's say you are in algos folder, you are level1 student and you want to solve algo of week 2, then type: `cd level1/week2`) 53 | 2. Create a new js file: for Mac/Linux: `touch fileName.js`, for Windows: `echo fileName.js` 54 | 3. Create a new test js file: for Mac/Linux: `touch fileName.test.js`, for Windows: `echo fileName.test.js` 55 | * you can create new files also manually of course 56 | 4. on the main js file, write a relevant function name with relevant parameters. You can use the names in the example in the relevant md file. Leave you function empty for now. Export the function. 57 | 5. on the test file, import your function from the other file and write your tests including several different cases. 58 | 6. when your tests are ready, turn back to your main.js file and complete your function. 59 | 7. run your tests explained above in use jest part 60 | 8. If some tests fail, check the failed tests and try to understand where the problem is. Try until all tests pass. Then refactor your code. 61 | 9. If all tests pass, you are ready to refactor your code. 62 | 10. If you are satisfied with your result, add your changes to the stagign area: `git add .` 63 | 11. Commit your changes with a short message telling what has been mainly done: `git commit -m "add blabla"` 64 | 12. Push your changes to your forked remote repo: `git push` 65 | 13. Go to your forked Github repo. Click on 'pull requests' and make it manually. 66 | 67 | 68 | -------------------------------------------------------------------------------- /cohort2020.md: -------------------------------------------------------------------------------- 1 | # etki_JS RCC - Cohort 2020 2 | 3 | _This document contains students' working repositories for etki_JS cohort 2020_ 4 | 5 | _Alphabetically sorted by Slack nickname_ 6 | 7 | | Slack Nickname | Repository URL | 8 | | ------ | ----------- | 9 | | @Abdullah Amida | https://www.github.com/YourGithubHandle/YourRepo | 10 | | @AmiOnodera | https://github.com/ami-onodera/full-stack-open-2020 | 11 | | @BrunoElo | https://github.com/BrunoElo/FullStackOpen2020 | 12 | | @Chidera | https://www.github.com/YourGithubHandle/YourRepo | 13 | | @Chidiogo | https://www.github.com/YourGithubHandle/YourRepo | 14 | | @Cindy | https://www.github.com/YourGithubHandle/YourRepo | 15 | | @daisy | https://github.com/aryomide | 16 | | @Debora | https://github.com/deboragaleano/fullstackopen | 17 | | @Dee Dan | https://www.github.com/YourGithubHandle/YourRepo | 18 | | @delz | https://github.com/areel007 | 19 | | @Ecem | https://www.github.com/YourGithubHandle/YourRepo | 20 | | @Elo Agbawe | https://github.com/Eloagbawe/fullstackopen | 21 | | @Emin | https://github.com/emindeniz99 | 22 | | @Emre | https://github.com/Emreburak1/fullstackopen | 23 | | @Enny | https://www.github.com/YourGithubHandle/YourRepo | 24 | | @Eren | https://github.com/erenguler1994/fullstackOpen2020 | 25 | | @fabio | https://www.github.com/YourGithubHandle/YourRepo | 26 | | @Fernanda | https://www.github.com/YourGithubHandle/YourRepo | 27 | | @Gblend | https://github.com/gblend/fullstackopen | 28 | | @George | https://github.com/devGeorgeOwi | 29 | | @Grace | https://github.com/babiryegrace20 | 30 | | @gzan | https://github.com/gzandiemer/fullstackopen | 31 | | @Hasan | https://www.github.com/oz1127/etki_JS_works | 32 | | @hubnotch | https://github.com/Hubnotch | 33 | | @immanuel | https://github.com/immanuelredd | 34 | | @jayumaks | https://github.com/jayumaks | 35 | | @Jennifer R. | https://github.com/jrussell416/fullstackopen | 36 | | @Jeremy H. | https://github.com/jeremyhuiskamp/fullstackopen.com/ | 37 | | @Kateryna | https://github.com/katamatata/fullstackopen | 38 | | @Kim | https://www.github.com/YourGithubHandle/YourRepo | 39 | | @Kirsi | https://github.com/Tsaikkari | 40 | | @Laura | https://github.com/lslada | 41 | | @Leila | https://github.com/LeiladosSantos11 | 42 | | @Leli | https://github.com/lelilia/fullstackopen | 43 | | @Maria M. | https://www.github.com/YourGithubHandle/YourRepo | 44 | | @Maria Z. | https://github.com/mashazyu | 45 | | @Merve G. | https://github.com/GulenayMer/etki_JS | 46 | | @miku86 | https://github.com/miku86/react-native-rate-repos | 47 | | @mino | https://github.com/miriamino | 48 | | @Miriam G. | https://github.com/miriamela/fullstackopen-etki-2020 | 49 | | @Nath L. | https://www.github.com/YourGithubHandle/YourRepo | 50 | | @Okan | https://www.github.com/YourGithubHandle/YourRepo | 51 | | @Oyedola | https://github.com/oyedolacode | 52 | | @Pelin | https://www.github.com/YourGithubHandle/YourRepo | 53 | | @Rieke | https://www.github.com/YourGithubHandle/YourRepo | 54 | | @Robert | https://www.github.com/Robertito1/FullStackOpen | 55 | | @Rohit | https://github.com/diru1100/fullstackopen | 56 | | @Ruth | https://github.com/Ruth-star | 57 | | @Schnitter | https://github.com/Stein-Hakase | 58 | | @Timothy | https://github.com/timothymayor | 59 | | @Türkan | https://github.com/Turkan027 | 60 | | @Umit | https://www.github.com/YourGithubHandle/YourRepo | 61 | | @Yomibrawn | https://www.github.com/YourGithubHandle/YourRepo | 62 | | @Viet Duc | https://github.com/bila9630 | 63 | | @Vivyanne | https://github.com/Vivyanne-504 | 64 | | @Yagmur | https://www.github.com/YourGithubHandle/YourRepo | 65 | | @Yasemin | https://github.com/yaseminertan | 66 | | @Zainab | https://github.com/oladipupozainab | 67 | | @Your Name | https://www.github.com/YourGithubHandle/YourRepo | 68 | 69 | --- 70 | -------------------------------------------------------------------------------- /algos/level2/week19/LinkedList.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(data, next = null) { 3 | this.data = data; 4 | this.next = next; 5 | } 6 | } 7 | 8 | class LinkedList { 9 | constructor(values = []) { 10 | this.head = null; 11 | 12 | for (let value of values) { 13 | this.insertLast(value); 14 | } 15 | } 16 | 17 | clear() { 18 | this.head = null; 19 | } 20 | 21 | size() { 22 | let counter = 0; 23 | let node = this.head; 24 | 25 | while (node) { 26 | counter++; 27 | node = node.next; 28 | } 29 | 30 | return counter; 31 | } 32 | 33 | getAt(index) { 34 | if (!this.head) { 35 | return null; 36 | } 37 | 38 | let counter = 0; 39 | let node = this.head; 40 | while (node) { 41 | if (counter === index) { 42 | return node; 43 | } 44 | node = node.next; 45 | counter++; 46 | } 47 | return null; 48 | } 49 | 50 | insertAt(data, index) { 51 | if (!this.head) { 52 | this.head = new Node(data); 53 | return; 54 | } 55 | 56 | if (index === 0) { 57 | this.head = new Node(data, this.head); 58 | return; 59 | } 60 | 61 | let counter = 1; 62 | let previous = this.head; 63 | let node = this.head.next; 64 | while (node) { 65 | if (counter === index) { 66 | previous.next = new Node(data, node); 67 | return; 68 | } 69 | previous = node; 70 | node = node.next; 71 | counter++; 72 | } 73 | 74 | previous.next = new Node(data, node); 75 | } 76 | 77 | removeFirst() { 78 | if (!this.head) { 79 | return; 80 | } 81 | 82 | this.head = this.head.next; 83 | } 84 | 85 | removeLast() { 86 | if (!this.head) { 87 | return; 88 | } 89 | 90 | if (!this.head.next) { 91 | this.head = null; 92 | return; 93 | } 94 | 95 | let previous = this.head; 96 | let node = this.head.next; 97 | while (node.next) { 98 | previous = node; 99 | node = node.next; 100 | } 101 | previous.next = null; 102 | } 103 | 104 | removeAt(index) { 105 | if (!this.head) { 106 | return; 107 | } 108 | 109 | let counter = 0; 110 | let node = this.head; 111 | while (node) { 112 | if (counter === index - 1) { 113 | if (node.next) { 114 | return (node.next = node.next.next); 115 | } else { 116 | return (node.next = null); 117 | } 118 | } 119 | node = node.next; 120 | counter++; 121 | } 122 | } 123 | 124 | getFirst() { 125 | return this.head; 126 | } 127 | 128 | insertFirst(data) { 129 | this.head = new Node(data, this.getFirst()); 130 | } 131 | 132 | getLast() { 133 | if (!this.head) { 134 | return null; 135 | } 136 | 137 | let node = this.head; 138 | while (node.next) { 139 | node = node.next; 140 | } 141 | 142 | return node; 143 | } 144 | 145 | insertLast(data) { 146 | const last = this.getLast(); 147 | 148 | if (last) { 149 | last.next = new Node(data); 150 | return last.next; 151 | } else { 152 | this.head = new Node(data); 153 | return this.head; 154 | } 155 | } 156 | 157 | forEach(fn) { 158 | if (!this.head) { 159 | return null; 160 | } 161 | 162 | let node = this.head; 163 | while (node) { 164 | fn(node); 165 | node = node.next; 166 | } 167 | } 168 | 169 | *[Symbol.iterator]() { 170 | let node = this.head; 171 | while (node) { 172 | yield node; 173 | node = node.next; 174 | } 175 | } 176 | } 177 | 178 | module.exports = { Node, LinkedList }; 179 | 180 | //Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level2/week20/LinkedList.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(data, next = null) { 3 | this.data = data; 4 | this.next = next; 5 | } 6 | } 7 | 8 | class LinkedList { 9 | constructor(values = []) { 10 | this.head = null; 11 | 12 | for (let value of values) { 13 | this.insertLast(value); 14 | } 15 | } 16 | 17 | clear() { 18 | this.head = null; 19 | } 20 | 21 | size() { 22 | let counter = 0; 23 | let node = this.head; 24 | 25 | while (node) { 26 | counter++; 27 | node = node.next; 28 | } 29 | 30 | return counter; 31 | } 32 | 33 | getAt(index) { 34 | if (!this.head) { 35 | return null; 36 | } 37 | 38 | let counter = 0; 39 | let node = this.head; 40 | while (node) { 41 | if (counter === index) { 42 | return node; 43 | } 44 | node = node.next; 45 | counter++; 46 | } 47 | return null; 48 | } 49 | 50 | insertAt(data, index) { 51 | if (!this.head) { 52 | this.head = new Node(data); 53 | return; 54 | } 55 | 56 | if (index === 0) { 57 | this.head = new Node(data, this.head); 58 | return; 59 | } 60 | 61 | let counter = 1; 62 | let previous = this.head; 63 | let node = this.head.next; 64 | while (node) { 65 | if (counter === index) { 66 | previous.next = new Node(data, node); 67 | return; 68 | } 69 | previous = node; 70 | node = node.next; 71 | counter++; 72 | } 73 | 74 | previous.next = new Node(data, node); 75 | } 76 | 77 | removeFirst() { 78 | if (!this.head) { 79 | return; 80 | } 81 | 82 | this.head = this.head.next; 83 | } 84 | 85 | removeLast() { 86 | if (!this.head) { 87 | return; 88 | } 89 | 90 | if (!this.head.next) { 91 | this.head = null; 92 | return; 93 | } 94 | 95 | let previous = this.head; 96 | let node = this.head.next; 97 | while (node.next) { 98 | previous = node; 99 | node = node.next; 100 | } 101 | previous.next = null; 102 | } 103 | 104 | removeAt(index) { 105 | if (!this.head) { 106 | return; 107 | } 108 | 109 | let counter = 0; 110 | let node = this.head; 111 | while (node) { 112 | if (counter === index - 1) { 113 | if (node.next) { 114 | return (node.next = node.next.next); 115 | } else { 116 | return (node.next = null); 117 | } 118 | } 119 | node = node.next; 120 | counter++; 121 | } 122 | } 123 | 124 | getFirst() { 125 | return this.head; 126 | } 127 | 128 | insertFirst(data) { 129 | this.head = new Node(data, this.getFirst()); 130 | } 131 | 132 | getLast() { 133 | if (!this.head) { 134 | return null; 135 | } 136 | 137 | let node = this.head; 138 | while (node.next) { 139 | node = node.next; 140 | } 141 | 142 | return node; 143 | } 144 | 145 | insertLast(data) { 146 | const last = this.getLast(); 147 | 148 | if (last) { 149 | last.next = new Node(data); 150 | return last.next; 151 | } else { 152 | this.head = new Node(data); 153 | return this.head; 154 | } 155 | } 156 | 157 | forEach(fn) { 158 | if (!this.head) { 159 | return null; 160 | } 161 | 162 | let node = this.head; 163 | while (node) { 164 | fn(node); 165 | node = node.next; 166 | } 167 | } 168 | 169 | *[Symbol.iterator]() { 170 | let node = this.head; 171 | while (node) { 172 | yield node; 173 | node = node.next; 174 | } 175 | } 176 | } 177 | 178 | module.exports = { Node, LinkedList }; 179 | 180 | //Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /algos/level2/week18/robert.index.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(data, next){ 3 | this.data = data; 4 | this.next = next ? next : null; 5 | } 6 | } 7 | 8 | class List { 9 | constructor(){ 10 | this.head = null; 11 | } 12 | 13 | insertFirst(data){ 14 | let current = this.head; 15 | let node = new Node(data); 16 | if(!current){ 17 | this.head = node; 18 | return data; 19 | }else { 20 | node.next = current; 21 | this.head = node; 22 | } 23 | return data; 24 | } 25 | 26 | insertLast(data){ 27 | let current = this.head; 28 | let node = new Node(data); 29 | if(!current){ 30 | this.head = node; 31 | return data; 32 | }else { 33 | while(current.next){ 34 | current = current.next 35 | } 36 | current.next = node 37 | } 38 | return node; 39 | } 40 | 41 | insertAt(data, index){ 42 | let current = this.head 43 | let node = new Node(data) 44 | let previous; 45 | if(index === 0){ 46 | return this.insertFirst(data) 47 | } 48 | for(let i = 0; i <= index - 1; i++){ 49 | if(current.next){ 50 | previous = current 51 | current = current.next 52 | continue; 53 | }else{ 54 | current.next = node 55 | return node 56 | } 57 | } 58 | previous.next = node 59 | node.next = current 60 | // return { 61 | // data: node.data, 62 | // next: node.next.data 63 | // } 64 | } 65 | 66 | getFirst(){ 67 | if(!this.head){ 68 | return null 69 | } 70 | return this.head 71 | } 72 | 73 | getLast(){ 74 | let current = this.head; 75 | while(current.next){ 76 | current = current.next 77 | } 78 | return current 79 | } 80 | 81 | getAt(index){ 82 | if(this.size() - 1 < index){ 83 | return null 84 | } 85 | let current = this.head; 86 | let previous 87 | for(let i = 0; i <= index; i++){ 88 | previous = current 89 | current = current.next ? current.next : current 90 | } 91 | return previous 92 | } 93 | 94 | removeFirst(){ 95 | if(!this.head){ 96 | return null 97 | } 98 | this.head = this.head.next 99 | } 100 | 101 | 102 | removeLast(){ 103 | if(this.size() === 1 || this.size() === 0){ 104 | this.head = null 105 | return 106 | } 107 | let current = this.head; 108 | let previous; 109 | while(current.next){ 110 | previous = current 111 | current = current.next 112 | } 113 | previous.next = null 114 | return current 115 | } 116 | 117 | removeAt(index){ 118 | let current = this.head 119 | let previous; 120 | let round = 0 121 | if(index === 0){ 122 | return this.removeFirst() 123 | } 124 | if(this.size() - 1 < index){ 125 | return null 126 | } 127 | while(round !== index){ 128 | previous = current; 129 | current = current.next ? current.next : null; 130 | round++ 131 | } 132 | previous.next = current.next ? current.next : null 133 | // return{ data: current.data, 134 | // next: current.next ? current.next.data : null 135 | // } 136 | } 137 | 138 | size(){ 139 | let current = this.head; 140 | let length = 1 141 | if(!this.head){ 142 | return 0 143 | } 144 | while(current.next){ 145 | current = current.next 146 | length = length + 1 147 | } 148 | return length 149 | } 150 | 151 | clear(){ 152 | this.head = null 153 | return 'cleared!' 154 | } 155 | } 156 | 157 | module.exports = { 158 | Node, List 159 | } -------------------------------------------------------------------------------- /algos/level2/week18/robert.test.js: -------------------------------------------------------------------------------- 1 | const { Node, List} = require('./robert.index') 2 | 3 | describe('Test that classes are imported/exported correctly',()=>{ 4 | test('Node and List classes should be defined', () => { 5 | expect(Node).toBeDefined(); 6 | expect(List).toBeDefined(); 7 | }); 8 | }) 9 | 10 | 11 | describe('The node class behaves as the question specifies', () =>{ 12 | const node = new Node('element'); 13 | const node2 = new Node('element', node); 14 | test('that a new node can be created when only the data parameter is passed', () => { 15 | expect(node.data).toEqual("element") 16 | expect(node.next).toEqual(null) 17 | }) 18 | test('that a new node can be created when the data and next parameter are passed', () => { 19 | expect(node2.data).toEqual("element") 20 | expect(node2.next).toEqual(node) 21 | }) 22 | }) 23 | 24 | 25 | describe('The different Insert methods', () =>{ 26 | test('that values can be added to the front of the list', () => { 27 | const list1 = new List() 28 | list1.insertFirst(4) 29 | expect(list1.head.data).toBe(4) 30 | }) 31 | 32 | test('that values can be added to the end of the list', () => { 33 | const list2 = new List() 34 | list2.insertFirst(4) 35 | list2.insertLast('linked lists are cool') 36 | expect(list2.head.data).toBe(4) 37 | expect(list2.getLast().data).toBe('linked lists are cool') 38 | }) 39 | 40 | test('that values can be inserted into any index of the list', () => { 41 | const list3 = new List() 42 | list3.insertFirst(4) 43 | list3.insertLast('linked lists are cool') 44 | list3.insertAt('5', 1) 45 | expect(list3.head.data).toBe(4) 46 | expect(list3.getAt(1).data).toBe('5') 47 | expect(list3.getLast().data).toBe('linked lists are cool') 48 | }) 49 | }) 50 | 51 | describe('The different remove methods', () =>{ 52 | const list4 = new List() 53 | list4.insertFirst(6) 54 | list4.insertFirst(5) 55 | list4.insertFirst(4) 56 | list4.insertFirst(3) 57 | list4.insertFirst(2) 58 | list4.insertFirst(1) 59 | test('that values can be removed from the start of the list', () => { 60 | list4.removeFirst() 61 | expect(list4.getFirst().data).toBe(2) 62 | expect(list4.size()).toBe(5) 63 | }) 64 | test('that values can be removed from the end of the list', () => { 65 | expect(list4.getLast().data).toBe(6) 66 | list4.removeLast() 67 | expect(list4.getLast().data).toBe(5) 68 | expect(list4.size()).toBe(4) 69 | }) 70 | test('that values can be removed from any index the list', () => { 71 | expect(list4.getAt(2).data).toBe(4) 72 | list4.removeAt(2) 73 | expect(list4.getAt(2).data).toBe(5) 74 | expect(list4.size()).toBe(3) 75 | }) 76 | }) 77 | 78 | const list5 = new List() 79 | list5.insertFirst('blob') 80 | list5.insertFirst('array') 81 | list5.insertFirst('string') 82 | list5.insertFirst('integer') 83 | list5.insertFirst('double') 84 | list5.insertFirst('bigint') 85 | describe('The different get methods', () =>{ 86 | 87 | test('that values can be gotten from the start of the list', () => { 88 | const value = list5.getFirst().data 89 | expect(value).toBe('bigint') 90 | }) 91 | test('that values can be gotten from the end of the list', () => { 92 | const value = list5.getLast().data 93 | expect(value).toBe('blob') 94 | }) 95 | test('that values can be gotten from any index in the list', () => { 96 | const value = list5.getAt(3).data 97 | expect(value).toBe('string') 98 | }) 99 | }) 100 | 101 | describe('The size method', () =>{ 102 | test('that the method get the size of the list', () => { 103 | const value = list5.size() 104 | expect(value).toBe(6) 105 | }) 106 | }) 107 | 108 | describe('The clear method', () =>{ 109 | test('that the method returns an empty list', () => { 110 | const value = list5.clear() 111 | expect(value).toBe('cleared!') 112 | expect(list5.head).toBe(null) 113 | }) 114 | }) -------------------------------------------------------------------------------- /algos/level2/week18/gzan.test.js: -------------------------------------------------------------------------------- 1 | const L = require('./gzan.index'); 2 | const List = L.LinkedList; 3 | const Node = L.Node; 4 | 5 | test('List is a class', () => { 6 | expect(typeof List.prototype.constructor).toEqual('function'); 7 | }); 8 | 9 | test('Node is a class', () => { 10 | expect(typeof Node.prototype.constructor).toEqual('function'); 11 | }); 12 | 13 | describe('A Node', () => { 14 | test('has properties "data" and "next"', () => { 15 | const node = new Node('a', 'b'); 16 | expect(node.data).toEqual('a'); 17 | expect(node.next).toEqual('b'); 18 | }); 19 | }); 20 | 21 | describe('Insert First', () => { 22 | test('appends a node to the start of the list', () => { 23 | const l = new List(); 24 | l.insertFirst(1); 25 | expect(l.head.data).toEqual(1); 26 | l.insertFirst(2); 27 | expect(l.head.data).toEqual(2); 28 | }); 29 | }); 30 | 31 | describe('Size', () => { 32 | test('returns the number of items in the linked list', () => { 33 | const l = new List(); 34 | expect(l.size()).toEqual(0); 35 | l.insertFirst(1); 36 | l.insertFirst(1); 37 | l.insertFirst(1); 38 | l.insertFirst(1); 39 | expect(l.size()).toEqual(4); 40 | }); 41 | }); 42 | 43 | describe('GetFirst', () => { 44 | test('returns the first element', () => { 45 | const l = new List(); 46 | l.insertFirst(1); 47 | expect(l.getFirst().data).toEqual(1); 48 | l.insertFirst(2); 49 | expect(l.getFirst().data).toEqual(2); 50 | }); 51 | }); 52 | 53 | describe('GetLast', () => { 54 | test('returns the last element', () => { 55 | const l = new List(); 56 | l.insertFirst(2); 57 | expect(l.getLast()).toEqual({ data: 2, next: null }); 58 | l.insertFirst(1); 59 | expect(l.getLast()).toEqual({ data: 2, next: null }); 60 | }); 61 | }); 62 | 63 | describe('Clear', () => { 64 | test('empties out the list', () => { 65 | const l = new List(); 66 | expect(l.size()).toEqual(0); 67 | l.insertFirst(1); 68 | l.insertFirst(1); 69 | l.insertFirst(1); 70 | l.insertFirst(1); 71 | expect(l.size()).toEqual(4); 72 | l.clear(); 73 | expect(l.size()).toEqual(0); 74 | }); 75 | }); 76 | 77 | describe('RemoveFirst', () => { 78 | test('removes the first node when the list has a size of one', () => { 79 | const l = new List(); 80 | l.insertFirst('a'); 81 | l.removeFirst(); 82 | expect(l.size()).toEqual(0); 83 | expect(l.getFirst()).toEqual(null); 84 | }); 85 | 86 | test('removes the first node when the list has a size of three', () => { 87 | const l = new List(); 88 | l.insertFirst('c'); 89 | l.insertFirst('b'); 90 | l.insertFirst('a'); 91 | l.removeFirst(); 92 | expect(l.size()).toEqual(2); 93 | expect(l.getFirst().data).toEqual('b'); 94 | l.removeFirst(); 95 | expect(l.size()).toEqual(1); 96 | expect(l.getFirst().data).toEqual('c'); 97 | }); 98 | }); 99 | 100 | describe('RemoveLast', () => { 101 | test('RemoveLast removes the last node when list is empty', () => { 102 | const l = new List(); 103 | expect(() => { 104 | l.removeLast(); 105 | }).not.toThrow(); 106 | }); 107 | 108 | test('RemoveLast removes the last node when list is length 1', () => { 109 | const l = new List(); 110 | l.insertFirst('a'); 111 | l.removeLast(); 112 | expect(l.head).toEqual(null); 113 | }); 114 | 115 | test('RemoveLast removes the last node when list is length 2', () => { 116 | const l = new List(); 117 | l.insertFirst('b'); 118 | l.insertFirst('a'); 119 | 120 | l.removeLast(); 121 | 122 | expect(l.size()).toEqual(1); 123 | expect(l.head.data).toEqual('a'); 124 | }); 125 | 126 | test('RemoveLast removes the last node when list is length 3', () => { 127 | const l = new List(); 128 | l.insertFirst('c'); 129 | l.insertFirst('b'); 130 | l.insertFirst('a'); 131 | l.removeLast(); 132 | 133 | expect(l.size()).toEqual(2); 134 | expect(l.getLast().data).toEqual('b'); 135 | }); 136 | }); 137 | 138 | describe('InsertLast', () => { 139 | test('adds to the end of the list', () => { 140 | const l = new List(); 141 | l.insertFirst('a'); 142 | 143 | l.insertLast('b'); 144 | 145 | expect(l.size()).toEqual(2); 146 | expect(l.getLast().data).toEqual('b'); 147 | }); 148 | }); 149 | 150 | describe('GetAt', () => { 151 | test('returns the node at given index', () => { 152 | const l = new List(); 153 | expect(l.getAt(10)).toEqual(null); 154 | 155 | l.insertLast(1); 156 | l.insertLast(2); 157 | l.insertLast(3); 158 | l.insertLast(4); 159 | 160 | expect(l.getAt(0).data).toEqual(1); 161 | expect(l.getAt(1).data).toEqual(2); 162 | expect(l.getAt(2).data).toEqual(3); 163 | expect(l.getAt(3).data).toEqual(4); 164 | }); 165 | }); 166 | 167 | describe('RemoveAt', () => { 168 | test('removeAt doesnt crash on an empty list', () => { 169 | const l = new List(); 170 | expect(() => { 171 | l.removeAt(0); 172 | l.removeAt(1); 173 | l.removeAt(2); 174 | }).not.toThrow(); 175 | }); 176 | 177 | test('removeAt doesnt crash on an index out of bounds', () => { 178 | const l = new List(); 179 | expect(() => { 180 | const l = new List(); 181 | l.insertFirst('a'); 182 | l.removeAt(1); 183 | }).not.toThrow(); 184 | }); 185 | 186 | test('removeAt deletes the first node', () => { 187 | const l = new List(); 188 | l.insertLast(1); 189 | l.insertLast(2); 190 | l.insertLast(3); 191 | l.insertLast(4); 192 | expect(l.getAt(0).data).toEqual(1); 193 | l.removeAt(0); 194 | expect(l.getAt(0).data).toEqual(2); 195 | }); 196 | 197 | test('removeAt deletes the node at the given index', () => { 198 | const l = new List(); 199 | l.insertLast(1); 200 | l.insertLast(2); 201 | l.insertLast(3); 202 | l.insertLast(4); 203 | expect(l.getAt(1).data).toEqual(2); 204 | l.removeAt(1); 205 | expect(l.getAt(1).data).toEqual(3); 206 | }); 207 | 208 | test('removeAt works on the last node', () => { 209 | const l = new List(); 210 | l.insertLast(1); 211 | l.insertLast(2); 212 | l.insertLast(3); 213 | l.insertLast(4); 214 | expect(l.getAt(3).data).toEqual(4); 215 | l.removeAt(3); 216 | expect(l.getAt(3)).toEqual(null); 217 | }); 218 | }); 219 | 220 | describe('InsertAt', () => { 221 | test('inserts a new node with data at the 0 index when the list is empty', () => { 222 | const l = new List(); 223 | l.insertAt('hi', 0); 224 | expect(l.getFirst().data).toEqual('hi'); 225 | }); 226 | 227 | test('inserts a new node with data at the 0 index when the list has elements', () => { 228 | const l = new List(); 229 | l.insertLast('a'); 230 | l.insertLast('b'); 231 | l.insertLast('c'); 232 | l.insertAt('hi', 0); 233 | expect(l.getAt(0).data).toEqual('hi'); 234 | expect(l.getAt(1).data).toEqual('a'); 235 | expect(l.getAt(2).data).toEqual('b'); 236 | expect(l.getAt(3).data).toEqual('c'); 237 | }); 238 | 239 | test('inserts a new node with data at a middle index', () => { 240 | const l = new List(); 241 | l.insertLast('a'); 242 | l.insertLast('b'); 243 | l.insertLast('c'); 244 | l.insertLast('d'); 245 | l.insertAt('hi', 2); 246 | expect(l.getAt(0).data).toEqual('a'); 247 | expect(l.getAt(1).data).toEqual('b'); 248 | expect(l.getAt(2).data).toEqual('hi'); 249 | expect(l.getAt(3).data).toEqual('c'); 250 | expect(l.getAt(4).data).toEqual('d'); 251 | }); 252 | 253 | test('inserts a new node with data at a last index', () => { 254 | const l = new List(); 255 | l.insertLast('a'); 256 | l.insertLast('b'); 257 | l.insertAt('hi', 2); 258 | expect(l.getAt(0).data).toEqual('a'); 259 | expect(l.getAt(1).data).toEqual('b'); 260 | expect(l.getAt(2).data).toEqual('hi'); 261 | }); 262 | 263 | test('insert a new node when index is out of bounds', () => { 264 | const l = new List(); 265 | l.insertLast('a'); 266 | l.insertLast('b'); 267 | l.insertAt('hi', 30); 268 | 269 | expect(l.getAt(0).data).toEqual('a'); 270 | expect(l.getAt(1).data).toEqual('b'); 271 | expect(l.getAt(2).data).toEqual('hi'); 272 | }); 273 | }); 274 | 275 | 276 | //Source: The Coding Interview Bootcamp: Algorithms + Data Structures by Stephen Grider at Udemy -------------------------------------------------------------------------------- /LICENSE.md/LICENSE.md: -------------------------------------------------------------------------------- 1 | This project is licensed under [Attribution-NonCommercial-NoDerivatives 4.0 International](https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode) 2 | 3 | [![](https://creativecommons.org/wp-content/themes/cc/images/cc.logo.white.svg)](https://creativecommons.org/) 4 | 5 | Creative Commons Legal Code 6 | =========================== 7 | 8 | Attribution-NonCommercial-NoDerivatives 4.0 International 9 | --------------------------------------------------------- 10 | 11 | Official translations of this license are available [in other 12 | languages](#languages). 13 | 14 | Creative Commons Corporation (“Creative Commons”) is not a law firm and 15 | does not provide legal services or legal advice. Distribution of 16 | Creative Commons public licenses does not create a lawyer-client or 17 | other relationship. Creative Commons makes its licenses and related 18 | information available on an “as-is” basis. Creative Commons gives no 19 | warranties regarding its licenses, any material licensed under their 20 | terms and conditions, or any related information. Creative Commons 21 | disclaims all liability for damages resulting from their use to the 22 | fullest extent possible. 23 | 24 | **Using Creative Commons Public Licenses** 25 | 26 | Creative Commons public licenses provide a standard set of terms and 27 | conditions that creators and other rights holders may use to share 28 | original works of authorship and other material subject to copyright and 29 | certain other rights specified in the public license below. The 30 | following considerations are for informational purposes only, are not 31 | exhaustive, and do not form part of our licenses. 32 | 33 | **Considerations for licensors:** Our public licenses are intended for 34 | use by those authorized to give the public permission to use material in 35 | ways otherwise restricted by copyright and certain other rights. Our 36 | licenses are irrevocable. Licensors should read and understand the terms 37 | and conditions of the license they choose before applying it. Licensors 38 | should also secure all rights necessary before applying our licenses so 39 | that the public can reuse the material as expected. Licensors should 40 | clearly mark any material not subject to the license. This includes 41 | other CC-licensed material, or material used under an exception or 42 | limitation to copyright. [More considerations for 43 | licensors.](//wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensors) 44 | 45 | **Considerations for the public:** By using one of our public licenses, 46 | a licensor grants the public permission to use the licensed material 47 | under specified terms and conditions. If the licensor’s permission is 48 | not necessary for any reason–for example, because of any applicable 49 | exception or limitation to copyright–then that use is not regulated by 50 | the license. Our licenses grant only permissions under copyright and 51 | certain other rights that a licensor has authority to grant. Use of the 52 | licensed material may still be restricted for other reasons, including 53 | because others have copyright or other rights in the material. A 54 | licensor may make special requests, such as asking that all changes be 55 | marked or described. Although not required by our licenses, you are 56 | encouraged to respect those requests where reasonable. [More 57 | considerations for the 58 | public.](//wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensees) 59 | 60 | ### Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License 61 | 62 | By exercising the Licensed Rights (defined below), You accept and agree 63 | to be bound by the terms and conditions of this Creative Commons 64 | Attribution-NonCommercial-NoDerivatives 4.0 International Public License 65 | ("Public License"). To the extent this Public License may be interpreted 66 | as a contract, You are granted the Licensed Rights in consideration of 67 | Your acceptance of these terms and conditions, and the Licensor grants 68 | You such rights in consideration of benefits the Licensor receives from 69 | making the Licensed Material available under these terms and conditions. 70 | 71 | **Section 1 – Definitions.** 72 | 73 | 1. **Adapted Material** means material subject to Copyright and Similar 74 | Rights that is derived from or based upon the Licensed Material and 75 | in which the Licensed Material is translated, altered, arranged, 76 | transformed, or otherwise modified in a manner requiring permission 77 | under the Copyright and Similar Rights held by the Licensor. For 78 | purposes of this Public License, where the Licensed Material is a 79 | musical work, performance, or sound recording, Adapted Material is 80 | always produced where the Licensed Material is synched in timed 81 | relation with a moving image. 82 | 2. **Copyright and Similar Rights** means copyright and/or similar 83 | rights closely related to copyright including, without limitation, 84 | performance, broadcast, sound recording, and Sui Generis Database 85 | Rights, without regard to how the rights are labeled or categorized. 86 | For purposes of this Public License, the rights specified in Section 87 | [2(b)(1)-(2)](#s2b) are not Copyright and Similar Rights. 88 | 3. **Effective Technological Measures** means those measures that, in 89 | the absence of proper authority, may not be circumvented under laws 90 | fulfilling obligations under Article 11 of the WIPO Copyright Treaty 91 | adopted on December 20, 1996, and/or similar international 92 | agreements. 93 | 4. **Exceptions and Limitations** means fair use, fair dealing, and/or 94 | any other exception or limitation to Copyright and Similar Rights 95 | that applies to Your use of the Licensed Material. 96 | 5. **Licensed Material** means the artistic or literary work, database, 97 | or other material to which the Licensor applied this Public License. 98 | 6. **Licensed Rights** means the rights granted to You subject to the 99 | terms and conditions of this Public License, which are limited to 100 | all Copyright and Similar Rights that apply to Your use of the 101 | Licensed Material and that the Licensor has authority to license. 102 | 7. **Licensor** means the individual(s) or entity(ies) granting rights 103 | under this Public License. 104 | 8. **NonCommercial** means not primarily intended for or directed 105 | towards commercial advantage or monetary compensation. For purposes 106 | of this Public License, the exchange of the Licensed Material for 107 | other material subject to Copyright and Similar Rights by digital 108 | file-sharing or similar means is NonCommercial provided there is no 109 | payment of monetary compensation in connection with the exchange. 110 | 9. **Share** means to provide material to the public by any means or 111 | process that requires permission under the Licensed Rights, such as 112 | reproduction, public display, public performance, distribution, 113 | dissemination, communication, or importation, and to make material 114 | available to the public including in ways that members of the public 115 | may access the material from a place and at a time individually 116 | chosen by them. 117 | 10. **Sui Generis Database Rights** means rights other than copyright 118 | resulting from Directive 96/9/EC of the European Parliament and of 119 | the Council of 11 March 1996 on the legal protection of databases, 120 | as amended and/or succeeded, as well as other essentially equivalent 121 | rights anywhere in the world. 122 | 11. **You** means the individual or entity exercising the Licensed 123 | Rights under this Public License. **Your** has a corresponding 124 | meaning. 125 | 126 | **Section 2 – Scope.** 127 | 128 | 1. **License grant**. 129 | 1. Subject to the terms and conditions of this Public License, the 130 | Licensor hereby grants You a worldwide, royalty-free, 131 | non-sublicensable, non-exclusive, irrevocable license to 132 | exercise the Licensed Rights in the Licensed Material to: 133 | 1. reproduce and Share the Licensed Material, in whole or in 134 | part, for NonCommercial purposes only; and 135 | 2. produce and reproduce, but not Share, Adapted Material for 136 | NonCommercial purposes only. 137 | 138 | 2. Exceptions and Limitations. For the avoidance of doubt, where 139 | Exceptions and Limitations apply to Your use, this Public 140 | License does not apply, and You do not need to comply with its 141 | terms and conditions. 142 | 3. Term. The term of this Public License is specified in Section 143 | [6(a)](#s6a). 144 | 4. Media and formats; technical modifications allowed. The Licensor 145 | authorizes You to exercise the Licensed Rights in all media and 146 | formats whether now known or hereafter created, and to make 147 | technical modifications necessary to do so. The Licensor waives 148 | and/or agrees not to assert any right or authority to forbid You 149 | from making technical modifications necessary to exercise the 150 | Licensed Rights, including technical modifications necessary to 151 | circumvent Effective Technological Measures. For purposes of 152 | this Public License, simply making modifications authorized by 153 | this Section [2(a)(4)](#s2a4) never produces Adapted Material. 154 | 5. Downstream recipients. 155 | 1. Offer from the Licensor – Licensed Material. Every recipient 156 | of the Licensed Material automatically receives an offer 157 | from the Licensor to exercise the Licensed Rights under the 158 | terms and conditions of this Public License. 159 | 2. No downstream restrictions. You may not offer or impose any 160 | additional or different terms or conditions on, or apply any 161 | Effective Technological Measures to, the Licensed Material 162 | if doing so restricts exercise of the Licensed Rights by any 163 | recipient of the Licensed Material. 164 | 165 | 6. No endorsement. Nothing in this Public License constitutes or 166 | may be construed as permission to assert or imply that You are, 167 | or that Your use of the Licensed Material is, connected with, or 168 | sponsored, endorsed, or granted official status by, the Licensor 169 | or others designated to receive attribution as provided in 170 | Section [3(a)(1)(A)(i)](#s3a1Ai). 171 | 172 | 2. **Other rights**. 173 | 174 | 1. Moral rights, such as the right of integrity, are not licensed 175 | under this Public License, nor are publicity, privacy, and/or 176 | other similar personality rights; however, to the extent 177 | possible, the Licensor waives and/or agrees not to assert any 178 | such rights held by the Licensor to the limited extent necessary 179 | to allow You to exercise the Licensed Rights, but not otherwise. 180 | 2. Patent and trademark rights are not licensed under this Public 181 | License. 182 | 3. To the extent possible, the Licensor waives any right to collect 183 | royalties from You for the exercise of the Licensed Rights, 184 | whether directly or through a collecting society under any 185 | voluntary or waivable statutory or compulsory licensing scheme. 186 | In all other cases the Licensor expressly reserves any right to 187 | collect such royalties, including when the Licensed Material is 188 | used other than for NonCommercial purposes. 189 | 190 | **Section 3 – License Conditions.** 191 | 192 | Your exercise of the Licensed Rights is expressly made subject to the 193 | following conditions. 194 | 195 | 1. **Attribution**. 196 | 197 | 1. If You Share the Licensed Material, You must: 198 | 199 | 1. retain the following if it is supplied by the Licensor with 200 | the Licensed Material: 201 | 1. identification of the creator(s) of the Licensed 202 | Material and any others designated to receive 203 | attribution, in any reasonable manner requested by the 204 | Licensor (including by pseudonym if designated); 205 | 2. a copyright notice; 206 | 3. a notice that refers to this Public License; 207 | 4. a notice that refers to the disclaimer of warranties; 208 | 5. a URI or hyperlink to the Licensed Material to the 209 | extent reasonably practicable; 210 | 211 | 2. indicate if You modified the Licensed Material and retain an 212 | indication of any previous modifications; and 213 | 3. indicate the Licensed Material is licensed under this Public 214 | License, and include the text of, or the URI or hyperlink 215 | to, this Public License. 216 | 217 | For the avoidance of doubt, You do not have permission under 218 | this Public License to Share Adapted Material. 219 | 220 | 2. You may satisfy the conditions in Section [3(a)(1)](#s3a1) in 221 | any reasonable manner based on the medium, means, and context in 222 | which You Share the Licensed Material. For example, it may be 223 | reasonable to satisfy the conditions by providing a URI or 224 | hyperlink to a resource that includes the required information. 225 | 3. If requested by the Licensor, You must remove any of the 226 | information required by Section [3(a)(1)(A)](#s3a1A) to the 227 | extent reasonably practicable. 228 | 229 | **Section 4 – Sui Generis Database Rights.** 230 | 231 | Where the Licensed Rights include Sui Generis Database Rights that apply 232 | to Your use of the Licensed Material: 233 | 234 | 1. for the avoidance of doubt, Section [2(a)(1)](#s2a1) grants You the 235 | right to extract, reuse, reproduce, and Share all or a substantial 236 | portion of the contents of the database for NonCommercial purposes 237 | only and provided You do not Share Adapted Material; 238 | 2. if You include all or a substantial portion of the database contents 239 | in a database in which You have Sui Generis Database Rights, then 240 | the database in which You have Sui Generis Database Rights (but not 241 | its individual contents) is Adapted Material; and 242 | 3. You must comply with the conditions in Section [3(a)](#s3a) if You 243 | Share all or a substantial portion of the contents of the database. 244 | 245 | For the avoidance of doubt, this Section [4](#s4) supplements and does 246 | not replace Your obligations under this Public License where the 247 | Licensed Rights include other Copyright and Similar Rights. 248 | 249 | **Section 5 – Disclaimer of Warranties and Limitation of Liability.** 250 | 251 | 1. **Unless otherwise separately undertaken by the Licensor, to the 252 | extent possible, the Licensor offers the Licensed Material as-is and 253 | as-available, and makes no representations or warranties of any kind 254 | concerning the Licensed Material, whether express, implied, 255 | statutory, or other. This includes, without limitation, warranties 256 | of title, merchantability, fitness for a particular purpose, 257 | non-infringement, absence of latent or other defects, accuracy, or 258 | the presence or absence of errors, whether or not known or 259 | discoverable. Where disclaimers of warranties are not allowed in 260 | full or in part, this disclaimer may not apply to You.** 261 | 2. **To the extent possible, in no event will the Licensor be liable to 262 | You on any legal theory (including, without limitation, negligence) 263 | or otherwise for any direct, special, indirect, incidental, 264 | consequential, punitive, exemplary, or other losses, costs, 265 | expenses, or damages arising out of this Public License or use of 266 | the Licensed Material, even if the Licensor has been advised of the 267 | possibility of such losses, costs, expenses, or damages. Where a 268 | limitation of liability is not allowed in full or in part, this 269 | limitation may not apply to You.** 270 | 271 | 3. The disclaimer of warranties and limitation of liability provided 272 | above shall be interpreted in a manner that, to the extent possible, 273 | most closely approximates an absolute disclaimer and waiver of all 274 | liability. 275 | 276 | **Section 6 – Term and Termination.** 277 | 278 | 1. This Public License applies for the term of the Copyright and 279 | Similar Rights licensed here. However, if You fail to comply with 280 | this Public License, then Your rights under this Public License 281 | terminate automatically. 282 | 2. Where Your right to use the Licensed Material has terminated under 283 | Section [6(a)](#s6a), it reinstates: 284 | 285 | 1. automatically as of the date the violation is cured, provided it 286 | is cured within 30 days of Your discovery of the violation; or 287 | 2. upon express reinstatement by the Licensor. 288 | 289 | For the avoidance of doubt, this Section [6(b)](#s6b) does not 290 | affect any right the Licensor may have to seek remedies for Your 291 | violations of this Public License. 292 | 293 | 3. For the avoidance of doubt, the Licensor may also offer the Licensed 294 | Material under separate terms or conditions or stop distributing the 295 | Licensed Material at any time; however, doing so will not terminate 296 | this Public License. 297 | 4. Sections [1](#s1), [5](#s5), [6](#s6), [7](#s7), and [8](#s8) 298 | survive termination of this Public License. 299 | 300 | **Section 7 – Other Terms and Conditions.** 301 | 302 | 1. The Licensor shall not be bound by any additional or different terms 303 | or conditions communicated by You unless expressly agreed. 304 | 2. Any arrangements, understandings, or agreements regarding the 305 | Licensed Material not stated herein are separate from and 306 | independent of the terms and conditions of this Public License. 307 | 308 | **Section 8 – Interpretation.** 309 | 310 | 1. For the avoidance of doubt, this Public License does not, and shall 311 | not be interpreted to, reduce, limit, restrict, or impose conditions 312 | on any use of the Licensed Material that could lawfully be made 313 | without permission under this Public License. 314 | 2. To the extent possible, if any provision of this Public License is 315 | deemed unenforceable, it shall be automatically reformed to the 316 | minimum extent necessary to make it enforceable. If the provision 317 | cannot be reformed, it shall be severed from this Public License 318 | without affecting the enforceability of the remaining terms and 319 | conditions. 320 | 3. No term or condition of this Public License will be waived and no 321 | failure to comply consented to unless expressly agreed to by the 322 | Licensor. 323 | 4. Nothing in this Public License constitutes or may be interpreted as 324 | a limitation upon, or waiver of, any privileges and immunities that 325 | apply to the Licensor or You, including from the legal processes of 326 | any jurisdiction or authority. 327 | 328 | Creative Commons is not a party to its public licenses. Notwithstanding, 329 | Creative Commons may elect to apply one of its public licenses to 330 | material it publishes and in those instances will be considered the 331 | “Licensor.” The text of the Creative Commons public licenses is 332 | dedicated to the public domain under the [CC0 Public Domain 333 | Dedication](//creativecommons.org/publicdomain/zero/1.0/legalcode). 334 | Except for the limited purpose of indicating that material is shared 335 | under a Creative Commons public license or as otherwise permitted by the 336 | Creative Commons policies published at 337 | [creativecommons.org/policies](//creativecommons.org/policies), Creative 338 | Commons does not authorize the use of the trademark “Creative Commons” 339 | or any other trademark or logo of Creative Commons without its prior 340 | written consent including, without limitation, in connection with any 341 | unauthorized modifications to any of its public licenses or any other 342 | arrangements, understandings, or agreements concerning use of licensed 343 | material. For the avoidance of doubt, this paragraph does not form part 344 | of the public licenses.\ 345 | \ 346 | Creative Commons may be contacted at 347 | [creativecommons.org](//creativecommons.org/). 348 | 349 | Additional languages available: 350 | [العربية](/licenses/by-nc-nd/4.0/legalcode.ar), 351 | [čeština](/licenses/by-nc-nd/4.0/legalcode.cs), 352 | [Deutsch](/licenses/by-nc-nd/4.0/legalcode.de), 353 | [Ελληνικά](/licenses/by-nc-nd/4.0/legalcode.el), 354 | [Español](/licenses/by-nc-nd/4.0/legalcode.es), 355 | [euskara](/licenses/by-nc-nd/4.0/legalcode.eu), 356 | [suomeksi](/licenses/by-nc-nd/4.0/legalcode.fi), 357 | [français](/licenses/by-nc-nd/4.0/legalcode.fr), 358 | [hrvatski](/licenses/by-nc-nd/4.0/legalcode.hr), [Bahasa 359 | Indonesia](/licenses/by-nc-nd/4.0/legalcode.id), 360 | [italiano](/licenses/by-nc-nd/4.0/legalcode.it), 361 | [日本語](/licenses/by-nc-nd/4.0/legalcode.ja), 362 | [한국어](/licenses/by-nc-nd/4.0/legalcode.ko), 363 | [Lietuvių](/licenses/by-nc-nd/4.0/legalcode.lt), 364 | [latviski](/licenses/by-nc-nd/4.0/legalcode.lv), [te reo 365 | Māori](/licenses/by-nc-nd/4.0/legalcode.mi), 366 | [Nederlands](/licenses/by-nc-nd/4.0/legalcode.nl), 367 | [norsk](/licenses/by-nc-nd/4.0/legalcode.no), 368 | [polski](/licenses/by-nc-nd/4.0/legalcode.pl), 369 | [português](/licenses/by-nc-nd/4.0/legalcode.pt), 370 | [русский](/licenses/by-nc-nd/4.0/legalcode.ru), 371 | [Slovenščina](/licenses/by-nc-nd/4.0/legalcode.sl), 372 | [svenska](/licenses/by-nc-nd/4.0/legalcode.sv), 373 | [Türkçe](/licenses/by-nc-nd/4.0/legalcode.tr), 374 | [українська](/licenses/by-nc-nd/4.0/legalcode.uk), 375 | [中文](/licenses/by-nc-nd/4.0/legalcode.zh-Hans), 376 | [華語](/licenses/by-nc-nd/4.0/legalcode.zh-Hant). Please read the 377 | [FAQ](/FAQ#officialtranslations) for more information about official 378 | translations. 379 | 380 | [« Back to Commons Deed](./) 381 | 382 | [![cc.logo.white](https://creativecommons.org/wp-content/uploads/2016/06/cc.logo_.white_.png)](https://creativecommons.org/) 383 | 384 | - [Contact](https://creativecommons.org/about/contact/) 385 | - [Privacy](https://creativecommons.org/privacy/) 386 | - [Policies](https://creativecommons.org/policies/) 387 | - [Terms](https://creativecommons.org/terms/) 388 | 389 | ###### [We'd love to hear from you!](https://creativecommons.org/about/contact) 390 | 391 | Creative Commons\ 392 | PO Box 1866, Mountain View, CA 94042 393 | 394 | - [info@creativecommons.org](mailto:info@creativecommons.org) 395 | - [Frequently Asked Questions](https://creativecommons.org/faq) 396 | 397 | [** 398 | **](https://creativecommons.org/licenses/by/4.0/ "Creative Commons Attribution 4.0 International license") 399 | 400 | Except where otherwise 401 | [noted](https://creativecommons.org/policies#license), content on this 402 | site is licensed under a [Creative Commons Attribution 4.0 International 403 | license](https://creativecommons.org/licenses/by/4.0/). 404 | [Icons](https://creativecommons.org/website-icons) by The Noun Project. 405 | --------------------------------------------------------------------------------