├── .gitignore ├── README.md ├── package-lock.json ├── package.json └── src ├── array-advanced ├── pyramid-builder │ └── pyramid-builder.js └── tennis-score │ └── tennis-score.js ├── array-functions ├── censorship │ └── censorship.js ├── only-odds │ └── only-odds.js ├── pascal-case │ └── pascal-case.js └── uniq │ └── uniq.js ├── array-multidimensional ├── minesweeper │ └── minesweeper.js └── tictactoe │ └── tictactoe.js ├── array ├── found-min │ ├── found-min.js │ └── found-min.test.js ├── inverse-values │ ├── inverse-values.js │ └── inverse-values.test.js ├── soccer │ └── soccer.js ├── social-like │ ├── social-like.js │ └── social-like.test.js └── sum-of-odds │ ├── sum-of-odds.js │ └── sum-of-odds.test.js ├── binary-tree ├── binarytree-max │ └── binarytree-max.js ├── binarytree-search │ └── binarytree-search.js └── binarytree-sum │ └── binarytree-sum.js ├── collection ├── morse-code │ └── morse-code.js └── roman-numerals │ └── roman-numerals.js ├── database ├── database-modeling │ └── database-modeling.md └── sql-queries │ ├── restaurant-uml.png │ ├── restaurant.sql │ └── sql-queries.md ├── fundamental ├── fizz-buzz │ └── fizz-buzz.js ├── hello-you │ └── hello-you.js ├── math-min │ └── math-min.js ├── math-pow │ └── math-pow.js └── sum-of-multiples │ └── sum-of-multiples.js ├── number-conversion ├── binary-to-decimal │ └── binary-to-decimal.js ├── chmod │ └── chmod.js ├── decimal-to-binary │ └── decimal-to-binary.js ├── hex-to-decimal │ └── hex-to-decimal.js └── hex-to-rgb │ └── hex-to-rgb.js ├── object ├── person │ └── person.js └── shape │ └── shape.js ├── recursion ├── recursive-exponentiation │ └── recursive-exponentiation.js ├── recursive-factorial │ └── recursive-factorial.js ├── recursive-fibonacci │ └── recursive-fibonacci.js └── recursive-multiply │ └── recursive-multiply.js ├── string-advanced ├── caesar-cipher │ └── caesar-cipher.js └── runlength-encoding │ └── runlength-encoding.js └── string ├── abbreviate-names ├── abbreviate-names.js └── abbreviate-names.test.js ├── count-letters ├── count-letters.js └── count-letters.test.js ├── duration ├── duration.js └── duration.test.js ├── palindrome ├── palindrome.js └── palindrome.test.js └── string-compare ├── string-compare.js └── string-compare.test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .history 3 | .vscode -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JS Katas 2 | 3 | ## Katas 4 | 5 | ### Fundamental 6 | 7 | - [hello-you](./src/fundamental/hello-you/hello-you.js) 8 | - [fizz-buzz](./src/fundamental/fizz-buzz/fizz-buzz.js) 9 | - [sum-of-multiples](./src/fundamental/sum-of-multiples/sum-of-multiples.js) 10 | - [math-min](./src/fundamental/math-min/math-min.js) 11 | - [math-pow](./src/fundamental/math-pow/math-pow.js) 12 | 13 | ### Array 14 | 15 | - [social-like](./src/array/social-like/social-like.js) 16 | - [found-min](./src/array/found-min/found-min.js) 17 | - [sum-of-odds](./src/array/sum-of-odds/sum-of-odds.js) 18 | - [inverse-values](./src/array/inverse-values/inverse-values.js) 19 | - [soccer](./src/array/soccer/soccer.js) 20 | 21 | ### String 22 | 23 | - [count-letters](./src/string/count-letters/count-letters.js) 24 | - [palindrome](./src/string/palindrome/palindrome.js) 25 | - [duration](./src/string/duration/duration.js) 26 | - [abbreviate-names](./src/string/abbreviate-names/abbreviate-names.js) 27 | - [string-compare](./src/string/string-compare/string-compare.js) 28 | 29 | ### Array functions 30 | 31 | - [only-odds](./src/array-functions/only-odds/only-odds.js) 32 | - [pascal-case](./src/array-functions/pascal-case/pascal-case.js) 33 | - [censorship](./src/array-functions/censorship/censorship.js) 34 | - [uniq](./src/array-functions/uniq/uniq.js) 35 | 36 | ### Object 37 | 38 | - [person](./src/object/person/person.js) 39 | - [shape](./src/object/shape/shape.js) 40 | 41 | ### Database 42 | 43 | - [database-modeling](./src/database/database-modeling/database-modeling.md) 44 | - [sql-queries](./src/database/sql-queries/sql-queries.md) 45 | 46 | ### Array Advanced 47 | 48 | - [tennis-score](./src/array-advanced/tennis-score/tennis-score.js) 49 | - [pyramid-builder](./src/array-advanced/pyramid-builder/pyramid-builder.js) 50 | 51 | ### String Advanced 52 | 53 | - [runlength-encoding](./src/string-advanced/runlength-encoding/runlength-encoding.js) 54 | - [caesar-cipher](./src/string-advanced/caesar-cipher/caesar-cipher.js) 55 | 56 | ### Multidimensional Array 57 | 58 | - [tictactoe](./src/array-multidimensional/tictactoe/tictactoe.js) 59 | - [minesweeper](./src/array-multidimensional/minesweeper/minesweeper.js) 60 | 61 | ### Collection 62 | 63 | - [morse-code](./src/collection/morse-code/morse-code.js) 64 | - [roman-numerals](./src/collection/roman-numerals/roman-numerals.js) 65 | 66 | ### Number conversion 67 | 68 | - [binary-to-decimal](./src/number-conversion/binary-to-decimal/binary-to-decimal.js) 69 | - [decimal-to-binary](./src/number-conversion/decimal-to-binary/decimal-to-binary.js) 70 | - [chmod](./src/number-conversion/chmod/chmod.js) 71 | - [hex-to-decimal](./src/number-conversion/hex-to-decimal/hex-to-decimal.js) 72 | - [hex-to-rgb](./src/number-conversion/hex-to-rgb/hex-to-rgb.js) 73 | 74 | ### Recursion 75 | 76 | - [recursive-factorial](./src/recursion/recursive-factorial/recursive-factorial.js) 77 | - [recursive-fibonacci](./src/recursion/recursive-fibonacci/recursive-fibonacci.js) 78 | - [recursive-exponentiation](./src/recursion/recursive-exponentiation/recursive-exponentiation.js) 79 | - [recursive-multiply](./src/recursion/recursive-multiply/recursive-multiply.js) 80 | 81 | ### Binary Tree 82 | 83 | - [binarytree-max](./src/binary-tree/binarytree-max/binarytree-max.js) 84 | - [binarytree-sum](./src/binary-tree/binarytree-sum/binarytree-sum.js) 85 | - [binarytree-search](./src/binary-tree/binarytree-search/binarytree-search.js) 86 | 87 | ## Setup 88 | 89 | ### 1. Get this repo 90 | 91 | First, [**fork**](https://github.com/WildCodeSchool/js-katas/fork?fragment=1) this repository: you'll then have a copy of this repo under your GitHub account. 92 | 93 | Then go to wherever you store your development work, and run these commands to clone the forked repo (replace `GITHUB_LOGIN` with your login): 94 | 95 | ```sh 96 | # download your code locally 97 | git clone https://github.com/GITHUB_LOGIN/js-katas.git 98 | 99 | # change working directory to the newly cloned repository 100 | cd js-katas 101 | ``` 102 | 103 | ### 2. Configure this repo 104 | 105 | **Prerequisites**: you must have installed Node 106 | 107 | Install the needed libraries: 108 | 109 | ```sh 110 | npm install 111 | ``` 112 | 113 | ## Testing 114 | 115 | ### 1. Fundamental katas 116 | 117 | Fundamental katas use the Node Assert testing library: https://nodejs.org/api/assert.html 118 | 119 | ```sh 120 | node src/fundamental/kata-name/kata-name.js 121 | ``` 122 | 123 | ### 2. Other katas 124 | 125 | The other katas use the Jest testing framework: https://jestjs.io/docs/getting-started 126 | 127 | ```sh 128 | npm test -- kata-name 129 | ``` 130 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "js-katas", 3 | "scripts": { 4 | "test": "jest" 5 | }, 6 | "devDependencies": { 7 | "jest": "^27.5.1" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/array-advanced/pyramid-builder/pyramid-builder.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a function `build` which returns a pyramid of `n` floors, from top to bottom, stored in a string array. 3 | 4 | Example : 5 | 6 | n = 5 : 7 | [ 8 | " * ", 9 | " *** ", 10 | " ***** ", 11 | " ******* ", 12 | "*********" 13 | ] 14 | 15 | If `n` is zero or negative, throw a RangeError. 16 | If `n` is null or not a number, throw a TypeError. 17 | 18 | */ 19 | 20 | // TODO add your code here 21 | 22 | // Begin of tests 23 | const assert = require("assert"); 24 | 25 | assert.strictEqual(typeof build, "function"); 26 | assert.strictEqual(build.length, 1); 27 | assert.deepStrictEqual(build(1), ["*"]); 28 | assert.deepStrictEqual(build(2), [" * ", "***"]); 29 | assert.deepStrictEqual(build(5), [ 30 | " * ", 31 | " *** ", 32 | " ***** ", 33 | " ******* ", 34 | "*********", 35 | ]); 36 | assert.throws(() => { 37 | build(0); 38 | }, RangeError); 39 | assert.throws(() => { 40 | build(-1); 41 | }, RangeError); 42 | assert.throws(() => { 43 | build(null); 44 | }, TypeError); 45 | assert.throws(() => { 46 | build("a"); 47 | }, TypeError); 48 | // End of tests 49 | -------------------------------------------------------------------------------- /src/array-advanced/tennis-score/tennis-score.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a function `getScore` which returns the string of the current scores of a tennis game, from a number array where each value represents the player that scored. 3 | 4 | * [1, 1, 2, 2, 1] : serving player (1) scored twice, then the receiving player (2) scored twice, and finally the serving player (1) scored once. 5 | The expected result is "40-30". 6 | 7 | Game rules : 8 | 9 | The score on the left represents the serving player (1), the score on the right represents the receiving player (2). 10 | 11 | Scores from zero to three points are described as "love", "15", "30", and "40", respectively. 12 | 13 | If at least three points have been scored by each player, the score is not called out as "40–40", but rather as "deuce". 14 | 15 | If at least three points have been scored by each side and a player has one more point than his opponent, the score of the game can be called "ad in" when the serving player (1) is ahead, and "ad out" when the receiving player (2) is ahead. 16 | 17 | Example: 18 | * points : [1, 1, 1], result : "40-love" 19 | * points : [2, 1, 2, 2], result : "15-40" 20 | * points : [1, 2, 1, 2, 1, 2], result : "deuce" 21 | * points : [1, 1, 1, 2, 2, 2, 1], result : "ad in" 22 | 23 | If the argument is null or not an array, throw a TypeError. 24 | If a value of the argument is null or not a number, throw a TypeError. 25 | If a value of the argument is not 1 or 2, throw a RangeError. 26 | 27 | Add you own tests. 28 | 29 | */ 30 | 31 | // TODO add your code here 32 | 33 | // Begin of tests 34 | const assert = require("assert"); 35 | 36 | assert.strictEqual(typeof getScore, "function"); 37 | assert.strictEqual(getScore.length, 1); 38 | // TODO add your tests: 39 | 40 | // End of tests 41 | -------------------------------------------------------------------------------- /src/array-functions/censorship/censorship.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a function `censor` which takes an array of sentences and a forbidden word as argument, then returns the array with the word censored. 3 | 4 | A censored word is replaced with asterisks, example: "tacos" -> "*****". 5 | 6 | Only a full word should be censored. 7 | 8 | sentences: [ 9 | "I love the smell of tacos in the morning.", 10 | "Where is my umbrella?", 11 | "The test is not a diagnosis of the disease psittacosis.", 12 | "Eat tacos every day." 13 | ] 14 | forbidden word: "tacos" 15 | 16 | result: [ 17 | "I love the smell of ***** in the morning.", 18 | "Where is my umbrella?", 19 | "The test is not a diagnosis of the disease psittacosis.", 20 | "Eat ***** every day." 21 | ] 22 | 23 | You can't use a loop! 24 | 25 | Don't mutate the parameter. 26 | 27 | */ 28 | 29 | // TODO add your code here 30 | 31 | // Begin of tests 32 | const assert = require("assert"); 33 | 34 | assert.strictEqual(typeof censor, "function"); 35 | assert.strictEqual(censor.length, 2); 36 | assert.strictEqual( 37 | censor.toString().includes("for "), 38 | false, 39 | "don't use a loop" 40 | ); 41 | assert.strictEqual( 42 | censor.toString().includes("while "), 43 | false, 44 | "don't use a loop" 45 | ); 46 | assert.deepStrictEqual(censor([], "test"), []); 47 | assert.deepStrictEqual(censor(["schnibble"], "schnibble"), ["*********"]); 48 | assert.deepStrictEqual( 49 | censor( 50 | [ 51 | "I love the smell of tacos in the morning.", 52 | "Where is my umbrella?", 53 | "The test is not a diagnosis of the disease psittacosis.", 54 | "Eat tacos every day.", 55 | ], 56 | "tacos" 57 | ), 58 | [ 59 | "I love the smell of ***** in the morning.", 60 | "Where is my umbrella?", 61 | "The test is not a diagnosis of the disease psittacosis.", 62 | "Eat ***** every day.", 63 | ] 64 | ); 65 | let test = ["this test is awesome"]; 66 | censor(test); 67 | assert.deepStrictEqual( 68 | test, 69 | ["this test is awesome"], 70 | "don't mutate the parameter" 71 | ); 72 | 73 | // End of tests 74 | -------------------------------------------------------------------------------- /src/array-functions/only-odds/only-odds.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a function `odd` which only keep odd values from an array passed as an argument. 3 | 4 | You can't use a loop! 5 | 6 | Don't mutate the parameter. 7 | 8 | */ 9 | 10 | // TODO add your code here 11 | 12 | // Begin of tests 13 | const assert = require("assert"); 14 | 15 | assert.strictEqual(typeof odd, "function"); 16 | assert.strictEqual(odd.length, 1); 17 | assert.strictEqual(odd.toString().includes("for "), false, "don't use a loop"); 18 | assert.strictEqual( 19 | odd.toString().includes("while "), 20 | false, 21 | "don't use a loop" 22 | ); 23 | assert.deepStrictEqual(odd([1, 2, 3, 4]), [1, 3]); 24 | assert.deepStrictEqual(odd([10, 20]), []); 25 | assert.deepStrictEqual(odd([]), []); 26 | let nums = [6, 7]; 27 | odd(nums); 28 | assert.deepStrictEqual(nums, [6, 7], "don't mutate the parameter"); 29 | 30 | // End of tests 31 | -------------------------------------------------------------------------------- /src/array-functions/pascal-case/pascal-case.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a function `pascalCase` which convert a sentence into upper case Camel Case, also known as Pascal Case. 3 | 4 | Example: 5 | * "this is sparta" > "ThisIsSparta" 6 | * "sO rAdicAL DuDe" > "SoRadicalDude" 7 | 8 | You can't use a loop! 9 | 10 | Don't mutate the parameter. 11 | 12 | */ 13 | 14 | // TODO add your code here 15 | 16 | // Begin of tests 17 | const assert = require("assert"); 18 | 19 | assert.strictEqual(typeof pascalCase, "function"); 20 | assert.strictEqual(pascalCase.length, 1); 21 | assert.strictEqual( 22 | pascalCase.toString().includes("for "), 23 | false, 24 | "don't use a loop" 25 | ); 26 | assert.strictEqual( 27 | pascalCase.toString().includes("while "), 28 | false, 29 | "don't use a loop" 30 | ); 31 | assert.strictEqual(pascalCase("this is sparta"), "ThisIsSparta"); 32 | assert.strictEqual(pascalCase("sO rAdicAL DuDe"), "SoRadicalDude"); 33 | let test = "no mutation"; 34 | pascalCase(test); 35 | assert.strictEqual(test, "no mutation", "don't mutate the parameter"); 36 | 37 | // End of tests 38 | -------------------------------------------------------------------------------- /src/array-functions/uniq/uniq.js: -------------------------------------------------------------------------------- 1 | /* 2 | Implement a function `uniq` which takes as input a sequence and returns a sequence in which all duplicate elements following each other have been reduced to one instance. 3 | 4 | Example: 5 | * ['a','a','b','b','c','a','b','c'] --> ['a','b','c','a','b','c'] 6 | 7 | Don't mutate the parameter. 8 | 9 | Bonus : do not use a loop 10 | 11 | */ 12 | 13 | // TODO add your code here 14 | 15 | // Begin of tests 16 | const assert = require("assert"); 17 | 18 | assert.strictEqual(typeof uniq, "function"); 19 | assert.strictEqual(uniq.length, 1); 20 | assert.deepStrictEqual(uniq(["a", "a", "b", "b", "c", "a", "b", "c", "c"]), [ 21 | "a", 22 | "b", 23 | "c", 24 | "a", 25 | "b", 26 | "c", 27 | ]); 28 | assert.deepStrictEqual(uniq(["a", "a", "a", "b", "b", "b", "c", "c", "c"]), [ 29 | "a", 30 | "b", 31 | "c", 32 | ]); 33 | assert.deepStrictEqual(uniq([]), []); 34 | assert.deepStrictEqual(uniq(["foo"]), ["foo"]); 35 | assert.deepStrictEqual(uniq(["bar", "bar", "bar", "bar", "bar"]), ["bar"]); 36 | assert.deepStrictEqual(uniq([undefined]), [undefined]); 37 | assert.deepStrictEqual(uniq([undefined, "a", "a"]), [undefined, "a"]); 38 | assert.deepStrictEqual(uniq([""]), [""]); 39 | let test = ["a", "a", "b"]; 40 | uniq(test); 41 | assert.deepStrictEqual(test, ["a", "a", "b"], "don't mutate the parameter"); 42 | 43 | // End of tests 44 | -------------------------------------------------------------------------------- /src/array-multidimensional/minesweeper/minesweeper.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a function `sweep` which takes a grid and two numbers as parameters : 3 | * grid : a minesweeper matrix where 0 are empty cells and 1 are bombs. The width and height of the grid can vary. 4 | * row : the vertical coordinate of the cell to sweep 5 | * column : the horizontal coordinate of the cell to sweep 6 | 7 | The function will check the cell using the coordinates and returns : 8 | * "kaboom", if it contains a boom 9 | * the number of adjacent bombs, if it's empty 10 | 11 | The function will throw : 12 | * TypeError if grid is null or not an array 13 | * TypeError if at least one value of the grid is not 0 or 1 14 | * TypeError if row or column are null or not a number 15 | * RangeError if grid has a width or height inferior to one 16 | * RangeError if row or column are out of bounds 17 | 18 | Example : 19 | 20 | grid : 21 | [ 22 | [0, 0, 0, 1], 23 | [0, 1, 0, 0], 24 | [1, 0, 0, 0] 25 | ] 26 | row : 1 27 | column : 2 28 | 29 | result : 2 30 | 31 | */ 32 | 33 | // TODO add your code here 34 | 35 | // Begin of tests 36 | const assert = require("assert"); 37 | 38 | assert.strictEqual(typeof sweep, "function"); 39 | assert.strictEqual(sweep.length, 3); 40 | const grid = [ 41 | [0, 0, 0, 1], 42 | [0, 1, 0, 0], 43 | [1, 0, 0, 0], 44 | ]; 45 | assert.strictEqual(sweep(grid, 1, 1), "kaboom"); 46 | assert.strictEqual(sweep(grid, 0, 3), "kaboom"); 47 | assert.strictEqual(sweep(grid, 2, 0), "kaboom"); 48 | assert.strictEqual(sweep(grid, 0, 0), 1); 49 | assert.strictEqual(sweep(grid, 1, 2), 2); 50 | assert.strictEqual(sweep(grid, 2, 3), 0); 51 | assert.throws(() => { 52 | sweep(null, 1, 1); 53 | }, TypeError); 54 | assert.throws(() => { 55 | sweep("a", 1, 1); 56 | }, TypeError); 57 | assert.throws(() => { 58 | sweep( 59 | [ 60 | [0, 0, "0", 1], 61 | [0, 1, 0, 1], 62 | [1, 0, 0, 0], 63 | ], 64 | 1, 65 | 1 66 | ); 67 | }, TypeError); 68 | assert.throws(() => { 69 | sweep( 70 | [ 71 | [0, 0, 0, 1], 72 | [0, -1, 0, 1], 73 | [1, 0, 0, 0], 74 | ], 75 | 1, 76 | 1 77 | ); 78 | }, TypeError); 79 | assert.throws(() => { 80 | sweep( 81 | [ 82 | [0, 0, 0, 1], 83 | [0, 1, null, 1], 84 | [1, 0, 0, 0], 85 | ], 86 | 0, 87 | 1 88 | ); 89 | }, TypeError); 90 | assert.throws(() => { 91 | sweep(grid, -1, 1); 92 | }, RangeError); 93 | assert.throws(() => { 94 | sweep(grid, 1, 5); 95 | }, RangeError); 96 | 97 | // End of tests 98 | -------------------------------------------------------------------------------- /src/array-multidimensional/tictactoe/tictactoe.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a function `winner` which analyses a 3x3 tic-tac-toe grid. 3 | * "X" represents player X 4 | * "0" represents player 0 5 | * " " (space) is an empty cell 6 | 7 | grid : 8 | [ 9 | ["X", "O", "O"], 10 | ["X", "O", "O"], 11 | ["X", " ", " "], 12 | ] 13 | 14 | The function should returns the winner : 15 | * "X wins" when X wins 16 | * "O wins" when O wins 17 | * "Cat's game" if it's a draw or if nobody wins 18 | * "{player} is a cheater" where {player} is replaced by the player who cheated. 19 | 20 | The function should throw : 21 | * TypeError if the grid is null or not an array. 22 | * RangeError if the grid has not the size expected 23 | * Error with the text "Illegal character" if the grid contains at least one illegal character. 24 | 25 | */ 26 | 27 | // TODO add your code here 28 | 29 | // Begin of tests 30 | const assert = require("assert"); 31 | 32 | assert.strictEqual(typeof winner, "function"); 33 | assert.strictEqual(winner.length, 1); 34 | assert.strictEqual( 35 | winner([ 36 | ["X", "O", "O"], 37 | ["X", "O", "O"], 38 | ["X", " ", " "], 39 | ]), 40 | "X wins" 41 | ); 42 | assert.strictEqual( 43 | winner([ 44 | ["X", "O", "X"], 45 | ["O", "O", "O"], 46 | [" ", " ", "X"], 47 | ]), 48 | "O wins" 49 | ); 50 | assert.strictEqual( 51 | winner([ 52 | ["X", "X", "O"], 53 | ["O", "X", "O"], 54 | ["X", "O", "X"], 55 | ]), 56 | "X wins" 57 | ); 58 | assert.strictEqual( 59 | winner([ 60 | ["O", "X", "X"], 61 | ["O", "X", "O"], 62 | ["X", "O", "X"], 63 | ]), 64 | "X wins" 65 | ); 66 | assert.strictEqual( 67 | winner([ 68 | ["O", "X", "O"], 69 | ["X", "X", "O"], 70 | ["O", "O", "X"], 71 | ]), 72 | "Cat's game" 73 | ); 74 | assert.strictEqual( 75 | winner([ 76 | ["O", "X", " "], 77 | [" ", " ", " "], 78 | [" ", "O", " "], 79 | ]), 80 | "Cat's game" 81 | ); 82 | assert.strictEqual( 83 | winner([ 84 | ["O", "X", "X"], 85 | ["X", "X", "O"], 86 | ["X", "O", "X"], 87 | ]), 88 | "X is a cheater" 89 | ); 90 | assert.throws(() => [winner(null)], TypeError); 91 | assert.throws(() => [winner("OXXOXOXXOX")], TypeError); 92 | assert.throws(() => { 93 | winner([ 94 | ["O", "X", "X"], 95 | ["X", "X", "O"], 96 | ]); 97 | }, RangeError); 98 | assert.throws(() => { 99 | winner([ 100 | ["O", "X", "X"], 101 | ["X", "X"], 102 | ["X", "O", "X"], 103 | ]); 104 | }, RangeError); 105 | assert.throws(() => { 106 | winner([ 107 | ["O", "X", "X"], 108 | ["O", "X", "0"], 109 | ["X", "O", "X"], 110 | ]); 111 | }, /^Error: Illegal character$/); 112 | 113 | // End of tests 114 | -------------------------------------------------------------------------------- /src/array/found-min/found-min.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a function `min` which founds the minimum value of a number array. 3 | 4 | If the array is empty or null, return null. 5 | 6 | Example: 7 | * [1, 2, 3] -> 1 8 | * [3, -2, 1] -> -2 9 | * [] -> null 10 | 11 | You can't use the function Math.min() 12 | 13 | */ 14 | 15 | // TODO add your code here 16 | 17 | module.exports = min; 18 | -------------------------------------------------------------------------------- /src/array/found-min/found-min.test.js: -------------------------------------------------------------------------------- 1 | const min = require("./found-min"); 2 | 3 | test("min function exists", () => { 4 | expect(typeof min).toBe("function"); 5 | }); 6 | 7 | test("min as one parameter", () => { 8 | expect(min.length).toBe(1); 9 | }); 10 | 11 | test("min should not use Math.min()", () => { 12 | expect(min.toString().includes("Math.min")).toBe(false); 13 | }); 14 | 15 | test("min should return null", () => { 16 | expect(min([])).toBe(null); 17 | expect(min(null)).toBe(null); 18 | }); 19 | 20 | test("min array with only one value", () => { 21 | expect(min([0])).toBe(0); 22 | expect(min([1])).toBe(1); 23 | expect(min([-1])).toBe(-1); 24 | }); 25 | 26 | test("min array with mutiple values", () => { 27 | expect(min([0, -1, 1])).toBe(-1); 28 | expect(min([-2, -1, -3])).toBe(-3); 29 | expect(min([2, 1, 3])).toBe(1); 30 | }); 31 | -------------------------------------------------------------------------------- /src/array/inverse-values/inverse-values.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a function `inverse`, which given an array of numbers, return the additive inverse of each : each positive becomes negatives, and the negatives become positives. 3 | 4 | You can assume that all values are numbers. 5 | 6 | If the argument is an empty array or null, return an empty array. 7 | 8 | Example: 9 | * [1, 2, 3, 4, 5] -> [-1, -2, -3, -4, -5] 10 | * [1, -2, 3, -4, 5] -> [-1, 2, -3, 4, -5] 11 | * [] -> [] 12 | 13 | Don't mutate the parameter. 14 | 15 | */ 16 | 17 | // TODO add your code here 18 | 19 | module.exports = inverse; 20 | -------------------------------------------------------------------------------- /src/array/inverse-values/inverse-values.test.js: -------------------------------------------------------------------------------- 1 | const inverse = require("./inverse-values"); 2 | 3 | test("inverse function exists", () => { 4 | expect(typeof inverse).toBe("function"); 5 | }); 6 | 7 | test("inverse as one parameter", () => { 8 | expect(inverse.length).toBe(1); 9 | }); 10 | 11 | test("inverse empty array", () => { 12 | expect(inverse([])).toStrictEqual([]); 13 | }); 14 | 15 | test("inverse null", () => { 16 | expect(inverse(null)).toStrictEqual([]); 17 | }); 18 | 19 | test("inverse one value", () => { 20 | expect(inverse([1])).toStrictEqual([-1]); 21 | expect(inverse([-1])).toStrictEqual([1]); 22 | }); 23 | 24 | test("inverse multiple values", () => { 25 | expect(inverse([1, 2, 3, 4, 5])).toStrictEqual([-1, -2, -3, -4, -5]); 26 | expect(inverse([1, -2, 3, -4, 5])).toStrictEqual([-1, 2, -3, 4, -5]); 27 | }); 28 | 29 | test("inverse doesn't mutate its argument", () => { 30 | let arg = [1]; 31 | inverse(arg); 32 | expect(arg).toStrictEqual([1]); 33 | }); 34 | -------------------------------------------------------------------------------- /src/array/soccer/soccer.js: -------------------------------------------------------------------------------- 1 | /* 2 | A soccer match took place between 2 teams. You are given the list of goals scored in a table of numbers: each number represents a goal of one of the teams: 3 | - 1 for a team 1 goal 4 | - 2 for a team 2 goal 5 | 6 | Create a function `getScore` which returns the string of the current scores and the winning team. 7 | Example: 8 | * points: [1, 1, 1], result: "3-0: team 1 wins the game" 9 | * points: [2, 1, 2, 2], result: "1-3: team 2 wins the game" 10 | * points: [1, 2, 1, 2], result: "2-2: draw" 11 | * points: [], result: "0-0: draw" 12 | 13 | If the argument is null, return "Illegal argument". 14 | 15 | If a value of the argument is not 1 or 2, return "Illegal argument". 16 | */ 17 | // TODO add your code here 18 | 19 | // Begin of tests 20 | const assert = require("assert"); 21 | assert.strictEqual(typeof getScore, "function"); 22 | assert.strictEqual(getScore.length, 1); 23 | assert.deepStrictEqual(getScore(null), "Illegal argument"); 24 | assert.strictEqual(getScore([]), "0-0 : draw"); 25 | assert.strictEqual(getScore([1, 1, 1]), "3-0 : team 1 wins the game"); 26 | assert.strictEqual(getScore([2, 2, 2]), "0-3 : team 2 wins the game"); 27 | assert.strictEqual(getScore([1, 1, 2, 2]), "2-2 : draw"); 28 | assert.strictEqual(getScore([1, 2, 1, 3, 1, 2]), "Illegal argument"); 29 | assert.strictEqual(getScore(["1", "2"]), "Illegal argument"); 30 | // End of tests 31 | -------------------------------------------------------------------------------- /src/array/social-like/social-like.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a function `getLikes` which receives an array of names, and returns: 3 | * [] => "Be the first to like this" 4 | * ["Cartman"] => "Cartman likes this" 5 | * ["Kenny", "Cartman"] => "Kenny and Cartman like this" 6 | * ["Stan", "Kyle", "Kenny", "Cartman"] => "Stan and 3 other people like this" 7 | 8 | */ 9 | 10 | // TODO add your code here 11 | 12 | module.exports = getLikes; 13 | -------------------------------------------------------------------------------- /src/array/social-like/social-like.test.js: -------------------------------------------------------------------------------- 1 | const getLikes = require("./social-like"); 2 | 3 | test("getLikes function exists", () => { 4 | expect(typeof getLikes).toBe("function"); 5 | }); 6 | 7 | test("getLikes as one parameter", () => { 8 | expect(getLikes.length).toBe(1); 9 | }); 10 | 11 | test("getLikes no like", () => { 12 | expect(getLikes([])).toBe("Be the first to like this"); 13 | }); 14 | 15 | test("getLikes one like", () => { 16 | expect(getLikes(["Cartman"])).toBe("Cartman likes this"); 17 | expect(getLikes(["Bart"])).toBe("Bart likes this"); 18 | }); 19 | 20 | test("getLikes two likes", () => { 21 | expect(getLikes(["Kenny", "Cartman"])).toBe("Kenny and Cartman like this"); 22 | expect(getLikes(["Bart", "Lisa"])).toBe("Bart and Lisa like this"); 23 | }); 24 | 25 | test("getLikes more likes", () => { 26 | expect(getLikes(["Stan", "Kyle", "Kenny", "Cartman"])).toBe( 27 | "Stan and 3 other people like this" 28 | ); 29 | expect(getLikes(["Homer", "Marge", "Bart", "Lisa", "Maggie"])).toBe( 30 | "Homer and 4 other people like this" 31 | ); 32 | }); 33 | -------------------------------------------------------------------------------- /src/array/sum-of-odds/sum-of-odds.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a function `sum` which returns the sum of all odd values contained in a number array. 3 | 4 | If the array is empty or null, return zero. 5 | 6 | Example: 7 | * [] -> 0 8 | * [1, 2, 3] -> 4 9 | 10 | */ 11 | 12 | // TODO add your code here 13 | 14 | module.exports = sum; 15 | -------------------------------------------------------------------------------- /src/array/sum-of-odds/sum-of-odds.test.js: -------------------------------------------------------------------------------- 1 | const sum = require("./sum-of-odds"); 2 | 3 | test("sum function exists", () => { 4 | expect(typeof sum).toBe("function"); 5 | }); 6 | 7 | test("sum as one parameter", () => { 8 | expect(sum.length).toBe(1); 9 | }); 10 | 11 | test("sum empty array", () => { 12 | expect(sum([])).toBe(0); 13 | }); 14 | 15 | test("sum null array", () => { 16 | expect(sum(null)).toBe(0); 17 | }); 18 | 19 | test("sum one value", () => { 20 | expect(sum([-1])).toBe(-1); 21 | expect(sum([0])).toBe(0); 22 | expect(sum([1])).toBe(1); 23 | expect(sum([2])).toBe(0); 24 | }); 25 | 26 | test("sum multiple values", () => { 27 | expect(sum([1, 2, 3])).toBe(4); 28 | expect(sum([-3, 3])).toBe(0); 29 | }); 30 | -------------------------------------------------------------------------------- /src/binary-tree/binarytree-max/binarytree-max.js: -------------------------------------------------------------------------------- 1 | /* 2 | In computer science, a binary tree is a tree data structure in which each node has at most two children, which are referred to as the left child and the right child. 3 | 4 | You are given a binary tree. Implement the function `max` which returns the maximal node value in the tree. 5 | 6 | Example: 7 | 8 | 7 9 | / \ 10 | 5 2 11 | \ \ 12 | 6 11 13 | / \ / 14 | 1 9 4 15 | 16 | result: 11 17 | 18 | If the root node is null, return null. 19 | 20 | This function must be recursive: you can't use a loop. 21 | 22 | */ 23 | 24 | class TreeNode { 25 | constructor(value, left, right) { 26 | this.value = value; 27 | this.left = left; 28 | this.right = right; 29 | } 30 | } 31 | 32 | const max = (node) => { 33 | // TODO add your code here 34 | }; 35 | 36 | // Begin of tests 37 | const assert = require("assert"); 38 | 39 | assert.strictEqual(typeof max, "function"); 40 | assert.strictEqual(max.length, 1); 41 | assert.strictEqual(max.toString().includes("for "), false, "don't use a loop"); 42 | assert.strictEqual( 43 | max.toString().includes("while "), 44 | false, 45 | "don't use a loop" 46 | ); 47 | assert.strictEqual( 48 | max.toString().includes("max("), 49 | true, 50 | "max must be recursive" 51 | ); 52 | assert.strictEqual(max(null), null); 53 | assert.strictEqual(max(new TreeNode(42, null, null)), 42); 54 | const tree = new TreeNode( 55 | 7, 56 | new TreeNode( 57 | 5, 58 | null, 59 | new TreeNode(6, new TreeNode(1, null, null), new TreeNode(9, null, null)) 60 | ), 61 | new TreeNode(2, null, new TreeNode(11, new TreeNode(4, null, null), null)) 62 | ); 63 | assert.strictEqual(max(tree), 11); 64 | 65 | // End of tests 66 | -------------------------------------------------------------------------------- /src/binary-tree/binarytree-search/binarytree-search.js: -------------------------------------------------------------------------------- 1 | /* 2 | A binary search tree is a specific binary tree which has the following properties: 3 | * the left subtree of a node contains only nodes with keys lesser than the node’s key 4 | * the right subtree of a node contains only nodes with keys greater than the node’s key 5 | * the left and right subtree each must also be a binary search tree. There must be no duplicate nodes 6 | 7 | Example: 8 | 9 | 8 10 | / \ 11 | 3 10 12 | / \ \ 13 | 1 6 14 14 | / \ / 15 | 4 7 13 16 | 17 | Implement the function `search` which, given a binary search tree and a value : 18 | * return the node where the value is found 19 | * return null if the value does not exists in the tree 20 | 21 | This function must be recursive: you can't use a loop. 22 | 23 | */ 24 | 25 | class TreeNode { 26 | constructor(value, left, right) { 27 | this.value = value; 28 | this.left = left; 29 | this.right = right; 30 | } 31 | } 32 | 33 | const search = (node, value) => { 34 | // TODO add your code here 35 | }; 36 | 37 | // Begin of tests 38 | const assert = require("assert"); 39 | 40 | assert.strictEqual(typeof search, "function"); 41 | assert.strictEqual(search.length, 2); 42 | assert.strictEqual( 43 | search.toString().includes("for "), 44 | false, 45 | "don't use a loop" 46 | ); 47 | assert.strictEqual( 48 | search.toString().includes("while "), 49 | false, 50 | "don't use a loop" 51 | ); 52 | assert.strictEqual( 53 | search.toString().includes("search("), 54 | true, 55 | "search must be recursive" 56 | ); 57 | const tree = new TreeNode( 58 | 8, 59 | new TreeNode( 60 | 3, 61 | new TreeNode(1, null, null), 62 | new TreeNode(6, new TreeNode(4, null, null), new TreeNode(7, null, null)) 63 | ), 64 | new TreeNode(10, null, new TreeNode(14, new TreeNode(13, null, null), null)) 65 | ); 66 | assert.strictEqual(search(null, 3), null); 67 | assert.strictEqual(search(tree, 42), null); 68 | assert.strictEqual(search(tree, 6).value, 6); 69 | assert.strictEqual(search(tree, 13).value, 13); 70 | 71 | // End of tests 72 | -------------------------------------------------------------------------------- /src/binary-tree/binarytree-sum/binarytree-sum.js: -------------------------------------------------------------------------------- 1 | /* 2 | You are given a binary tree. Implement the method `sum` which returns the sumimal sum of a route from root to leaf. 3 | 4 | Example: 5 | 6 | 17 7 | / \ 8 | 3 -10 9 | / / \ 10 | 2 16 1 11 | / 12 | 13 13 | 14 | result: 23, since [17,-10,16] is the route from root to leaf with the sumimal sum. 15 | 16 | If the root node is null, return zero. 17 | 18 | This function must be recursive: you can't use a loop. 19 | 20 | */ 21 | 22 | class TreeNode { 23 | constructor(value, left, right) { 24 | this.value = value; 25 | this.left = left; 26 | this.right = right; 27 | } 28 | } 29 | 30 | const sum = (node) => { 31 | // TODO add your code here 32 | }; 33 | 34 | // Begin of tests 35 | const assert = require("assert"); 36 | 37 | assert.strictEqual(typeof sum, "function"); 38 | assert.strictEqual(sum.length, 1); 39 | assert.strictEqual(sum.toString().includes("for "), false, "don't use a loop"); 40 | assert.strictEqual( 41 | sum.toString().includes("while "), 42 | false, 43 | "don't use a loop" 44 | ); 45 | assert.strictEqual( 46 | sum.toString().includes("sum("), 47 | true, 48 | "sum must be recursive" 49 | ); 50 | assert.strictEqual(sum(null), 0); 51 | assert.strictEqual(sum(new TreeNode(42, null, null)), 42); 52 | assert.strictEqual( 53 | sum( 54 | new TreeNode( 55 | 17, 56 | new TreeNode(3, new TreeNode(2, null, null), null), 57 | new TreeNode( 58 | -10, 59 | new TreeNode(16, null, null), 60 | new TreeNode(1, new TreeNode(13, null, null), null) 61 | ) 62 | ) 63 | ), 64 | 23 65 | ); 66 | assert.strictEqual( 67 | sum( 68 | new TreeNode( 69 | 7, 70 | new TreeNode( 71 | 5, 72 | null, 73 | new TreeNode( 74 | 6, 75 | new TreeNode(1, null, null), 76 | new TreeNode(9, null, null) 77 | ) 78 | ), 79 | new TreeNode(2, null, new TreeNode(11, new TreeNode(4, null, null), null)) 80 | ) 81 | ), 82 | 27 83 | ); 84 | 85 | // End of tests 86 | -------------------------------------------------------------------------------- /src/collection/morse-code/morse-code.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a function `decode` which translates morse code into latin alphabet. 3 | 4 | Morse code is consisting of dots and dashes: 5 | * each word being separated by three spaces 6 | * each letter being separated by one space 7 | 8 | */ 9 | 10 | const morseMap = new Map(); 11 | morseMap.set(".-", "A"); 12 | morseMap.set("-...", "B"); 13 | morseMap.set("-.-.", "C"); 14 | morseMap.set("-..", "D"); 15 | morseMap.set(".", "E"); 16 | morseMap.set("..-.", "F"); 17 | morseMap.set("--.", "G"); 18 | morseMap.set("....", "H"); 19 | morseMap.set("..", "I"); 20 | morseMap.set(".---", "J"); 21 | morseMap.set("-.-", "K"); 22 | morseMap.set(".-..", "L"); 23 | morseMap.set("--", "M"); 24 | morseMap.set("-.", "N"); 25 | morseMap.set("---", "O"); 26 | morseMap.set(".--.", "P"); 27 | morseMap.set("--.-", "Q"); 28 | morseMap.set(".-.", "R"); 29 | morseMap.set("...", "S"); 30 | morseMap.set("-", "T"); 31 | morseMap.set("..-", "U"); 32 | morseMap.set("...-", "V"); 33 | morseMap.set(".--", "W"); 34 | morseMap.set("-..-", "X"); 35 | morseMap.set("-.--", "Y"); 36 | morseMap.set("--..", "Z"); 37 | morseMap.set(".-.-.-", "."); 38 | morseMap.set("..--..", "?"); 39 | morseMap.set("-.-.--", "!"); 40 | 41 | // TODO add your code here 42 | 43 | // Begin of tests 44 | const assert = require("assert"); 45 | 46 | assert.strictEqual(typeof decode, "function"); 47 | assert.strictEqual(decode.length, 1); 48 | assert.strictEqual(decode(".-- .. .-.. -.."), "WILD"); 49 | assert.strictEqual(decode("- .- -.-. --- ..."), "TACOS"); 50 | assert.strictEqual(decode(".-- .. .-.. -.. -.-. --- -.. ."), "WILD CODE"); 51 | 52 | // End of tests 53 | -------------------------------------------------------------------------------- /src/collection/roman-numerals/roman-numerals.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a method `convert` which converts roman numeral to arabic. 3 | 4 | If the argument is null, empty or contains an illegal numeral, throw an Error with the text "Illegal argument". 5 | 6 | Example : 7 | * I -> 1 8 | * III -> 3 9 | * IV -> 4 10 | * V -> 5 11 | * VIII -> 8 12 | * IX -> 9 13 | * X -> 10 14 | * XLIII -> 43 15 | * CXI -> 111 16 | * MDCLXVI -> 1666 17 | 18 | */ 19 | 20 | const romanNumerals = new Map(); 21 | romanNumerals.set("I", 1); 22 | romanNumerals.set("V", 5); 23 | romanNumerals.set("X", 10); 24 | romanNumerals.set("L", 50); 25 | romanNumerals.set("C", 100); 26 | romanNumerals.set("D", 500); 27 | romanNumerals.set("M", 1000); 28 | 29 | // TODO add your code here 30 | 31 | // Begin of tests 32 | const assert = require("assert"); 33 | 34 | assert.strictEqual(typeof convert, "function"); 35 | assert.strictEqual(convert.length, 1); 36 | assert.strictEqual(convert("I"), 1); 37 | assert.strictEqual(convert("III"), 3); 38 | assert.strictEqual(convert("IV"), 4); 39 | assert.strictEqual(convert("XIV"), 14); 40 | assert.strictEqual(convert("XIX"), 19); 41 | assert.strictEqual(convert("XXXVII"), 37); 42 | assert.strictEqual(convert("XLIII"), 43); 43 | assert.strictEqual(convert("CLIX"), 159); 44 | assert.strictEqual(convert("MCCXXXVIII"), 1238); 45 | assert.throws(() => { 46 | convert(""); 47 | }, /^Error: Illegal argument$/); 48 | assert.throws(() => { 49 | convert(null); 50 | }, /^Error: Illegal argument$/); 51 | assert.throws(() => { 52 | convert("tacos"); 53 | }, /^Error: Illegal argument$/); 54 | 55 | // End of tests 56 | -------------------------------------------------------------------------------- /src/database/database-modeling/database-modeling.md: -------------------------------------------------------------------------------- 1 | # Database Modeling 2 | 3 | Each restaurant (specified by a name and a city) sells one or more menus, but a menu is sold in only one restaurant. 4 | 5 | A menu (specified by a title) contains one or more dishes. 6 | 7 | A dish (specified by a name and a price) can be contained by one or more menus. 8 | 9 | 1. Create a Conceptual Data Model. 10 | 2. Create a Logical Data Model. 11 | 3. Create a Physical Data Model. 12 | -------------------------------------------------------------------------------- /src/database/sql-queries/restaurant-uml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WildCodeSchool/js-katas/680c730fb4a4de41cfb72a880005e7d95b1dd0db/src/database/sql-queries/restaurant-uml.png -------------------------------------------------------------------------------- /src/database/sql-queries/restaurant.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE IF NOT EXISTS `kata_sql_restaurant` /*!40100 DEFAULT CHARACTER SET utf8 */; 2 | USE `kata_sql_restaurant`; 3 | -- MySQL dump 10.13 Distrib 5.7.26, for Linux (x86_64) 4 | -- 5 | -- Host: localhost Database: kata_sql_restaurant 6 | -- ------------------------------------------------------ 7 | -- Server version 5.7.26-0ubuntu0.18.04.1 8 | 9 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 10 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 11 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 12 | /*!40101 SET NAMES utf8 */; 13 | /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; 14 | /*!40103 SET TIME_ZONE='+00:00' */; 15 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; 16 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 17 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 18 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; 19 | 20 | -- 21 | -- Table structure for table `dish` 22 | -- 23 | 24 | DROP TABLE IF EXISTS `dish`; 25 | /*!40101 SET @saved_cs_client = @@character_set_client */; 26 | /*!40101 SET character_set_client = utf8 */; 27 | CREATE TABLE `dish` ( 28 | `id` int(11) NOT NULL AUTO_INCREMENT, 29 | `name` varchar(100) NOT NULL, 30 | `price` float NOT NULL, 31 | PRIMARY KEY (`id`) 32 | ) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8; 33 | /*!40101 SET character_set_client = @saved_cs_client */; 34 | 35 | -- 36 | -- Dumping data for table `dish` 37 | -- 38 | 39 | LOCK TABLES `dish` WRITE; 40 | /*!40000 ALTER TABLE `dish` DISABLE KEYS */; 41 | INSERT INTO `dish` VALUES (1,'Tartiflette',12),(2,'Coq au Vin',14),(3,'Pot au feu',13.5),(4,'Quiche lorraine',9),(5,'Crêpe',4.5),(6,'Steak tartare',8),(7,'Cassoulet',16),(8,'Huîtres',22),(9,'Gratin dauphinois',10),(10,'Bœuf bourguignon',15),(11,'Biscôme',5.9),(12,'Brioche',6),(13,'Pain perdu',4),(14,'Panettone',4.5),(15,'Tarte à la rhubarbe',5),(16,'Macarons',3.5),(17,'Flan pâtissier',5),(18,'Forêt noire',8),(19,'Tarte Tatin',6),(20,'Merveilleux',5.5); 42 | /*!40000 ALTER TABLE `dish` ENABLE KEYS */; 43 | UNLOCK TABLES; 44 | 45 | -- 46 | -- Table structure for table `menu` 47 | -- 48 | 49 | DROP TABLE IF EXISTS `menu`; 50 | /*!40101 SET @saved_cs_client = @@character_set_client */; 51 | /*!40101 SET character_set_client = utf8 */; 52 | CREATE TABLE `menu` ( 53 | `id` int(11) NOT NULL AUTO_INCREMENT, 54 | `title` varchar(100) NOT NULL, 55 | `restaurant_id` int(11) NOT NULL, 56 | PRIMARY KEY (`id`), 57 | KEY `menu_restaurant_FK` (`restaurant_id`), 58 | CONSTRAINT `menu_restaurant_FK` FOREIGN KEY (`restaurant_id`) REFERENCES `restaurant` (`id`) 59 | ) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8; 60 | /*!40101 SET character_set_client = @saved_cs_client */; 61 | 62 | -- 63 | -- Dumping data for table `menu` 64 | -- 65 | 66 | LOCK TABLES `menu` WRITE; 67 | /*!40000 ALTER TABLE `menu` DISABLE KEYS */; 68 | INSERT INTO `menu` VALUES (1,'Le menu cher',1),(2,'Le menu très cher',1),(3,'Le menu trop cher',1),(4,'Le menu unique',2),(5,'Pastèque et camembert',3),(6,'Picouli',3),(7,'Menu midi',4),(8,'Menu soir',4),(9,'Brunch de ouf',5),(10,'Les petits plats',6),(11,'Menu enfant',6),(12,'Menu A',7),(13,'Menu B',7),(14,'Menu C',7),(15,'Menu S+',7),(16,'Mangeons bien',8),(17,'Mangeons équilibré',8),(18,'Mangeons peu',8),(19,'Mangeons beaucoup',8),(20,'Faim de table',10); 69 | /*!40000 ALTER TABLE `menu` ENABLE KEYS */; 70 | UNLOCK TABLES; 71 | 72 | -- 73 | -- Table structure for table `menu_dish` 74 | -- 75 | 76 | DROP TABLE IF EXISTS `menu_dish`; 77 | /*!40101 SET @saved_cs_client = @@character_set_client */; 78 | /*!40101 SET character_set_client = utf8 */; 79 | CREATE TABLE `menu_dish` ( 80 | `dish_id` int(11) NOT NULL, 81 | `menu_id` int(11) NOT NULL, 82 | PRIMARY KEY (`dish_id`,`menu_id`), 83 | KEY `menu_dish_menu0_FK` (`menu_id`), 84 | CONSTRAINT `menu_dish_dish_FK` FOREIGN KEY (`dish_id`) REFERENCES `dish` (`id`), 85 | CONSTRAINT `menu_dish_menu0_FK` FOREIGN KEY (`menu_id`) REFERENCES `menu` (`id`) 86 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 87 | /*!40101 SET character_set_client = @saved_cs_client */; 88 | 89 | -- 90 | -- Dumping data for table `menu_dish` 91 | -- 92 | 93 | LOCK TABLES `menu_dish` WRITE; 94 | /*!40000 ALTER TABLE `menu_dish` DISABLE KEYS */; 95 | INSERT INTO `menu_dish` VALUES (1,1),(10,1),(2,2),(2,3),(6,3),(12,3),(7,4),(18,4),(1,5),(4,5),(7,5),(16,5),(3,6),(8,7),(16,7),(19,8),(20,8),(7,9),(9,10),(15,10),(3,12),(7,12),(8,13),(14,13),(7,15),(18,15),(2,16),(3,16),(4,16),(11,16),(12,16),(1,17),(4,18),(15,18),(6,19),(8,19),(8,20),(9,20),(10,20),(11,20); 96 | /*!40000 ALTER TABLE `menu_dish` ENABLE KEYS */; 97 | UNLOCK TABLES; 98 | 99 | -- 100 | -- Table structure for table `restaurant` 101 | -- 102 | 103 | DROP TABLE IF EXISTS `restaurant`; 104 | /*!40101 SET @saved_cs_client = @@character_set_client */; 105 | /*!40101 SET character_set_client = utf8 */; 106 | CREATE TABLE `restaurant` ( 107 | `id` int(11) NOT NULL AUTO_INCREMENT, 108 | `name` varchar(100) NOT NULL, 109 | `city` text NOT NULL, 110 | PRIMARY KEY (`id`) 111 | ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8; 112 | /*!40101 SET character_set_client = @saved_cs_client */; 113 | 114 | -- 115 | -- Dumping data for table `restaurant` 116 | -- 117 | 118 | LOCK TABLES `restaurant` WRITE; 119 | /*!40000 ALTER TABLE `restaurant` DISABLE KEYS */; 120 | INSERT INTO `restaurant` VALUES (1,'Guy Savoy','Paris'),(2,'Alain Ducasse','Paris'),(3,'La Vague d’Or','Saint Tropez'),(4,'L’Ambroisie','Paris'),(5,'L’Auberge du Vieux Puits','Fonjoncouse'),(6,'L’Assiette Champenoise','Tinqueux'),(7,'L’Arpège','Paris'),(8,'Pavillon Ledoyen','Paris'),(9,'Le Pré Catelan','Paris'),(10,'La Maison Troisgros','Ouches'); 121 | /*!40000 ALTER TABLE `restaurant` ENABLE KEYS */; 122 | UNLOCK TABLES; 123 | /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; 124 | 125 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; 126 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; 127 | /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; 128 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 129 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 130 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 131 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; 132 | 133 | -- Dump completed on 2019-06-20 11:25:46 134 | 135 | -------------------------------------------------------------------------------- /src/database/sql-queries/sql-queries.md: -------------------------------------------------------------------------------- 1 | # SQL Queries 2 | 3 | ![Database diagram](./restaurant-uml.png) 4 | 5 | Import the [restaurant.sql](./restaurant.sql) file into MySQL. 6 | 7 | Create the following queries : 8 | 9 | 1. Select all restaurant's name 10 | 11 | 2. Select all menu's title alphabetically 12 | 13 | 3. Select each dish's name and price, in decreasing price order 14 | 15 | 4. Select restaurant's name located in the city of Paris 16 | 17 | 5. Select all menu's title which contains the word "menu" 18 | 19 | 6. Select cities without duplicates 20 | 21 | 7. Select the name of the most expensive dish 22 | 23 | 8. Select all menu's title and the restaurant's name where they are sold 24 | 25 | 9. Select all dish's name (without duplicate) which are contained by at least one menu 26 | 27 | 10. Select all dish's name and price with corresponding menu's title 28 | 29 | 11. Select each dish's name and price, corresponding menu's title and restaurant's name who sells it 30 | 31 | 12. Select all the restaurants' name which don't sell any menu 32 | 33 | 13. Select all dish's name not contained in any menu 34 | 35 | 14. Select each city's name and how many restaurants located in this city 36 | 37 | 15. Select menu's title and dishes' count for each menu 38 | 39 | 16. Select the title of the menu with the most dishes 40 | 41 | 17. Select, for each restaurant, its name and how many menus it sells (some restaurants might not have any menu) 42 | 43 | 18. Select all menu's title and dishes count, where menus have more than two dishes. 44 | 45 | 19. Select all restaurant's name which sells at least one menu where dishes' price combined is 30 or more 46 | 47 | ## Hints : 48 | 49 |
50 | Request 1 51 | 52 | SELECT, FROM 53 | 54 |
55 |
56 | Request 2 57 | 58 | ORDER BY 59 | 60 |
61 |
62 | Request 3 63 | 64 | ORDER BY 65 | 66 |
67 |
68 | Request 4 69 | 70 | WHERE 71 | 72 |
73 |
74 | Request 5 75 | 76 | LIKE 77 | 78 |
79 |
80 | Request 6 81 | 82 | DISTINCT 83 | 84 |
85 |
86 | Request 7 87 | 88 | ORDER BY, LIMIT 89 | 90 |
91 |
92 | Request 8 93 | 94 | INNER JOIN 95 | 96 |
97 |
98 | Request 9 99 | 100 | DISTINCT, INNER JOIN 101 | 102 |
103 |
104 | Request 10 105 | 106 | INNER JOIN (x2) 107 | 108 |
109 |
110 | Request 11 111 | 112 | INNER JOIN (x3) 113 | 114 |
115 |
116 | Request 12 117 | 118 | LEFT JOIN 119 | 120 |
121 |
122 | Request 13 123 | 124 | LEFT JOIN 125 | 126 |
127 |
128 | Request 14 129 | 130 | COUNT, GROUP BY 131 | 132 |
133 |
134 | Request 15 135 | 136 | COUNT, INNER JOIN (x2), GROUP BY 137 | 138 |
139 |
140 | Request 16 141 | 142 | CCOUNT, INNER JOIN (x2), GROUP BY, ORDER BY, LIMIT 143 | 144 |
145 |
146 | Request 17 147 | 148 | COUNT, LEFT JOIN, GROUP BY 149 | 150 |
151 |
152 | Request 18 153 | 154 | COUNT, INNER JOIN, GROUP BY, HAVING 155 | 156 |
157 |
158 | Request 19 159 | 160 | DISTINCT, INNER JOIN (x3), GROUP BY, HAVING 161 | 162 |
163 | -------------------------------------------------------------------------------- /src/fundamental/fizz-buzz/fizz-buzz.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a function `fizzBuzz` which takes a number as parameter, and returns: 3 | * "Fizz", if the argument is a multiple of 3 4 | * "Buzz" if the argument is a multiple of 5 5 | * "FizzBuzz", if the argument is a multiple of 3 and 5 6 | * the argument as a string in any other case 7 | 8 | */ 9 | 10 | // TODO add your code here 11 | 12 | // Begin of tests 13 | const assert = require("assert"); 14 | 15 | assert.strictEqual(typeof fizzBuzz, "function"); 16 | assert.strictEqual(fizzBuzz.length, 1); 17 | assert.strictEqual(fizzBuzz(3), "Fizz"); 18 | assert.strictEqual(fizzBuzz(9), "Fizz"); 19 | assert.strictEqual(fizzBuzz(5), "Buzz"); 20 | assert.strictEqual(fizzBuzz(10), "Buzz"); 21 | assert.strictEqual(fizzBuzz(15), "FizzBuzz"); 22 | assert.strictEqual(fizzBuzz(30), "FizzBuzz"); 23 | assert.strictEqual(fizzBuzz(7), "7"); 24 | assert.strictEqual(fizzBuzz(13), "13"); 25 | // End of tests 26 | 27 | console.log("🎉"); 28 | -------------------------------------------------------------------------------- /src/fundamental/hello-you/hello-you.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a function `sayHello` which takes a string as parameter and returns: "Hello {first name}", where {first name} is replaced with the argument value, example: 3 | * sayHello("Barbara") -> "Hello Barbara" 4 | 5 | If the argument is empty, null or undefined, return "Hello World": 6 | * sayHello(null) -> "Hello World" 7 | 8 | */ 9 | 10 | // TODO add your code here 11 | 12 | // Begin of tests 13 | const assert = require("assert"); 14 | 15 | assert.strictEqual(typeof sayHello, "function"); 16 | assert.strictEqual(sayHello.length, 1); 17 | assert.strictEqual(sayHello("Barbara"), "Hello Barbara"); 18 | assert.strictEqual(sayHello("Jean-Michel"), "Hello Jean-Michel"); 19 | assert.strictEqual(sayHello(""), "Hello World"); 20 | assert.strictEqual(sayHello(null), "Hello World"); 21 | assert.strictEqual(sayHello(), "Hello World"); 22 | // End of tests 23 | 24 | console.log("🎉"); 25 | -------------------------------------------------------------------------------- /src/fundamental/math-min/math-min.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a function `min` which returns the lowest-valued of the two numbers passed into it, 3 | or NaN if any parameter isn't a number. 4 | 5 | * min(0, 0) -> 0 6 | * min(0, 1) -> 0 7 | * min(-1, 0) -> -1 8 | * min("tacos", 0) -> NaN 9 | * min() -> NaN 10 | 11 | You can't use Math.min(), the goal is to recreate this function! 12 | 13 | */ 14 | 15 | // TODO add your code here 16 | 17 | // Begin of tests 18 | const assert = require("assert"); 19 | 20 | assert.strictEqual(typeof min, "function"); 21 | assert.strictEqual(min.length, 2); 22 | assert.strictEqual(min(0, 0), 0); 23 | assert.strictEqual(min(0, 1), 0); 24 | assert.strictEqual(min(-1, 0), -1); 25 | assert.strictEqual(min("tacos", 0), NaN); 26 | assert.strictEqual(min(), NaN); 27 | // End of tests 28 | 29 | console.log("🎉"); 30 | -------------------------------------------------------------------------------- /src/fundamental/math-pow/math-pow.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a function `pow` which given two arguments, base and exponent, returns the base to the exponent power, as in base^exponent. 3 | 4 | The base and exponent will only have positive values (you don't need to check this). 5 | 6 | If an argument is not a number, return NaN. 7 | 8 | * pow(2, 0) -> 1 9 | * pow(2, 1) -> 2 10 | * pow(2, 2) -> 4 11 | * pow(3, 3) -> 27 12 | * pow("tacos", 2) -> NaN 13 | * pow(42) -> NaN 14 | 15 | You can't use Math.pow(), the goal is to recreate this function! 16 | 17 | */ 18 | 19 | // TODO add your code here 20 | 21 | // Begin of tests 22 | const assert = require("assert"); 23 | 24 | assert.strictEqual(typeof pow, "function"); 25 | assert.strictEqual(pow.length, 2); 26 | assert.strictEqual(pow(2, 0), 1); 27 | assert.strictEqual(pow(2, 1), 2); 28 | assert.strictEqual(pow(2, 2), 4); 29 | assert.strictEqual(pow(3, 3), 27); 30 | assert.strictEqual(pow("tacos", 2), NaN); 31 | assert.strictEqual(pow(42), NaN); 32 | // End of tests 33 | 34 | console.log("🎉"); 35 | -------------------------------------------------------------------------------- /src/fundamental/sum-of-multiples/sum-of-multiples.js: -------------------------------------------------------------------------------- 1 | /* 2 | If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23. 3 | 4 | Create a function `sum` which returns the sum of all the multiples of 3 or 5 below the number in argument. 5 | 6 | Note: If the number is a multiple of both 3 and 5, only count it once. 7 | 8 | */ 9 | 10 | // TODO add your code here 11 | 12 | // Begin of tests 13 | const assert = require("assert"); 14 | 15 | assert.strictEqual(typeof sum, "function"); 16 | assert.strictEqual(sum.length, 1); 17 | assert.strictEqual(sum(10), 23); 18 | assert.strictEqual(sum(42), 408); 19 | assert.strictEqual(sum(100), 2318); 20 | 21 | // End of tests 22 | 23 | console.log("🎉"); 24 | -------------------------------------------------------------------------------- /src/number-conversion/binary-to-decimal/binary-to-decimal.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a function `convert` which, given a binary string representation of a number, returns its decimal value. 3 | 4 | Here's the numbers 0 to 9 represented as base 2 (binary): 5 | 6 | "0" 0 7 | "1" 1 8 | "10" 2 9 | "11" 3 10 | "100" 4 11 | "101" 5 12 | "110" 6 13 | "111" 7 14 | "1000" 8 15 | "1001" 9 16 | 17 | You can't use the function parseInt. 18 | 19 | Add you own tests. 20 | 21 | Bonus: 22 | * if the argument isn't a string, throw a TypeError with the message "Illegal argument" 23 | * if the argument is an empty string, or if a digit isn't 1 or 0, throw an Error with the message "Illegal binary string" 24 | 25 | */ 26 | 27 | // TODO add your code here 28 | 29 | // Begin of tests 30 | const assert = require("assert"); 31 | 32 | assert.strictEqual(typeof convert, "function"); 33 | assert.strictEqual(convert.length, 1); 34 | assert.strictEqual( 35 | convert.toString().includes("parseInt"), 36 | false, 37 | "don't use parseInt()" 38 | ); 39 | // TODO add your tests: 40 | 41 | // Bonus: exceptions 42 | /* 43 | assert.throws(() => { 44 | convert(1); 45 | }, /^TypeError: Illegal argument$/); 46 | assert.throws(() => { 47 | convert(""); 48 | }, /^Error: Illegal binary string$/); 49 | assert.throws(() => { 50 | convert("01A1"); 51 | }, /^Error: Illegal binary string$/); 52 | */ 53 | // End of tests 54 | -------------------------------------------------------------------------------- /src/number-conversion/chmod/chmod.js: -------------------------------------------------------------------------------- 1 | /* 2 | Chmod: 3 | 4 | In Unix-like operating systems, chmod is the command which is used to change the access permissions of files and directories. 5 | 6 | * Numerical 7 | 8 | The numerical permissions are composed of three integers, from 0 to 7, corresponding to "user", "group" and "other" rights. 9 | 10 | In order to understand how a permission is assigned to an integer, you need to convert to binary : 11 | 12 | r w x 13 | 0 : 0 0 0 14 | 1 : 0 0 1 15 | 2 : 0 1 0 16 | 3 : 0 1 1 17 | 4 : 1 0 0 18 | 5 : 1 0 1 19 | 6 : 1 1 0 20 | 7 : 1 1 1 21 | 22 | Each binary digit is assigned to a corresponding right : read (r), write (w), execute (x). 23 | 24 | If a digit value is 1, the right is obtained. 25 | 26 | Example: 27 | > entry: 142 28 | > binary: 001 100 010 29 | 30 | * Octal 31 | 32 | The octal mode assign the corresponding right r, w, x if the digit is 1, and a dash - if it's 0. 33 | 34 | Example: 35 | > binary: 001 100 010 36 | > octal: --x r-- -w- 37 | 38 | Kata: 39 | 40 | Create a function `chmod` with converts numerical permissions to octal mode. 41 | 42 | Example: 43 | > numerical : "000", result : "---------" 44 | > numerical : "352", result : "-wxr-x-w-" 45 | > numerical : "777", result : "rwxrwxrwx" 46 | 47 | You can convert decimal to binary using this : Number(decimal).toString(2) 48 | 49 | Add your own tests. 50 | 51 | */ 52 | 53 | // TODO add your code here 54 | 55 | // Begin of tests 56 | const assert = require("assert"); 57 | 58 | assert.strictEqual(typeof chmod, "function"); 59 | assert.strictEqual(chmod.length, 1); 60 | // TODO add your tests: 61 | 62 | // End of tests 63 | -------------------------------------------------------------------------------- /src/number-conversion/decimal-to-binary/decimal-to-binary.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a function `convert` which converts a positive integer to a binary string. 3 | 4 | Example: 5 | * integer: 164, binary: "10100100" 6 | 7 | You can't use the Number class nor the toString method. 8 | 9 | Hint (only if you're stuck) : https://gist.github.com/bastienwcs/bebab3c43e7390b29159aaa936c35883 10 | 11 | Add you own tests. 12 | 13 | */ 14 | 15 | // TODO add your code here 16 | 17 | // Begin of tests 18 | const assert = require("assert"); 19 | 20 | assert.strictEqual(typeof convert, "function"); 21 | assert.strictEqual(convert.length, 1); 22 | assert.strictEqual( 23 | convert.toString().includes("Number("), 24 | false, 25 | "don't use the Number class" 26 | ); 27 | assert.strictEqual( 28 | convert.toString().includes("toString("), 29 | false, 30 | "don't use toString()" 31 | ); 32 | // TODO add your tests: 33 | 34 | // End of tests 35 | -------------------------------------------------------------------------------- /src/number-conversion/hex-to-decimal/hex-to-decimal.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a function `convert` which, given a string representation of an hexadecimal value, returns its decimal value. 3 | 4 | If the argument is null, empty, not a string or contains an illegal character, throw an Error with the message "Illegal hexadecimal string". 5 | 6 | Hexadecimal is a numeral system with a base of 16. It uses sixteen distinct symbols : 0 to 9 to represent values zero to nine, and A to F represent values ten to fifteen. 7 | 8 | E.g: 9 | 10 | 0 : 0 11 | 1 : 1 12 | 9 : 9 13 | A : 10 14 | B : 11 15 | F : 15 16 | 10 : 16 17 | 11 : 17 18 | FF : 255 19 | 4F2C : 20268 20 | 21 | You can't use the function parseInt. 22 | 23 | Hint (only if you're stuck) : https://gist.github.com/bastienwcs/0cb437bff3e991d139770c4af6414e8f 24 | 25 | Add you own tests. 26 | 27 | */ 28 | 29 | // TODO add your code here 30 | 31 | // Begin of tests 32 | const assert = require("assert"); 33 | 34 | assert.strictEqual(typeof convert, "function"); 35 | assert.strictEqual(convert.length, 1); 36 | assert.strictEqual( 37 | convert.toString().includes("parseInt"), 38 | false, 39 | "don't use parseInt()" 40 | ); 41 | // TODO add your tests: 42 | 43 | // End of tests 44 | -------------------------------------------------------------------------------- /src/number-conversion/hex-to-rgb/hex-to-rgb.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a method `convert` that converts a hexadecimal color string into a RGB array. 3 | 4 | A hexadecimal color string is a triplet of hexadecimal values (red, blue, green) that begins with a '#'. E.g: #FFD700 will be the gold color : FF for red, D7 for blue, 00 for green. 5 | 6 | A hexadecimal digit (base 16) goes from 0 to 9 and then from A to F (10 to 15). Each color group contains two digits, and goes from 00 to FF (255). 7 | 8 | A RBG array contains the value of each color group in decimal. 9 | 10 | If you convert "#FFD700" into a RGB array, you'll obtain [255, 215, 0]. 11 | 12 | If the argument is null, empty, not a string, doesn't begins with a '#' or contains an illegal character, throw an Error with the message "Illegal argument". 13 | 14 | You MUST use parseInt this time! 15 | 16 | */ 17 | 18 | // TODO add your code here 19 | 20 | // Begin of tests 21 | const assert = require("assert"); 22 | 23 | assert.strictEqual(typeof convert, "function"); 24 | assert.strictEqual(convert.length, 1); 25 | assert.strictEqual( 26 | convert.toString().includes("parseInt"), 27 | true, 28 | "You must use parseInt()" 29 | ); 30 | assert.deepStrictEqual(convert("#000000"), [0, 0, 0]); 31 | assert.deepStrictEqual(convert("#FFD700"), [255, 215, 0]); 32 | assert.deepStrictEqual(convert("#9ACD32"), [154, 205, 50]); 33 | assert.throws(() => { 34 | convert("000000"); 35 | }, /^Error: Illegal argument$/); 36 | assert.throws(() => { 37 | convert("#00000G"); 38 | }, /^Error: Illegal argument$/); 39 | assert.throws(() => { 40 | convert(null); 41 | }, /^Error: Illegal argument$/); 42 | assert.throws(() => { 43 | convert(""); 44 | }, /^Error: Illegal argument$/); 45 | assert.throws(() => { 46 | convert(121045); 47 | }, /^Error: Illegal argument$/); 48 | 49 | // End of tests 50 | -------------------------------------------------------------------------------- /src/object/person/person.js: -------------------------------------------------------------------------------- 1 | /* 2 | Créez une classe Person qui comporte : 3 | - Un constructeur qui initialise trois propriétés dans cet ordre : name (string), age (nombre) et weeaboo (booléen). 4 | - Une méthode introduce qui renvoie "My name is {name} and I am {age}", où {name} et {age} sont remplacés par leurs propriétés respectives. 5 | - Une méthode greets qui reçoit un nom (name, string) en paramètre et renvoie "Hello {name}" si weeaboo est faux, et "Ohayou {name}-chan" si weeaboo est vrai. 6 | 7 | Ensuite, créer une classe Hero qui hérite de Person : 8 | - Un constructeur qui initialise une nouvelle propriété power (string). 9 | - Lors de l'appel de introduce, en plus de la présentation classique, le héros devra indiquer son pouvoir : "My superpower is {power}". 10 | 11 | Bonus : modifier la classe Person : 12 | - Ajouter une méthode match qui reçoit une personne (Person) en paramètre et renvoie "it's a match" si les propriétés weeaboo actuels et de l'argument sont identiques et "it's not a match" sinon. 13 | 14 | TODO : 15 | - créer la classe Person et son constructeur 16 | - créer la méthode introduce 17 | - créer la méthode greets 18 | - créer des instances de Person 19 | - créer la classe Hero et son constructeur 20 | - redéfinir la méthode introduce 21 | - créer des instances de Hero 22 | - Bonus : créer la méthode match 23 | 24 | */ 25 | 26 | // Votre code ici ! 27 | 28 | // Begin of tests 29 | /* 30 | const assert = require("assert"); 31 | assert.strictEqual(typeof Person, "function", "Person class is undefined"); 32 | if (typeof Person === "function") { 33 | assert.strictEqual(new Person("John Doe", 30, false).name, "John Doe"); 34 | assert.strictEqual(new Person("John Doe", 30, false).age, 30); 35 | assert.strictEqual(new Person("John Doe", 30, false).weeaboo, false); 36 | assert.strictEqual( 37 | typeof new Person().introduce, 38 | "function", 39 | "introduce method is undefined" 40 | ); 41 | if (typeof new Person().introduce === "function") { 42 | assert.strictEqual( 43 | new Person("John Doe", 30, false).introduce(), 44 | "My name is John Doe and I am 30" 45 | ); 46 | } 47 | assert.strictEqual( 48 | typeof new Person().greets, 49 | "function", 50 | "greets method is undefined" 51 | ); 52 | if (typeof new Person().greets === "function") { 53 | assert.strictEqual( 54 | new Person("John Doe", 30, false).greets("Barbara"), 55 | "Hello Barbara" 56 | ); 57 | assert.strictEqual( 58 | new Person("John Doe", 30, true).greets("Uzaki"), 59 | "Ohayou Uzaki-chan" 60 | ); 61 | } 62 | assert.strictEqual( 63 | typeof new Person().match, 64 | "function", 65 | "match method is undefined" 66 | ); 67 | if (typeof new Person().match === "function") { 68 | assert.strictEqual( 69 | new Person("John Doe", 30, false).match( 70 | new Person("Jane Doe", 30, false) 71 | ), 72 | true 73 | ); 74 | assert.strictEqual( 75 | new Person("John Doe", 30, true).match(new Person("Jane Doe", 30, false)), 76 | false 77 | ); 78 | assert.strictEqual( 79 | new Person("John Doe", 30, true).match(new Person("Jane Doe", 30, true)), 80 | true 81 | ); 82 | } 83 | } 84 | 85 | // End of tests 86 | */ 87 | -------------------------------------------------------------------------------- /src/object/shape/shape.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create three classes which inherit the class Shape: 3 | * Rectangle 4 | * Triangle 5 | * Circle 6 | 7 | For each classes: 8 | * add a constructor and initialise the necessary attributes 9 | * implement the area method. 10 | 11 | Create a class Square, which inherits Rectangle: 12 | * add a constructor which has only one argument 13 | * call the constructor of its parent with the super keyword 14 | * don't implement the area method! 15 | 16 | */ 17 | 18 | // Don't touch this! 19 | class Shape { 20 | constructor() {} 21 | 22 | area() { 23 | throw new Error("You have to implement the area method!"); 24 | } 25 | } 26 | 27 | // TODO add your code here 28 | 29 | // Begin of tests 30 | const assert = require("assert"); 31 | assert.strictEqual(typeof Shape, "function", "Shape class is undefined"); 32 | assert.strictEqual( 33 | typeof new Shape().area, 34 | "function", 35 | "Shape area method is undefined" 36 | ); 37 | assert.throws(() => { 38 | new Shape().area(); 39 | }, /^Error: You have to implement the area method!$/); 40 | assert.strictEqual( 41 | typeof Rectangle, 42 | "function", 43 | "Rectangle class is undefined" 44 | ); 45 | if (typeof Rectangle === "function") { 46 | assert.strictEqual( 47 | Rectangle.prototype instanceof Shape, 48 | true, 49 | "Rectangle inherits Shape" 50 | ); 51 | assert.strictEqual( 52 | Rectangle.toString().includes("constructor"), 53 | true, 54 | "Rectangle has a constructor" 55 | ); 56 | assert.strictEqual(new Rectangle(2, 3).area(), 6); 57 | } 58 | assert.strictEqual(typeof Triangle, "function", "Triangle class is undefined"); 59 | if (typeof Triangle === "function") { 60 | assert.strictEqual( 61 | Triangle.prototype instanceof Shape, 62 | true, 63 | "Triangle inherits Shape" 64 | ); 65 | assert.strictEqual( 66 | Triangle.toString().includes("constructor"), 67 | true, 68 | "Triangle has a constructor" 69 | ); 70 | assert.strictEqual(new Triangle(3, 4).area(), 6); 71 | } 72 | assert.strictEqual(typeof Circle, "function", "Circle class is undefined"); 73 | if (typeof Circle === "function") { 74 | assert.strictEqual( 75 | Circle.prototype instanceof Shape, 76 | true, 77 | "Circle inherits Shape" 78 | ); 79 | assert.strictEqual( 80 | Circle.toString().includes("constructor"), 81 | true, 82 | "Circle has a constructor" 83 | ); 84 | assert.strictEqual(Math.round(new Circle(1.954410048).area()), 12); 85 | } 86 | assert.strictEqual(typeof Square, "function", "Square class is undefined"); 87 | if (typeof Square === "function") { 88 | assert.strictEqual( 89 | Square.prototype instanceof Rectangle, 90 | true, 91 | "Square inherits Rectangle" 92 | ); 93 | assert.strictEqual( 94 | Square.toString().includes("constructor"), 95 | true, 96 | "Square has a constructor" 97 | ); 98 | assert.strictEqual( 99 | Square.toString().includes("area("), 100 | false, 101 | "Square does not overrides area()" 102 | ); 103 | assert.strictEqual(new Square(3).area(), 9); 104 | } 105 | 106 | // End of tests 107 | -------------------------------------------------------------------------------- /src/recursion/recursive-exponentiation/recursive-exponentiation.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create the function pow, where you need to call pow(n, e) recursively. 3 | 4 | 2⁰ = 1 5 | 2¹ = 2 = 2 * 2⁰ 6 | 2² = 2 * 2 = 2¹ * 2 7 | 2³ = 2 * 2 * 2 = 2² * 2 8 | 2⁴ ... 9 | 10 | This function must be recursive: you can't use a loop. 11 | 12 | You can't use Math.pow(). 13 | 14 | Add you own tests. 15 | 16 | */ 17 | 18 | // TODO add your code here 19 | 20 | // Begin of tests 21 | const assert = require("assert"); 22 | 23 | assert.strictEqual(typeof pow, "function"); 24 | assert.strictEqual(pow.length, 2); 25 | assert.strictEqual( 26 | pow.toString().includes("Math.pow"), 27 | false, 28 | "don't use Math.pow()" 29 | ); 30 | assert.strictEqual(pow.toString().includes("for "), false, "don't use a loop"); 31 | assert.strictEqual( 32 | pow.toString().includes("while "), 33 | false, 34 | "don't use a loop" 35 | ); 36 | assert.strictEqual( 37 | pow.toString().includes("pow("), 38 | true, 39 | "pow must be recursive" 40 | ); 41 | // TODO add your tests: 42 | 43 | // End of tests 44 | -------------------------------------------------------------------------------- /src/recursion/recursive-factorial/recursive-factorial.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a function `facto` which calculate the factorial n! of a number n. 3 | 4 | 0! = 1 5 | 1! = 1 = 1 * 0! 6 | 2! = 2 * 1 = 2 * 1! 7 | 3! = 3 * 2 * 1 = 3 * 2! 8 | 4! ... 9 | 10 | This function must be recursive: you can't use a loop. 11 | 12 | Add you own tests. 13 | 14 | */ 15 | 16 | // TODO add your code here 17 | 18 | // Begin of tests 19 | const assert = require("assert"); 20 | 21 | assert.strictEqual(typeof facto, "function"); 22 | assert.strictEqual(facto.length, 1); 23 | assert.strictEqual( 24 | facto.toString().includes("for "), 25 | false, 26 | "don't use a loop" 27 | ); 28 | assert.strictEqual( 29 | facto.toString().includes("while "), 30 | false, 31 | "don't use a loop" 32 | ); 33 | assert.strictEqual( 34 | facto.toString().includes("facto("), 35 | true, 36 | "facto must be recursive" 37 | ); 38 | // TODO add your tests: 39 | 40 | // End of tests 41 | -------------------------------------------------------------------------------- /src/recursion/recursive-fibonacci/recursive-fibonacci.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a recursive function `fibo` that returns n'th element of Fibonacci sequence. 3 | 4 | fibo(0) = 0 5 | fibo(1) = 1 6 | fibo(n) = fibo(n-1) + fibo(n-2) 7 | 8 | Example: 9 | fibo(4) = fibo(3) + fibo(2) 10 | 11 | Replace fibo(x) call with their respective values : 12 | fibo(4) = (fibo(2) + fibo(1)) + (fibo(1) + fibo(0)) 13 | fibo(4) = ((fibo(1) + fibo(0)) + 1) + (1 + 0) 14 | fibo(4) = ((1 + 0) + 1) + (1 + 0) 15 | fibo(4) = 3 16 | 17 | This function must be recursive: you can't use a loop. 18 | 19 | Add you own tests. 20 | 21 | */ 22 | 23 | // TODO add your code here 24 | 25 | // Begin of tests 26 | const assert = require("assert"); 27 | 28 | assert.strictEqual(typeof fibo, "function"); 29 | assert.strictEqual(fibo.length, 1); 30 | assert.strictEqual(fibo.toString().includes("for "), false, "don't use a loop"); 31 | assert.strictEqual( 32 | fibo.toString().includes("while "), 33 | false, 34 | "don't use a loop" 35 | ); 36 | assert.strictEqual( 37 | fibo.toString().includes("fibo("), 38 | true, 39 | "fibo must be recursive" 40 | ); 41 | // TODO add your tests: 42 | 43 | // End of tests 44 | -------------------------------------------------------------------------------- /src/recursion/recursive-multiply/recursive-multiply.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a function `multiply`, which multiply two numbers (positive or negative), using recursion. 3 | 4 | You can't use the * operator. 5 | 6 | This function must be recursive: you can't use a loop. 7 | 8 | */ 9 | 10 | // TODO add your code here 11 | 12 | // Begin of tests 13 | const assert = require("assert"); 14 | 15 | assert.strictEqual(typeof multiply, "function"); 16 | assert.strictEqual(multiply.length, 2); 17 | assert.strictEqual( 18 | multiply.toString().includes("*"), 19 | false, 20 | "don't use the * operator" 21 | ); 22 | assert.strictEqual( 23 | multiply.toString().includes("for "), 24 | false, 25 | "don't use a loop" 26 | ); 27 | assert.strictEqual( 28 | multiply.toString().includes("while "), 29 | false, 30 | "don't use a loop" 31 | ); 32 | assert.strictEqual( 33 | multiply.toString().includes("multiply("), 34 | true, 35 | "multiply must be recursive" 36 | ); 37 | assert.strictEqual(multiply(0, 0), 0); 38 | assert.strictEqual(multiply(0, 1), 0); 39 | assert.strictEqual(multiply(1, 0), 0); 40 | assert.strictEqual(multiply(1, 1), 1); 41 | assert.strictEqual(multiply(1, -1), -1); 42 | assert.strictEqual(multiply(-1, 1), -1); 43 | assert.strictEqual(multiply(-1, -1), 1); 44 | assert.strictEqual(multiply(2, 3), 6); 45 | assert.strictEqual(multiply(4, 2), 8); 46 | 47 | // End of tests 48 | -------------------------------------------------------------------------------- /src/string-advanced/caesar-cipher/caesar-cipher.js: -------------------------------------------------------------------------------- 1 | /* 2 | In cryptography, a Caesar cipher is a simple encryption technique, in which each letter in text is replaced by a letter some fixed number of positions down the alphabet. 3 | 4 | For example, with a right shift of 3, a becomes d, b becomes e, and so on until w which become z. Then x, y and z become a, b and c. 5 | 6 | Create a function `cipher` which encrypts a word (only in lowercase) using Caesar cipher, where the shift value (which can be positive or negative) is a parameter. 7 | 8 | word: shift: result: 9 | * "abcd" 1 "bcde" 10 | * "abcd" -1 "zabc" 11 | * "tacos" 3 "wdfrv" 12 | * "zebra" 2 "bgdtc" 13 | 14 | If `word` is null or not a string, or if `shift` is null or not a number, throw a TypeError. 15 | 16 | Add you own tests. 17 | 18 | */ 19 | 20 | // TODO add your code here 21 | 22 | // Begin of tests 23 | const assert = require("assert"); 24 | 25 | assert.strictEqual(typeof cipher, "function"); 26 | assert.strictEqual(cipher.length, 2); 27 | // TODO add your tests: 28 | 29 | // End of tests 30 | -------------------------------------------------------------------------------- /src/string-advanced/runlength-encoding/runlength-encoding.js: -------------------------------------------------------------------------------- 1 | /* 2 | Run-length encoding (RLE) is a very simple form of lossless data compression, in which same consecutive elements are stored as a single data value and count. 3 | 4 | Create a function `encode` that implements a RLE of a string. If a character is present only once or twice consecutively, you must not compress it. 5 | 6 | Example: 7 | * "a" -> "a" 8 | * "aa" -> "aa" 9 | * "aaa" -> "a3" 10 | * "aaaabbccca" -> "a4bbc3a" 11 | 12 | If the argument is null, return an empty string. 13 | If the argument is not a string, throw a TypeError. 14 | 15 | Add you own tests. 16 | 17 | */ 18 | 19 | // TODO add your code here 20 | 21 | // Begin of tests 22 | const assert = require("assert"); 23 | 24 | assert.strictEqual(typeof encode, "function"); 25 | assert.strictEqual(encode.length, 1); 26 | // TODO add your tests: 27 | 28 | // End of tests 29 | -------------------------------------------------------------------------------- /src/string/abbreviate-names/abbreviate-names.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a function `abbreviate` which converts a name into initials. 3 | 4 | The output should be capital letters with a dot separating them. 5 | 6 | Example: 7 | * "Alyson Hannigan" -> "A.H" 8 | * "Cobie Smulders" -> "C.S" 9 | * "Neil Patrick Harris" -> "N.P.H" 10 | 11 | Add you own tests. 12 | 13 | */ 14 | 15 | // TODO add your code here 16 | 17 | module.exports = abbreviate; 18 | -------------------------------------------------------------------------------- /src/string/abbreviate-names/abbreviate-names.test.js: -------------------------------------------------------------------------------- 1 | const abbreviate = require("./abbreviate-names"); 2 | 3 | test("abbreviate function exists", () => { 4 | expect(typeof abbreviate).toBe("function"); 5 | }); 6 | 7 | test("abbreviate as one parameter", () => { 8 | expect(abbreviate.length).toBe(1); 9 | }); 10 | 11 | // TODO add your tests here 12 | -------------------------------------------------------------------------------- /src/string/count-letters/count-letters.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a function `countChar` which counts, in a given string, the number of times a character appears. 3 | 4 | If the string or the character is null, return -1. 5 | If the character length is other than 1, return -1. 6 | 7 | Example: 8 | * "" and "a" -> 0 9 | * "a" and "a" -> 1 10 | * "aaaaabbbaa" and "a" -> 7 11 | * "bbacbaaa" and "c" -> 1 12 | * "bbcc" and "a" -> 0 13 | * null and "a" -> -1 14 | 15 | Add you own tests. 16 | 17 | */ 18 | 19 | // TODO add your code here 20 | 21 | module.exports = countChar; 22 | -------------------------------------------------------------------------------- /src/string/count-letters/count-letters.test.js: -------------------------------------------------------------------------------- 1 | const countChar = require("./count-letters"); 2 | 3 | test("countChar function exists", () => { 4 | expect(typeof countChar).toBe("function"); 5 | }); 6 | 7 | test("countChar as two parameters", () => { 8 | expect(countChar.length).toBe(2); 9 | }); 10 | 11 | // TODO add your tests here 12 | -------------------------------------------------------------------------------- /src/string/duration/duration.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a function `convertTime` which converts a time formatted as "hh:mm" in a duration in minuts. 3 | 4 | If the argument is not correctly formatted, return null. 5 | 6 | * "02:30" -> 150 7 | * "01:45" -> 105 8 | * "01h45m" -> null 9 | 10 | Add you own tests. 11 | 12 | */ 13 | 14 | // TODO add your code here 15 | 16 | module.exports = convertTime; 17 | -------------------------------------------------------------------------------- /src/string/duration/duration.test.js: -------------------------------------------------------------------------------- 1 | const convertTime = require("./duration"); 2 | 3 | test("convertTime function exists", () => { 4 | expect(typeof convertTime).toBe("function"); 5 | }); 6 | 7 | test("convertTime as one parameter", () => { 8 | expect(convertTime.length).toBe(1); 9 | }); 10 | 11 | // TODO add your tests here 12 | -------------------------------------------------------------------------------- /src/string/palindrome/palindrome.js: -------------------------------------------------------------------------------- 1 | /* 2 | A palindrome is a word or a phrase that reads the same backwards as forwards, example. madam. 3 | 4 | Create a function `isPalindrome` that returns if a word is a palindrome. 5 | 6 | This function must not be case sensitive. 7 | 8 | If the word is null or empty, return true. 9 | 10 | Example: 11 | * "rotor" -> true 12 | * "tacos" -> false 13 | * "Kayak" -> true 14 | * null -> true 15 | 16 | Add you own tests. 17 | 18 | */ 19 | 20 | // TODO add your code here 21 | 22 | module.exports = isPalindrome; 23 | -------------------------------------------------------------------------------- /src/string/palindrome/palindrome.test.js: -------------------------------------------------------------------------------- 1 | const isPalindrome = require("./palindrome"); 2 | 3 | test("isPalindrome function exists", () => { 4 | expect(typeof isPalindrome).toBe("function"); 5 | }); 6 | 7 | test("isPalindrome as one parameter", () => { 8 | expect(isPalindrome.length).toBe(1); 9 | }); 10 | 11 | // TODO add your tests here 12 | -------------------------------------------------------------------------------- /src/string/string-compare/string-compare.js: -------------------------------------------------------------------------------- 1 | /* 2 | Create a function `compare` which returns the number of identical characters at same position, from two String of same length. 3 | 4 | If the two arguments doesn't have the same length or at least one is null, return -1 instead. 5 | 6 | Example: 7 | string1 string2 result 8 | * "a" "a" 1 9 | * "a" "b" 0 10 | * "aa" "ba" 1 11 | * "cassis" "castor" 3 12 | * "tacos" "poulpe" -1 13 | * null "a" -1 14 | 15 | Add you own tests. 16 | 17 | */ 18 | 19 | // TODO add your code here 20 | 21 | module.exports = compare; 22 | -------------------------------------------------------------------------------- /src/string/string-compare/string-compare.test.js: -------------------------------------------------------------------------------- 1 | const compare = require("./string-compare"); 2 | 3 | test("compare function exists", () => { 4 | expect(typeof compare).toBe("function"); 5 | }); 6 | 7 | test("compare as two parameters", () => { 8 | expect(compare.length).toBe(2); 9 | }); 10 | 11 | // TODO add your tests here 12 | --------------------------------------------------------------------------------