diff --git a/Sprint-1/fix/median.js b/Sprint-1/fix/median.js index b22590bc6..3007f8852 100644 --- a/Sprint-1/fix/median.js +++ b/Sprint-1/fix/median.js @@ -5,10 +5,40 @@ // Hint: Please consider scenarios when 'list' doesn't have numbers (the function is expected to return null) // or 'list' has mixed values (the function is expected to sort only numbers). +// [...list] create a new exactly array but independent +// const sortArr = list.sort((a, b) => a - b); this modify the array + +// order the array to find the middle number +//using [...list] is a safe immutable sorting +// const sortArr = [...list].sort((a, b) => a - b); + function calculateMedian(list) { - const middleIndex = Math.floor(list.length / 2); - const median = list.splice(middleIndex, 1)[0]; - return median; + // if is not an array + if (!Array.isArray(list)) { + return null; + } + + // Filter for valid numbers only typeof n === "number"' already excludes null, strings, and objects + const numsOnly = list.filter((n) => typeof n === "number" && !isNaN(n)); + + // if return numbers check if after cleaning the length is same as expected or empty + if (numsOnly.length === 0) { + return null; + } + + // now we change to use the numsOnly otherwise will take string as numbers + const sortArr = numsOnly.sort((a, b) => a - b); + + // divide the array to find the middle position. + const middleIndex = Math.floor(sortArr.length / 2); + + //if residual is 0, when the array is even + if (sortArr.length % 2 === 0) { + const leftHalf = sortArr[middleIndex - 1]; + const rightHalf = sortArr[middleIndex]; + return (leftHalf + rightHalf) / 2; + } + return sortArr[middleIndex]; } module.exports = calculateMedian; diff --git a/Sprint-1/implement/dedupe.js b/Sprint-1/implement/dedupe.js index 781e8718a..4258e4c49 100644 --- a/Sprint-1/implement/dedupe.js +++ b/Sprint-1/implement/dedupe.js @@ -1 +1,10 @@ -function dedupe() {} +/** + * Deduplicates an array of elements (strings, numbers, etc.) + * @param {Array} items - The array containing potential duplicates + */ + +function dedupe(items) { + return [...new Set(items)]; +} + +module.exports = dedupe; diff --git a/Sprint-1/implement/dedupe.test.js b/Sprint-1/implement/dedupe.test.js index d7c8e3d8e..44a6a3c9c 100644 --- a/Sprint-1/implement/dedupe.test.js +++ b/Sprint-1/implement/dedupe.test.js @@ -2,7 +2,7 @@ const dedupe = require("./dedupe.js"); /* Dedupe Array -📖 Dedupe means **deduplicate** +📖 Dedupe means **deduplicate** In this kata, you will need to deduplicate the elements of an array @@ -16,13 +16,36 @@ E.g. dedupe([1, 2, 1]) returns [1, 2] // Given an empty array // When passed to the dedupe function // Then it should return an empty array -test.todo("given an empty array, it returns an empty array"); +test("given an empty array, it returns an empty array", () => { + expect(dedupe([])).toEqual([]); +}); // Given an array with no duplicates // When passed to the dedupe function // Then it should return a copy of the original array +test("given an array with no duplicates, it returns a copy of the original array", () => { + const input = ["a", "b", "c"]; + const result = dedupe(input); + + expect(result).toEqual(["a", "b", "c"]); // Check that the result is correct + expect(input).toEqual(["a", "b", "c"]); // Check that the original input array is unchanged + expect(result).not.toBe(input); // Check that the result has created a new array (not the same reference as input) +}); // Given an array of strings or numbers // When passed to the dedupe function -// Then it should return a new array with duplicates removed while preserving the -// first occurrence of each element from the original array. +// Then it should remove the duplicate values, preserving the first occurence of each element + +describe("Describes dedupe() with duplicate values", () => { + [ + { input: [1, 2, 2, 3], expected: [1, 2, 3] }, + { input: [1, 1, 3, 4, 4, 4, 5], expected: [1, 3, 4, 5] }, + { input: ["a", "b", "a", "c"], expected: ["a", "b", "c"] }, + { input: [1, "1", 1], expected: [1, "1"] }, + { input: [5, 1, 5, 5, 2], expected: [5, 1, 2] }, + ].forEach(({ input, expected }) => { + it(`should return [${expected}] for input [${input}]`, () => { + expect(dedupe(input)).toEqual(expected); + }); + }); +}); diff --git a/Sprint-1/implement/max.js b/Sprint-1/implement/max.js index 6dd76378e..c912dc9d0 100644 --- a/Sprint-1/implement/max.js +++ b/Sprint-1/implement/max.js @@ -1,4 +1,11 @@ +// 1. filter: leep only elements that are onlyNumbers. +// 2. spread (...) take the numbers out of the Array +// 3. Math.max find the largest number and return -infinity if empty. + function findMax(elements) { + const onlyNumbers = elements.filter((element) => typeof element === "number" && !Number.isNaN(element)) + return Math.max(...onlyNumbers); } module.exports = findMax; + diff --git a/Sprint-1/implement/max.test.js b/Sprint-1/implement/max.test.js index 82f18fd88..a882c9dfc 100644 --- a/Sprint-1/implement/max.test.js +++ b/Sprint-1/implement/max.test.js @@ -5,9 +5,11 @@ In this kata, you will need to implement a function that find the largest numeri E.g. max([30, 50, 10, 40]), target output: 50 E.g. max(['hey', 10, 'hi', 60, 10]), target output: 60 (sum ignores any non-numerical elements) -You should implement this function in max.js, and add tests for it in this file. +You should implement this function in max.js, and add tests for it in this file.p We have set things up already so that this file can see your function from the other file. + +Driven Development (BDD), format Given / When / Then. */ const findMax = require("./max.js"); @@ -15,29 +17,71 @@ const findMax = require("./max.js"); // Given an empty array // When passed to the max function // Then it should return -Infinity -// Delete this test.todo and replace it with a test. -test.todo("given an empty array, returns -Infinity"); - +test("should return -Infinity when given an empty array", () => { + expect(findMax([])).toEqual(-Infinity); +}); // Given an array with one number // When passed to the max function // Then it should return that number +test("should return the number itself when the array has only one element", () => { + expect(findMax([2])).toEqual(2); +}); // Given an array with both positive and negative numbers // When passed to the max function // Then it should return the largest number overall +test("should return the largest number when given both positive and negative numbers", () => { + expect(findMax([-1, -3, 0, 3])).toEqual(3); +}); // Given an array with just negative numbers // When passed to the max function // Then it should return the closest one to zero +test("should return the closest number to zero when given only negative numbers", () => { + expect(findMax([-1, -3, -2, 0])).toEqual(0); +}); // Given an array with decimal numbers // When passed to the max function // Then it should return the largest decimal number +test("should return the largest decimal number correctly", () => { + expect(findMax([1.5, 2.5, 0.5])).toEqual(2.5); +}); // Given an array with non-number values // When passed to the max function // Then it should return the max and ignore non-numeric values +test("should ignore non-numeric values (strings, etc.) and return the max", () => { + expect(findMax(["hey", 10, "hi", 60, 10])).toEqual(60); +}); + +// given an array with non-numeric values +// When passed to the max function +// Then it should strictly ignore non-numeric values, including numeric strings like '300' +test("should strictly ignore non-numeric values, including numeric strings like '300'", () => { + const input = ["hey", 10, "300", 60, 10]; + const result = findMax(input); + + expect(result).toEqual(60); // Check that the result is correct +}); + +// Given an array with numbers and NaN +// When passed to the findMax function +// Then it should ignore NaN and return the largest number +test("should ignore NaN and return the max of the remaining numbers", () => { + expect(findMax([0, NaN, 1])).toEqual(1); +}); // Given an array with only non-number values // When passed to the max function // Then it should return the least surprising value given how it behaves for all other inputs +test("given an array with only non-number values, it returns -Infinity", () => { + expect(findMax(["abc", "def"])).toEqual(-Infinity); +}); + +// Given an array with only NaN values +// When passed to the findMax function +// Then it should return -Infinity +test("should return -Infinity when the array contains only NaN", () => { + expect(findMax([NaN])).toEqual(-Infinity); +}); \ No newline at end of file diff --git a/Sprint-1/implement/sum.js b/Sprint-1/implement/sum.js index 9062aafe3..0eb4f0775 100644 --- a/Sprint-1/implement/sum.js +++ b/Sprint-1/implement/sum.js @@ -1,4 +1,10 @@ function sum(elements) { + return elements.reduce( + (acc, curr) => + typeof curr === "number" && !Number.isNaN(curr) ? acc + curr : acc, + 0 + ); } module.exports = sum; + diff --git a/Sprint-1/implement/sum.test.js b/Sprint-1/implement/sum.test.js index dd0a090ca..6d4ee4c08 100644 --- a/Sprint-1/implement/sum.test.js +++ b/Sprint-1/implement/sum.test.js @@ -13,24 +13,70 @@ const sum = require("./sum.js"); // Given an empty array // When passed to the sum function // Then it should return 0 -test.todo("given an empty array, returns 0") +test("Should return 0 for empty array", () => { + expect(sum([])).toEqual(0); +}); // Given an array with just one number // When passed to the sum function // Then it should return that number +test("Should return the number itself for an array with one number", () => { + expect(sum([5])).toEqual(5); +}); // Given an array containing negative numbers // When passed to the sum function // Then it should still return the correct total sum +test("Should return the correct sum even when the array contains negative numbers", () => { + expect(sum([-1, -2, -3])).toEqual(-6); +}); // Given an array with decimal/float numbers // When passed to the sum function // Then it should return the correct total sum +test("Should return the correct sum even when the array contains decimal numbers", () => { + expect(sum([1.4, 1.6, 5.8])).toEqual(8.8); +}); + +describe("sum() edge cases and floating point precision", () => { + [ + { input: [0.1, 0.2], expected: 0.3 }, + { input: [0.7, 0.2], expected: 0.9 }, + { input: [1.2, 0.6, 0.005], expected: 1.805 }, + { input: [0.005, 0.6, 1.2], expected: 1.805 }, + ].forEach(({ input, expected }) => { + it(`should return ${expected} for input [${input.join(", ")}]`, () => { + expect(sum(input)).toBeCloseTo(expected); + }); + }); +}); + // Given an array containing non-number values // When passed to the sum function // Then it should ignore the non-numerical values and return the sum of the numerical elements +test("should return the sum of the numerical elements and ignore non-numerical values", () => { + expect(sum(['hey', 10, 'hi', 60, 10])).toEqual(80); +}) // Given an array with only non-number values // When passed to the sum function // Then it should return the least surprising value given how it behaves for all other inputs +test("Should return 0 for an array with only non-numbers", () => { + expect(sum(['hey', 'hi', 'hello'])).toEqual(0); +}) + +// Given an array with NaN and numbers +// When passed to the sum function +// Then it should ignore NaN and return the sum of the numbers +test("should ignore NaN and return the correct sum", () => { + expect(sum([NaN, 1, 5])).toEqual(6); +}); + + +// Given an array with Infinity and -Infinity +// When passed to the sum function +// Then it should return NaN (standard JS behavior for infinite subtraction) +test("should return NaN when summing Infinity and -Infinity", () => { + expect(sum([Infinity, -Infinity])).toBeNaN(); +}); \ No newline at end of file diff --git a/Sprint-1/refactor/includes.js b/Sprint-1/refactor/includes.js index 29dad81f0..8c9ae2e66 100644 --- a/Sprint-1/refactor/includes.js +++ b/Sprint-1/refactor/includes.js @@ -1,8 +1,7 @@ // Refactor the implementation of includes to use a for...of loop function includes(list, target) { - for (let index = 0; index < list.length; index++) { - const element = list[index]; + for (const element of list) { if (element === target) { return true; } diff --git a/Sprint-1/refactor/includes.test.js b/Sprint-1/refactor/includes.test.js index 812158470..dd09c1bc6 100644 --- a/Sprint-1/refactor/includes.test.js +++ b/Sprint-1/refactor/includes.test.js @@ -2,37 +2,22 @@ const includes = require("./includes.js"); -test("returns true when target is in array", () => { - const currentOutput = includes(["a", "b", "c", "d"], "c"); - const targetOutput = true; - - expect(currentOutput).toEqual(targetOutput); -}); +test("Return true if the array contains the elements desired", () => { + expect(includes(["a", "b", "c", "d"], "c")).toBe(true); +}) test("returns false when target not in array", () => { - const currentOutput = includes([1, 2, 3, 4], "a"); - const targetOutput = false; - - expect(currentOutput).toEqual(targetOutput); + expect(includes([1, 2, 3, 4], "a")).toBe(false); }); test("returns true when the target is in array multiple times", () => { - const currentOutput = includes([1, 2, 2, 3], 2); - const targetOutput = true; - - expect(currentOutput).toEqual(targetOutput); + expect(includes([1, 2, 2, 3], 2)).toBe(true); }); test("returns false for empty array", () => { - const currentOutput = includes([]); - const targetOutput = false; - - expect(currentOutput).toEqual(targetOutput); + expect(includes([], "a")).toBe(false); }); -test("searches for null", () => { - const currentOutput = includes(["b", "z", null, "a"], null); - const targetOutput = true; - - expect(currentOutput).toEqual(targetOutput); -}); +test("should find null when it exists in the array", () => { + expect(includes(["b", "z", null, "a"], null)).toBe(true); +}); \ No newline at end of file diff --git a/Sprint-1/stretch/aoc-2018-day1/input.txt b/Sprint-1/stretch/aoc-2018-day1/input.txt index 1ffa65fc8..3fad5707b 100644 --- a/Sprint-1/stretch/aoc-2018-day1/input.txt +++ b/Sprint-1/stretch/aoc-2018-day1/input.txt @@ -1,951 +1,996 @@ --10 --12 -+1 -+14 -+11 --19 --4 -+10 -+10 --12 --13 --10 --8 +-2 +-3 ++4 +-15 +-15 ++18 +-7 +11 -+3 --10 -+8 -+5 +-16 -14 -+7 -+12 -+12 ++2 +-6 ++16 ++6 +14 --1 -+17 --5 -+9 -15 -+8 --16 -+9 -+6 ++12 +-5 +17 +-10 +-20 +-19 +-14 +-10 ++4 -11 -+19 -+11 --9 ++10 -1 --8 --16 --5 -+6 -+2 -+6 +12 -+15 -+16 --6 --8 --5 -+11 --9 -+19 -+19 --5 --12 -17 --20 -+9 --6 -2 -+20 -+15 --8 -+15 -+19 --5 --17 --9 +1 --9 --11 --19 --1 --15 -+18 --4 +-17 ++9 ++4 +19 -+3 -+21 ++11 +-17 ++15 +-12 +5 ++4 -1 -+8 -+9 -+9 +-10 +-19 -16 -+17 --15 +-9 +18 -+14 -+8 ++2 ++4 +-19 ++16 ++6 +-16 +-14 ++7 +-9 ++7 ++17 ++17 +-14 ++6 +-22 -13 -2 --15 -+13 +-1 +-18 +-3 ++19 +19 --13 -+5 -+16 +16 -+7 -+8 --19 -+3 --12 -+18 --16 --19 -+8 --16 -+20 -+15 --5 --17 -+15 +-22 +14 -2 -+18 --6 -+5 -+16 -+13 +-3 ++2 +-18 +-15 +-14 +-4 +-15 ++1 +-3 -8 --9 --1 -+13 +18 --2 -+16 --4 -+19 +-11 +6 -+14 --6 --16 --10 --5 +-7 ++17 ++7 +-8 +-13 +-4 ++7 -15 -+11 -+10 -+18 -+8 --2 -+15 --9 +-11 +7 -+10 +9 --6 +-7 +1 +-20 +-19 +-18 -17 -12 -+19 -+14 --9 --18 -+20 -+12 -+10 ++7 +-16 +-11 +-4 +-8 +-4 +-3 +-2 ++3 +-15 ++18 ++5 +14 -+6 -+9 --18 -+4 +15 -+15 -+3 -+9 --4 ++2 -19 -+8 -+16 ++5 +-13 +19 --12 ++9 ++8 ++5 -1 -+16 +-19 +11 ++2 +13 --8 -+4 -+18 +-17 ++9 +-16 ++14 ++20 ++12 ++8 +10 --11 -+18 ++17 +-15 -8 ++15 +19 --4 --5 --12 +-14 -3 -10 --11 --18 --7 -+3 -+14 -+18 +2 --7 --12 -+14 -+12 -+13 --1 -+13 ++4 -1 ++14 +-12 +15 -+13 --1 --17 --4 -+17 --3 -+13 -+5 --19 -+17 -+10 -+6 --15 -+11 -+16 -+11 -+20 -+19 -+5 --11 -2 --12 --6 -11 -14 -+5 -+10 --23 +-18 ++6 +-12 ++7 ++18 ++15 ++6 ++12 ++3 +-6 ++17 ++11 +14 ++13 ++3 ++6 -11 -+22 --1 --14 --35 --23 -+11 -+4 -+10 --6 -+19 +-19 -5 -+4 --13 ++14 +-10 -7 -+11 --24 --17 -+9 ++18 +-8 +-13 +-2 ++19 +-18 -17 +11 -+2 --4 --10 --24 +14 ++17 ++1 ++26 ++6 +15 -+19 -+7 --2 -+11 --13 --8 --8 --14 --17 ++21 +-5 ++12 +6 -+8 --16 --18 -+1 --21 --14 -+8 --2 -+20 --19 -+9 --15 --6 --7 +4 --3 ++10 -8 +16 +-14 ++4 +-1 ++17 +-15 +-23 +15 --26 +18 --22 --16 --3 --17 ++19 ++10 -18 -+4 -+5 -+3 --1 -+3 -+2 -+3 -+7 --5 -+20 --11 +-2 ++15 +15 --6 --19 --24 --6 --20 +13 --4 ++5 ++10 +-8 ++2 -18 ++13 +15 -+9 -+16 -+12 --5 -+16 -+9 --4 --14 --9 ++8 -19 --5 --16 --16 -+5 ++2 -4 +-3 ++20 +-3 +12 ++6 ++13 ++13 -15 --15 --14 -+4 --18 --12 --4 +6 -+9 --12 -+14 -+9 --6 +-15 +3 -+8 -+4 +7 --14 --15 --18 -+12 -19 --14 --15 --16 ++11 ++17 +15 --8 -+14 -4 --21 -+7 --12 --2 -10 --6 -+14 -+14 --9 -14 --16 -+2 +-20 ++18 +-11 +-17 ++8 ++12 ++3 +-11 +7 -+5 --15 --15 +-13 +-4 +19 --16 --5 --16 --19 +-7 +-17 ++12 +9 --27 ++13 ++7 +-13 ++24 +-2 ++14 +-5 ++10 +-6 +-1 -8 -+6 -+1 +-5 +-6 ++5 ++12 ++16 ++5 -14 ++19 ++18 -9 --50 +-6 +-12 +-2 ++19 +-12 -9 --21 +5 --20 --19 -+6 --11 -+6 -+1 --17 --14 --2 -+8 -4 -+16 -+1 --3 --9 -+20 -+15 --22 --3 --13 --12 --25 -+5 --13 --2 --8 --11 -+17 -+3 --7 -+13 -+1 -+18 --13 -+1 -+7 --15 --43 --6 --10 --9 --20 --7 --8 --15 -9 -+13 -9 -+24 -+13 -+5 --8 --15 --4 --4 --4 --14 --21 +16 -+15 +-19 -14 +-7 +-24 -20 --20 --15 --19 --41 +16 -+3 -+8 --22 --30 -+8 -+40 -+15 -+24 --7 -+22 -+10 -+15 ++12 ++19 ++20 +-15 ++26 ++21 +-2 ++12 ++4 +-2 ++18 +-17 +-12 +-20 ++2 +9 -+28 +14 -+2 ++16 ++12 +-9 +14 -+6 +17 -+1 -+30 -+5 --2 -+46 -+24 -+46 +-19 ++11 ++3 +-13 -3 --7 -+35 -+16 -+13 --21 -+28 -+13 --25 -+180 -+25 -+5 --9 -+23 --5 --2 -+13 --12 -+2 --25 --5 ++11 +-14 +18 --24 -+45 -+17 --7 -+22 --152 --11 -+4 -+50 -+129 --7 -+22 -+109 --56 -+80 -+29 --75060 ++9 +-16 -2 --14 ++19 +7 --17 --5 -+6 +-10 -3 -+18 ++4 ++10 ++15 +19 --14 --12 --6 -+9 +-2 -5 --13 --6 --3 --15 -+13 -+3 --18 ++2 ++2 +-11 ++6 +-17 -11 ++6 +-10 +16 ++7 +-1 -2 -+10 --14 --7 +19 --20 -+15 -+10 -+12 -+10 ++6 +16 --11 -+14 --5 +-12 +14 -+11 -5 ++19 +-12 +1 --13 -+1 -+18 +-6 +-6 +-2 ++7 ++19 ++17 +-4 ++3 ++3 ++17 ++16 +-2 -10 -+25 -+13 +-1 +-14 +-2 -17 +-11 ++3 +-21 +15 ++11 ++7 +-3 -18 +1 --6 --12 -+5 --7 -+18 --6 --18 --17 --5 --15 --1 -15 +-11 +1 --12 +-18 ++11 ++15 +-17 +-16 +-19 +9 +-5 +16 -+8 +-18 ++13 ++16 +-17 +-1 +-3 +-2 ++20 ++14 +-13 +-17 ++13 +5 -+1 -+9 -+18 ++2 ++19 ++22 +-3 +-22 ++10 -13 --30 --27 --19 +2 +-29 +-27 -16 --19 --10 --18 -+21 ++17 +-27 +18 +-13 +-4 ++6 -5 -+14 -+9 ++12 +-16 +-9 ++3 ++1 ++10 +-25 +-1 +-19 ++13 ++12 ++2 -6 +-12 ++3 ++25 ++28 +-4 +2 ++17 +-9 ++63 ++23 +-8 ++9 +-6 ++15 +-14 ++12 ++6 ++18 +-6 +-15 ++12 -16 --11 +-3 ++15 ++24 ++19 +-6 ++4 +-8 +-19 ++4 ++4 +-20 +-1 ++24 ++10 +-9 ++13 ++11 ++2 ++11 ++14 +-2 ++18 +-12 +1 +-17 ++6 ++1 +-16 ++10 ++4 ++9 +-6 ++10 +-14 +-2 ++22 ++2 ++6 ++10 +-19 +-24 ++10 ++11 ++14 ++2 ++5 +18 --4 -+19 ++29 ++1 ++20 +7 -+6 --8 ++3 +-12 +25 --50 -+6 -21 ++24 ++4 +-18 ++1 ++51 ++19 +-17 +-23 ++31 +-15 ++27 ++2 ++19 +-16 ++1 ++18 ++9 ++22 +6 ++15 +-19 ++14 +-7 ++3 ++14 +-7 +-15 ++18 +-8 +-1 +-14 +-7 +-16 ++22 ++22 -2 ++18 ++2 +-15 +-39 ++5 ++21 +-5 +-2 ++4 ++1 ++9 +-58 ++6 +-95 +-85 +-5 ++1 ++7 ++9 ++15 +-117 +-12 +-14 +-18 ++70 ++9 +-17 ++93 +-37 +-134 +-90 ++22 +-19 +-7 +-59 +14 --11 -+10 +-13 +-47 ++213 ++81022 ++9 ++5 ++4 +-3 +-16 +-2 ++4 ++2 ++5 +-12 -9 -+16 -+25 --61 --17 +-13 ++2 +-18 +-18 -14 ++7 ++18 +-19 +13 -+3 --14 --4 -1 +-6 +9 -1 +-18 ++15 +-14 -4 --5 -+7 --15 -+7 ++12 +-1 ++5 +16 +-7 ++12 +6 --2 --11 --11 --13 -+11 --12 --13 --8 +-16 ++13 ++10 +3 +-11 -13 ++6 +-7 +16 ++3 +-6 ++19 +-15 ++14 -1 ++19 ++19 ++13 +-9 +-3 +-10 -14 ++15 +-9 +19 -+4 +-6 +10 -+12 -+26 +-7 ++11 +-1 ++3 ++2 +-3 ++8 ++3 ++13 +6 -+4 -+24 --31 -+9 --10 --23 --13 +3 --18 --9 --6 -+1 --2 -+15 --10 --17 ++2 ++18 ++9 -17 ++13 +15 +-13 +9 -+4 -+19 --4 -+12 -+11 --25 -+16 -+4 --2 -+39 -+49 -+9 -+96 -+4 ++2 +19 -+3 -+11 -+25 +14 -+11 +-13 ++8 ++18 ++6 +-4 +-18 ++1 +-19 +-1 ++10 -5 --26 --8 +-11 +-10 -16 -+11 -+2 -+2 --1 +-4 +-5 ++3 +-13 +-19 +-18 ++16 ++16 +-5 ++16 -10 --45 --160 --31 +-8 ++9 ++14 ++1 ++9 -3 --43 --18 +19 -+3 -+4 +-12 +11 ++12 ++5 ++19 +-9 ++4 ++15 ++19 +-4 +-10 +-12 +-18 -16 --19 --22 -+6 -+2 -+10 --11 --17 -+7 ++13 +-4 +-16 +-14 +-15 ++18 +1 -+15 -+17 --19 -+6 --26 +-8 -7 --9 -+19 +-18 ++3 +-21 ++9 +-7 ++8 ++18 +2 +-11 +6 --22 ++10 ++9 ++11 +-21 ++19 ++4 +2 --8 -+5 +7 -+9 -+8 ++10 -16 -+2 --19 --19 --3 ++13 ++9 ++9 +16 -+5 -+4 --18 ++9 ++13 -11 --19 +16 --15 -+7 --1 --9 --19 ++10 ++14 ++13 +-5 +-10 +-16 +-2 +-2 ++6 ++19 ++1 +-16 ++14 +-13 ++3 +-5 +-4 ++12 +-5 ++22 +11 --17 -5 -+7 ++13 ++4 ++13 ++19 ++18 +-13 ++15 ++19 +-12 -11 -+16 -19 +-12 +5 -+21 +-19 ++18 +-19 ++5 +-13 +-10 ++15 +-8 +-2 -2 +-11 +-6 ++5 +-4 ++21 ++18 +-5 ++18 +-11 ++19 +12 +-5 ++4 +-16 +-10 ++11 +-16 ++13 ++11 +-1 ++15 ++4 ++13 +-15 +14 -7 -+18 --8 -+10 --11 --17 -+3 --13 +19 --3 +10 -+17 -+17 --18 -+7 --2 --2 -+12 --6 +-8 +19 --20 --15 --11 --27 -+8 -+18 -+9 --1 --2 ++4 +-7 +19 -+7 -+12 -+32 ++8 +14 -+13 --9 --14 -+20 -+18 --4 --49 --6 --10 -7 --4 ++3 ++13 ++19 -9 --6 --37 --21 --2 -+5 -+12 +4 --33 --4 --13 --4 -+13 +-17 -19 --7 +-11 +-11 +-4 -16 --1 --1 -+8 --14 --15 -+11 --10 --14 --22 +-21 +-5 ++1 ++16 -11 -+10 --3 -+7 -+9 -15 -+16 +-18 +-13 +-7 +-13 +-21 +-18 ++10 ++14 ++13 -7 -1 -+2 +-4 ++17 +20 -+11 --1 -+6 --2 ++12 +-24 +3 +-8 +3 -+2 --20 --10 ++10 +11 --10 ++11 +-16 +13 --1 -+20 -+7 ++12 ++19 +-2 +7 ++6 +5 -+1 -+4 --13 ++3 ++10 +15 --3 +2 --4 --3 ++11 ++14 +-9 -1 -+13 --15 --14 --2 --6 -+3 -+13 -19 --11 -+8 --21 --2 --23 --18 -+20 -+7 +-16 ++9 ++17 +-13 ++4 +6 --28 -+7 --33 ++2 +13 --16 --18 --10 --18 ++16 ++19 ++12 ++1 ++18 ++17 ++19 ++5 +-8 ++6 ++10 ++16 +-9 +13 -+8 --14 --13 --2 +-8 +-9 ++5 +-12 +-7 +-16 +4 --14 +-12 ++18 +-19 -7 ++2 ++2 +-19 ++10 ++19 ++9 +-6 -18 --20 --4 --5 -+8 ++4 ++18 +-11 +-13 +-11 +-16 ++3 -4 -+16 -+21 -+20 --8 --14 +-11 -2 ++10 -14 --22 ++16 +14 -+36 -+32 --28 +-1 ++2 +1 --21 -+8 -+14 -+75784 \ No newline at end of file ++4 +-9 ++17 +-5 +-14 +-15 +-13 ++16 +-8 +-11 ++2 ++19 ++23 ++15 +-13 ++20 ++3 ++7 ++9 ++17 ++10 +-11 +-19 +-19 ++9 +-17 ++12 +-20 +-22 ++16 +-9 +-18 +-10 +-9 +-81046 \ No newline at end of file