From 017aa8d1f0a955436f71cb2acd878444f06bb096 Mon Sep 17 00:00:00 2001 From: AndreiHarbunou Date: Mon, 3 Jun 2024 12:23:24 +0300 Subject: [PATCH 01/12] 01-strings-tasks --- task/01-strings-tasks.js | 41 +++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/task/01-strings-tasks.js b/task/01-strings-tasks.js index e28054657..9f975dfdb 100644 --- a/task/01-strings-tasks.js +++ b/task/01-strings-tasks.js @@ -22,7 +22,7 @@ * '', 'bb' => 'bb' */ function concatenateStrings(value1, value2) { - throw new Error('Not implemented'); + return value1 + value2; } @@ -38,7 +38,7 @@ function concatenateStrings(value1, value2) { * '' => 0 */ function getStringLength(value) { - throw new Error('Not implemented'); + return value.length; } /** @@ -55,7 +55,7 @@ function getStringLength(value) { * 'Chuck','Norris' => 'Hello, Chuck Norris!' */ function getStringFromTemplate(firstName, lastName) { - throw new Error('Not implemented'); + return `Hello, ${firstName} ${lastName}!`; } /** @@ -69,7 +69,7 @@ function getStringFromTemplate(firstName, lastName) { * 'Hello, Chuck Norris!' => 'Chuck Norris' */ function extractNameFromTemplate(value) { - throw new Error('Not implemented'); + return value.slice(7, -1); } @@ -84,7 +84,7 @@ function extractNameFromTemplate(value) { * 'cat' => 'c' */ function getFirstChar(value) { - throw new Error('Not implemented'); + return value[0]; } /** @@ -99,7 +99,7 @@ function getFirstChar(value) { * '\tHello, World! ' => 'Hello, World!' */ function removeLeadingAndTrailingWhitespaces(value) { - throw new Error('Not implemented'); + return value.trim();; } /** @@ -114,7 +114,7 @@ function removeLeadingAndTrailingWhitespaces(value) { * 'cat', 3 => 'catcatcat' */ function repeatString(value, count) { - throw new Error('Not implemented'); + return value.repeat(count); } /** @@ -130,7 +130,7 @@ function repeatString(value, count) { * 'ABABAB','BA' => 'ABAB' */ function removeFirstOccurrences(str, value) { - throw new Error('Not implemented'); + return str.replace(value, ''); } /** @@ -145,7 +145,7 @@ function removeFirstOccurrences(str, value) { * '' => 'a' */ function unbracketTag(str) { - throw new Error('Not implemented'); + return str.slice(1, -1); } @@ -160,7 +160,7 @@ function unbracketTag(str) { * 'abcdefghijklmnopqrstuvwxyz' => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' */ function convertToUpperCase(str) { - throw new Error('Not implemented'); + return str.toUpperCase(); } /** @@ -174,7 +174,7 @@ function convertToUpperCase(str) { * 'info@gmail.com' => ['info@gmail.com'] */ function extractEmails(str) { - throw new Error('Not implemented'); + return str.split(';'); } /** @@ -201,7 +201,10 @@ function extractEmails(str) { * */ function getRectangleString(width, height) { - throw new Error('Not implemented'); + const topLine = '┌' + '─'.repeat(width - 2) + '┐\n'; + const middleLine = '│' + ' '.repeat(width - 2) + '│\n'; + const bottomLine = '└' + '─'.repeat(width - 2) + '┘\n'; + return topLine + middleLine.repeat(height - 2) + bottomLine; } @@ -221,7 +224,10 @@ function getRectangleString(width, height) { * */ function encodeToRot13(str) { - throw new Error('Not implemented'); + const alpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; + const flipped = 'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm'; + return str.replace(/[a-z]/gi, letter => flipped[alpha.indexOf(letter)]); +} } /** @@ -238,7 +244,7 @@ function encodeToRot13(str) { * isString(new String('test')) => true */ function isString(value) { - throw new Error('Not implemented'); + return typeof value === 'string' || value instanceof String; } @@ -267,7 +273,12 @@ function isString(value) { * 'K♠' => 51 */ function getCardId(value) { - throw new Error('Not implemented'); + const arr = ['A♣', '2♣', '3♣', '4♣', '5♣', '6♣', '7♣', '8♣', '9♣', '10♣', 'J♣', 'Q♣', 'K♣', + 'A♦', '2♦', '3♦', '4♦', '5♦', '6♦', '7♦', '8♦', '9♦', '10♦', 'J♦', 'Q♦', 'K♦', + 'A♥', '2♥', '3♥', '4♥', '5♥', '6♥', '7♥', '8♥', '9♥', '10♥', 'J♥', 'Q♥', 'K♥', + 'A♠', '2♠', '3♠', '4♠', '5♠', '6♠', '7♠', '8♠', '9♠', '10♠', 'J♠', 'Q♠', 'K♠' + ]; + return arr.indexOf(value); } From 152820d576cdcaf71d39af49fc538f3a206d7360 Mon Sep 17 00:00:00 2001 From: AndreiHarbunou Date: Mon, 3 Jun 2024 12:56:34 +0300 Subject: [PATCH 02/12] 02-number-tasks --- task/02-numbers-tasks.js | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/task/02-numbers-tasks.js b/task/02-numbers-tasks.js index c9ed20208..4fb7bdbac 100644 --- a/task/02-numbers-tasks.js +++ b/task/02-numbers-tasks.js @@ -22,7 +22,7 @@ * 5, 5 => 25 */ function getRectangleArea(width, height) { - throw new Error('Not implemented'); + return width * height; } @@ -38,7 +38,7 @@ function getRectangleArea(width, height) { * 0 => 0 */ function getCicleCircumference(radius) { - throw new Error('Not implemented'); + return 2 * Math.PI * radius; } /** @@ -54,7 +54,7 @@ function getCicleCircumference(radius) { * -3, 3 => 0 */ function getAverage(value1, value2) { - throw new Error('Not implemented'); + return value1 / 2 + value2 / 2; } /** @@ -73,7 +73,7 @@ function getAverage(value1, value2) { * (-5,0) (10,-10) => 18.027756377319946 */ function getDistanceBetweenPoints(x1, y1, x2, y2) { - throw new Error('Not implemented'); + return Math.sqrt(Math.pow((x2 - x1), 2) + Math.pow((y2 - y1), 2)); } /** @@ -89,7 +89,7 @@ function getDistanceBetweenPoints(x1, y1, x2, y2) { * 5*x = 0 => 0 */ function getLinearEquationRoot(a, b) { - throw new Error('Not implemented'); + return -b / a; } @@ -111,7 +111,17 @@ function getLinearEquationRoot(a, b) { * (0,1) (1,2) => 0 */ function getAngleBetweenVectors(x1, y1, x2, y2) { - throw new Error('Not implemented'); + let angle = Math.atan2(x1, y1) - Math.atan2(x2, y2); + + if (angle < 0) { + angle += 2 * Math.PI; + } + + if (angle > Math.PI) { + angle -= 2 * Math.PI; + } + + return angle;; } /** @@ -127,7 +137,7 @@ function getAngleBetweenVectors(x1, y1, x2, y2) { * 0 => 0 */ function getLastDigit(value) { - throw new Error('Not implemented'); + return value % 10; } @@ -143,7 +153,7 @@ function getLastDigit(value) { * '-525.5' => -525.5 */ function parseNumberFromString(value) { - throw new Error('Not implemented'); + return +value; } /** @@ -160,7 +170,7 @@ function parseNumberFromString(value) { * 1,2,3 => 3.741657386773941 */ function getParallelipidedDiagonal(a,b,c) { - throw new Error('Not implemented'); + return Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2) + Math.pow(c, 2)); } /** @@ -181,7 +191,7 @@ function getParallelipidedDiagonal(a,b,c) { * 1678, 3 => 2000 */ function roundToPowerOfTen(num, pow) { - throw new Error('Not implemented'); + return Math.round(num / Math.pow(10, pow)) * Math.pow(10, pow); } /** @@ -202,7 +212,13 @@ function roundToPowerOfTen(num, pow) { * 17 => true */ function isPrime(n) { - throw new Error('Not implemented'); + for (let i = 2; i < n; i++) { + if (n % i === 0) { + return false; + } + } + + return true; } /** @@ -221,7 +237,7 @@ function isPrime(n) { * toNumber(new Number(42), 0) => 42 */ function toNumber(value, def) { - throw new Error('Not implemented'); + return Number(value) || def; } module.exports = { From 9853b8430e3e6425aa9f8991df4b277c8f3be19f Mon Sep 17 00:00:00 2001 From: AndreiHarbunou Date: Mon, 3 Jun 2024 13:02:36 +0300 Subject: [PATCH 03/12] 03-date-tasks --- task/03-date-tasks.js | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/task/03-date-tasks.js b/task/03-date-tasks.js index 83c6266bc..efda57077 100644 --- a/task/03-date-tasks.js +++ b/task/03-date-tasks.js @@ -22,7 +22,7 @@ * 'Sun, 17 May 1998 03:00:00 GMT+01' => Date() */ function parseDataFromRfc2822(value) { - throw new Error('Not implemented'); + return new Date(value); } /** @@ -37,7 +37,7 @@ function parseDataFromRfc2822(value) { * '2016-01-19T08:07:37Z' => Date() */ function parseDataFromIso8601(value) { - throw new Error('Not implemented'); + return new Date(value); } @@ -56,7 +56,18 @@ function parseDataFromIso8601(value) { * Date(2015,1,1) => false */ function isLeapYear(date) { - throw new Error('Not implemented'); + const year = date.getFullYear(); + + if (year % 4 != 0) { + return false; + } + else if (year % 100 != 0) { + return true; + } + else if (year % 400 != 0) { + return false; + } + else return true; } @@ -76,7 +87,12 @@ function isLeapYear(date) { * Date(2000,1,1,10,0,0), Date(2000,1,1,15,20,10,453) => "05:20:10.453" */ function timeSpanToString(startDate, endDate) { - throw new Error('Not implemented'); + const rez = endDate - startDate; + let h = Math.trunc(rez / 3600000 % 100).toString().padStart(2, '0'); + let m = Math.trunc(rez / 60000 % 60).toString().padStart(2, '0'); + let s = Math.trunc(rez / 1000 % 60).toString().padStart(2, '0'); + let ms = Math.trunc(rez % 1000).toString().padStart(3, '0'); + return (h + ':' + m + ':' + s + '.' + ms); } @@ -94,7 +110,15 @@ function timeSpanToString(startDate, endDate) { * Date.UTC(2016,3,5,21, 0) => Math.PI/2 */ function angleBetweenClockHands(date) { - throw new Error('Not implemented'); + let hours = date.getUTCHours(); + let minutes = date.getUTCMinutes(); + hours = (hours > 12 ? hours - 12 : hours); + let angle = Math.abs(0.5 * (60 * hours - 11 * minutes)) + + if (angle > 180) { + angle -= 180; + } + return angle * Math.PI / 180; } From 1c8b39a86d206d24bb3ea052080d6ce84c5d0306 Mon Sep 17 00:00:00 2001 From: AndreiHarbunou Date: Tue, 4 Jun 2024 16:42:12 +0300 Subject: [PATCH 04/12] 04-arrays-tasks --- task/04-arrays-tasks.js | 123 +++++++++++++++++++++++++++++----------- 1 file changed, 91 insertions(+), 32 deletions(-) diff --git a/task/04-arrays-tasks.js b/task/04-arrays-tasks.js index ff3a4c019..68bf3d8e2 100644 --- a/task/04-arrays-tasks.js +++ b/task/04-arrays-tasks.js @@ -23,7 +23,7 @@ * [0, 1, 2, 3, 4, 5], 5 => 5 */ function findElement(arr, value) { - throw new Error('Not implemented'); + return arr.indexOf(value); } /** @@ -38,7 +38,7 @@ function findElement(arr, value) { * 5 => [ 1, 3, 5, 7, 9 ] */ function generateOdds(len) { - throw new Error('Not implemented'); + return new Array(len).fill(1).map((x, i) => x + 2 * i); } @@ -54,7 +54,7 @@ function generateOdds(len) { * [] => [] */ function doubleArray(arr) { - throw new Error('Not implemented'); + return arr.concat(arr); } @@ -70,7 +70,7 @@ function doubleArray(arr) { * [] => [] */ function getArrayOfPositives(arr) { - throw new Error('Not implemented'); + return arr.filter(x => x > 0); } /** @@ -85,7 +85,7 @@ function getArrayOfPositives(arr) { * [ 'cat, 'dog', 'raccon' ] => [ 'cat', 'dog', 'racoon' ] */ function getArrayOfStrings(arr) { - throw new Error('Not implemented'); + return arr.filter(x => Object.prototype.toString.call(x) === "[object String]"); } /** @@ -102,7 +102,7 @@ function getArrayOfStrings(arr) { * [ false, 0, NaN, '', undefined ] => [ ] */ function removeFalsyValues(arr) { - throw new Error('Not implemented'); + return arr.filter(x => Boolean(x) !== false); } /** @@ -116,7 +116,7 @@ function removeFalsyValues(arr) { * [ 'a', 'b', 'c', 'd', 'e', 'f', 'g' ] => [ 'A', 'B', 'C', 'D', 'E', 'F', 'G' ] */ function getUpperCaseStrings(arr) { - throw new Error('Not implemented'); + return arr.map(x => x.toUpperCase()); } @@ -131,7 +131,7 @@ function getUpperCaseStrings(arr) { * [ 'angular', 'react', 'ember' ] => [ 7, 5, 5 ] */ function getStringsLength(arr) { - throw new Error('Not implemented'); + return arr.map(x => x.length); } /** @@ -146,7 +146,7 @@ function getStringsLength(arr) { * [ 1, 'b', 'c'], 0, 'x' => [ 'x', 1, 'b', 'c' ] */ function insertItem(arr, item, index) { - throw new Error('Not implemented'); + return arr.splice(index, 0, item); } /** @@ -160,7 +160,7 @@ function insertItem(arr, item, index) { * [ 'a', 'b', 'c', 'd'], 3 => [ 'a', 'b', 'c' ] */ function getHead(arr, n) { - throw new Error('Not implemented'); + return arr.slice(0, n); } @@ -175,7 +175,7 @@ function getHead(arr, n) { * [ 'a', 'b', 'c', 'd'], 3 => [ 'b', 'c', 'd' ] */ function getTail(arr, n) { - throw new Error('Not implemented'); + return arr.slice(arr.length - n); } @@ -200,7 +200,7 @@ function getTail(arr, n) { * +'30,31,32,33,34' */ function toCsvText(arr) { - throw new Error('Not implemented'); + return arr.join('\n'); } /** @@ -215,7 +215,7 @@ function toCsvText(arr) { * [ 10, 100, -1 ] => [ 100, 10000, 1 ] */ function toArrayOfSquares(arr) { - throw new Error('Not implemented'); + return arr.map(x => x * x); } @@ -234,7 +234,9 @@ function toArrayOfSquares(arr) { * [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] => [ 1, 3, 6, 10, 15, 21, 28, 36, 45, 55 ] */ function getMovingSum(arr) { - throw new Error('Not implemented'); + var arr2 = []; + arr.reduce((prev, curr, i) => arr2[i] = prev + curr, 0); + return arr2; } /** @@ -249,7 +251,7 @@ function getMovingSum(arr) { * [ "a" ] => [] */ function getSecondItems(arr) { - throw new Error('Not implemented'); + return arr.filter((value, index) => index % 2 !== 0); } @@ -268,7 +270,9 @@ function getSecondItems(arr) { * [ 1,2,3,4,5 ] => [ 1, 2,2, 3,3,3, 4,4,4,4, 5,5,5,5,5 ] */ function propagateItemsByPositionIndex(arr) { - throw new Error('Not implemented'); + return [].concat(...arr.map((item, i) => { + return new Array(i + 1).fill(item); + })); } @@ -286,7 +290,7 @@ function propagateItemsByPositionIndex(arr) { * [ 10, 10, 10, 10 ] => [ 10, 10, 10 ] */ function get3TopItems(arr) { - throw new Error('Not implemented'); + return arr.sort((a, b) => b - a).slice(0, 3);; } @@ -304,7 +308,7 @@ function get3TopItems(arr) { * [ 1, '2' ] => 1 */ function getPositivesCount(arr) { - throw new Error('Not implemented'); + return arr.filter(value => typeof (value) == "number" && value > 0).length; } /** @@ -321,7 +325,20 @@ function getPositivesCount(arr) { * [ 'one','one','one','zero' ] => [ 'zero','one','one','one' ] */ function sortDigitNamesByNumericOrder(arr) { - throw new Error('Not implemented'); + let nmbrs = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten']; + return arr.sort(function (a, b) { + if (nmbrs.indexOf(a) < nmbrs.indexOf(b)) { + return -1; + } + + if (nmbrs.indexOf(a) > nmbrs.indexOf(b)) { + return 1; + } + + if (nmbrs.indexOf(a) === nmbrs.indexOf(b)) { + return 0; + } + }); } /** @@ -337,14 +354,14 @@ function sortDigitNamesByNumericOrder(arr) { * [ 1, 10, 100, 1000 ] => 1111 */ function getItemsSum(arr) { - throw new Error('Not implemented'); + return arr.reduce(((accum, value) => accum + value), 0); } /** * Returns the number of all falsy value in the specified array * * @param {array} arr - * @return {array} + * @return {number} * * @example * [] => 0 @@ -353,7 +370,7 @@ function getItemsSum(arr) { * [ null, undefined, NaN, false, 0, '' ] => 6 */ function getFalsyValuesCount(arr) { - throw new Error('Not implemented'); + return (arr.filter(element => Boolean(element) === false)).length;; } /** @@ -371,7 +388,7 @@ function getFalsyValuesCount(arr) { * [ true, 0, 1, 'true' ], true => 1 */ function findAllOccurences(arr, item) { - throw new Error('Not implemented'); + return (arr.filter(element => element === item)).length; } /** @@ -386,7 +403,7 @@ function findAllOccurences(arr, item) { * ['rock', 'paper', 'scissors'] => 'rock,paper,scissors' */ function toStringList(arr) { - throw new Error('Not implemented'); + return arr.toString(); } @@ -415,7 +432,31 @@ function toStringList(arr) { * { country: 'Russia', city: 'Saint Petersburg' } */ function sortCitiesArray(arr) { - throw new Error('Not implemented'); + function compareLocation(a, b) { + if (a.country < b.country) { + return -1; + } + + if (a.country > b.country) { + return 1; + } + + if (a.country === b.country) { + if (a.city < b.city) { + return -1; + } + + if (a.city > b.city) { + return 1; + } + + if (a.city === b.city) { + return 0; + } + } + } + + return arr.sort(compareLocation); } /** @@ -437,7 +478,11 @@ function sortCitiesArray(arr) { * [0,0,0,0,1]] */ function getIdentityMatrix(n) { - throw new Error('Not implemented'); + return Array(n).fill(0).map(function (elem, i) { + return Array(n).fill(0).map(function (elem2, j) { + return 1 - Math.min(Math.abs(i - j), 1); + }); + }); } /** @@ -454,7 +499,7 @@ function getIdentityMatrix(n) { * 3, 3 => [ 3 ] */ function getIntervalArray(start, end) { - throw new Error('Not implemented'); + return Array(end - start + 1).fill().map((_, idx) => start + idx); } /** @@ -469,7 +514,7 @@ function getIntervalArray(start, end) { * [ 1, 1, 2, 2, 3, 3, 4, 4] => [ 1, 2, 3, 4] */ function distinct(arr) { - throw new Error('Not implemented'); + return arr.filter((v, i, a) => a.indexOf(v) === i); } /** @@ -503,7 +548,9 @@ function distinct(arr) { * } */ function group(array, keySelector, valueSelector) { - throw new Error('Not implemented'); + return new Map(array.map(function (item, index, arr) { + return [keySelector(item), arr.filter(x => keySelector(x) === keySelector(item)).map(x => valueSelector(x))]; + })); } @@ -519,7 +566,7 @@ function group(array, keySelector, valueSelector) { * ['one','two','three'], x=>x.split('') => ['o','n','e','t','w','o','t','h','r','e','e'] */ function selectMany(arr, childrenSelector) { - throw new Error('Not implemented'); + return [].concat(...arr.map(childrenSelector)); } @@ -536,7 +583,9 @@ function selectMany(arr, childrenSelector) { * [[[ 1, 2, 3]]], [ 0, 0, 1 ] => 2 (arr[0][0][1]) */ function getElementByIndexes(arr, indexes) { - throw new Error('Not implemented'); + return indexes.reduce((newArr, indexValue) => { + return newArr[indexValue] + }, arr); } @@ -559,7 +608,17 @@ function getElementByIndexes(arr, indexes) { * */ function swapHeadAndTail(arr) { - throw new Error('Not implemented'); + if (arr.length === 1 || arr.length === 0) { + return arr; + } + + var head = arr.slice(0, arr.length / 2); + var tail = arr.slice(Math.ceil(arr.length / 2)); + if (arr.length % 2 === 0) { + return tail.concat(head); + } else { + return tail.concat(arr[Math.floor(arr.length / 2)], head); + } } From 2be91e6f66a88b2e64d9e5c250be773545b21715 Mon Sep 17 00:00:00 2001 From: AndreiHarbunou Date: Tue, 4 Jun 2024 16:51:59 +0300 Subject: [PATCH 05/12] 05-regex-tasks --- task/05-regex-tasks.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/task/05-regex-tasks.js b/task/05-regex-tasks.js index b1c60f2d4..2c1befd66 100644 --- a/task/05-regex-tasks.js +++ b/task/05-regex-tasks.js @@ -31,7 +31,7 @@ * @return {RegExp} */ function getRegexForGuid() { - throw new Error('Not implemented'); + return /{[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}}/; } @@ -53,7 +53,7 @@ function getRegexForGuid() { * */ function getRegexForPitSpot() { - throw new Error('Not implemented'); + return /.*p.t.*/; } @@ -72,7 +72,7 @@ function getRegexForPitSpot() { * @return {RegExp} */ function getRegexForIPv4() { - throw new Error('Not implemented'); + return /^([0-1]?\d?\d\.|2[0-5]\d\.){3}([0-1]?\d?\d|2[0-5]\d)$/; } @@ -91,7 +91,7 @@ function getRegexForIPv4() { * @return {RegExp} */ function getRegexForSSN() { - throw new Error('Not implemented'); + return /^(?!0{3})\d{3}-(?!00)\d{2}-(?!0{4})\d{4}$/; } @@ -105,7 +105,7 @@ function getRegexForSSN() { * - Valid passwords will only be alphanumeric characters. * * @param {number} minLength - * @return {Regex} + * @return {RegExp} * * @example * let validator = getPasswordValidator(6); @@ -116,7 +116,7 @@ function getRegexForSSN() { * 'Pa55'.match(validator) => false */ function getPasswordValidator(minLength) { - throw new Error('Not implemented'); + return new RegExp("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)[a-zA-Z\\d]{" + minLength + ",}$"); } From a23c5ecbfeb10d021f14a1c78d0949956a712d0c Mon Sep 17 00:00:00 2001 From: AndreiHarbunou Date: Tue, 4 Jun 2024 17:24:02 +0300 Subject: [PATCH 06/12] 06-conditions-n-loops-tasks --- task/06-conditions-n-loops-tasks.js | 204 +++++++++++++++++++++++++--- 1 file changed, 183 insertions(+), 21 deletions(-) diff --git a/task/06-conditions-n-loops-tasks.js b/task/06-conditions-n-loops-tasks.js index 249194c34..cd41c8e07 100644 --- a/task/06-conditions-n-loops-tasks.js +++ b/task/06-conditions-n-loops-tasks.js @@ -30,7 +30,7 @@ * */ function getFizzBuzz(num) { - throw new Error('Not implemented'); + return [num, 'Fizz', 'Buzz', 'FizzBuzz'][!(num % 3) + (!(num % 5) << 1)]; } @@ -46,7 +46,11 @@ function getFizzBuzz(num) { * 10 => 3628800 */ function getFactorial(n) { - throw new Error('Not implemented'); + let res = 1; + for (let i = 1; i <= n; i++) { + res *= i; + } + return res } @@ -63,7 +67,11 @@ function getFactorial(n) { * -1,1 => 0 ( = -1 + 0 + 1 ) */ function getSumBetweenNumbers(n1, n2) { - throw new Error('Not implemented'); + let res = 0; + for (let i = n1; i <= n2; i++) { + res += i; + } + return res; } @@ -73,7 +81,7 @@ function getSumBetweenNumbers(n1, n2) { * @param {number} a * @param {number} b * @param {number} c - * @return {bool} + * @return {boolean} * * @example: * 1,2,3 => false @@ -82,7 +90,8 @@ function getSumBetweenNumbers(n1, n2) { * 10,10,10 => true */ function isTriangle(a,b,c) { - throw new Error('Not implemented'); + let sides = [a, b, c].sort((a, b) => b - a); + return sides[0] < sides[1] + sides[2]; } @@ -108,7 +117,7 @@ function isTriangle(a,b,c) { * * @param {object} rect1 * @param {object} rect2 - * @return {bool} + * @return {boolean} * * @example: * { top: 0, left: 0, width: 10, height: 10 }, @@ -119,7 +128,10 @@ function isTriangle(a,b,c) { * */ function doRectanglesOverlap(rect1, rect2) { - throw new Error('Not implemented'); + return ((rect2.top >= rect1.top) && (rect2.top <= (rect1.top + rect1.width)) + && (rect2.left >= rect1.left) && (rect2.left <= (rect1.left + rect1.height))) + || ((rect1.top >= rect2.top) && (rect1.top <= (rect2.top + rect2.width)) + && (rect1.left >= rect2.left) && (rect1.left <= (rect2.left + rect2.height))); } @@ -142,7 +154,7 @@ function doRectanglesOverlap(rect1, rect2) { * * @param {object} circle * @param {object} point - * @return {bool} + * @return {boolean} * * @example: * { center: { x:0, y:0 }, radius:10 }, { x:0, y:0 } => true @@ -150,7 +162,7 @@ function doRectanglesOverlap(rect1, rect2) { * */ function isInsideCircle(circle, point) { - throw new Error('Not implemented'); + return Math.pow(point.x - circle.center.x, 2) + Math.pow(point.y - circle.center.y, 2) < circle.radius * circle.radius; } @@ -166,7 +178,11 @@ function isInsideCircle(circle, point) { * 'entente' => null */ function findFirstSingleChar(str) { - throw new Error('Not implemented'); + for (let i = 0; i < Math.round(str.length / 2); i++) { + if (str.slice(i + 1).indexOf(str[i]) === -1) { + return str[i]; + } + } } @@ -192,7 +208,11 @@ function findFirstSingleChar(str) { * */ function getIntervalString(a, b, isStartIncluded, isEndIncluded) { - throw new Error('Not implemented'); + let res = ""; + res += (isStartIncluded && res.length === 0) ? "[" : "("; + res += a <= b ? `${a}, ${b}` : `${b}, ${a}`; + res += isEndIncluded ? "]" : ")"; + return res; } @@ -209,7 +229,7 @@ function getIntervalString(a, b, isStartIncluded, isEndIncluded) { * 'noon' => 'noon' */ function reverseString(str) { - throw new Error('Not implemented'); + return str.split("").reverse().join(""); } @@ -226,7 +246,7 @@ function reverseString(str) { * 34143 => 34143 */ function reverseInteger(num) { - throw new Error('Not implemented'); + return Number.parseInt(reverseString(num.toString())); } @@ -251,7 +271,20 @@ function reverseInteger(num) { * 4916123456789012 => false */ function isCreditCardNumber(ccn) { - throw new Error('Not implemented'); + let sum = 0; + let Num = ccn.toString(); + let len = Num.length; + for (let i = 1; i <= len; i++) { + let p = Number(Num[len - i]); + if (i % 2 === 0) { + p *= 2; + } + if (p > 9) { + p -= 9; + } + sum += p; + } + return sum % 10 === 0; } @@ -270,7 +303,10 @@ function isCreditCardNumber(ccn) { * 165536 (1+6+5+5+3+6 = 26, 2+6 = 8) => 8 */ function getDigitalRoot(num) { - throw new Error('Not implemented'); + let sum = ('' + num).split("").reduce((prev, cur) => { + return (+prev) + (+cur); + }); + return sum > 9 ? getDigitalRoot(sum) : sum; } @@ -295,8 +331,34 @@ function getDigitalRoot(num) { * '{)' = false * '{[(<{[]}>)]}' = true */ +function bracketPairs(brackets) { + switch (brackets) { + case ']': return '['; + case ')': return '('; + case '}': return '{'; + case '>': return '<'; + } +} function isBracketsBalanced(str) { - throw new Error('Not implemented'); + let endBrackets = [']', ')', '}', '>']; + let startBrackets = ['[', '(', '{', '<']; + str = str.split(''); + let stack = []; + for (let i = 0; i < str.length; i++) { + if (startBrackets.includes(str[i])) { + stack.push(str[i]); + } else { + if (endBrackets.includes(str[i])) { + if (stack.length === 0) { + return false; + } + if (stack[stack.length - 1] === bracketPairs(str[i])) { + stack.pop(); + } + } + } + } + return stack.length === 0; } @@ -332,7 +394,42 @@ function isBracketsBalanced(str) { * */ function timespanToHumanString(startDate, endDate) { - throw new Error('Not implemented'); + const diff = endDate.getTime() - startDate.getTime(), + sec = 1000, + min = 60 * sec, + hour = 60 * min, + day = 24 * hour, + month = 30 * day, + year = 365 * day; + + if (diff <= 45 * sec) { + return 'a few seconds ago'; + } else if (diff <= 90 * sec) { + return 'a minute ago'; + } else if (diff <= 45 * min) { + return genString(min, 'minutes'); + } else if (diff <= 90 * min) { + return 'an hour ago'; + } else if (diff <= 22 * hour) { + return genString(hour, 'hours'); + } else if (diff <= 36 * hour) { + return 'a day ago'; + } else if (diff <= 25 * day) { + return genString(day, 'days'); + } else if (diff <= 45 * day) { + return 'a month ago'; + } else if (diff <= 345 * day) { + return genString(month, 'months'); + } else if (diff <= 545 * day) { + return 'a year ago'; + } else { + return genString(year, 'years'); + } + + function genString(period, periodStr) { + const diffPeriod = Math.floor(diff / period) + ((diff % period > period / 2) && 1); + return `${diffPeriod} ${periodStr} ago`; + } } @@ -356,7 +453,7 @@ function timespanToHumanString(startDate, endDate) { * 365, 10 => '365' */ function toNaryString(num, n) { - throw new Error('Not implemented'); + return num.toString(n); } @@ -373,7 +470,27 @@ function toNaryString(num, n) { * ['/web/favicon.ico', '/web-scripts/dump', '/webalizer/logs'] => '/' */ function getCommonDirectoryPath(pathes) { - throw new Error('Not implemented'); + let resstr = ''; + let posSlash = -1; + let strCommon = ''; + let flag = false; + while (!flag) { + posSlash = pathes[0].indexOf('/', posSlash + 1); + if (posSlash === -1) { + break; + } + strCommon = pathes[0].slice(0, posSlash + 1); + for (let i = 1; i < pathes.length; i++) { + if (pathes[i].indexOf(strCommon) !== 0) { + flag = true; + break; + } + } + if (!flag) { + resstr = strCommon; + } + } + return resstr; } @@ -396,7 +513,22 @@ function getCommonDirectoryPath(pathes) { * */ function getMatrixProduct(m1, m2) { - throw new Error('Not implemented'); + let result = Array.from({ + length: m1.length + }, + el => Array.from({ + length: m2[0].length + }, () => 0)); + + for (let i = 0; i < result.length; i++) { // result rows + for (let j = 0; j < result[i].length; j++) { // result colls + for (let k = 0; k < m1[0].length; k++) { // m1 colls + result[i][j] += m1[i][k] * m2[k][j]; + } + } + } + + return result; } @@ -431,7 +563,37 @@ function getMatrixProduct(m1, m2) { * */ function evaluateTicTacToePosition(position) { - throw new Error('Not implemented'); + // diagonal + let d1 = position.map((el, i) => el[i]), + d2 = position.map((el, i) => el[2 - i]); + + if (checkLine(d1)) { + return d1[0]; + } + if (checkLine(d2)) { + return d2[0]; + } + + for (let i = 0; i < 3; i++) { + let row = position[i], + col = position.map(el => el[i]); + + // horizontal + if (checkLine(row)) { + return row[0]; + } + + // vertical + if (checkLine(col)) { + return col[0]; + } + } + + function checkLine(arr) { + arr.length = 3; + + return Array.from(new Set(arr)).length === 1 && arr[0]; + } } From 31ecb4e0e813aa7675ff78fc75f7ce4577943df5 Mon Sep 17 00:00:00 2001 From: AndreiHarbunou Date: Tue, 4 Jun 2024 17:31:46 +0300 Subject: [PATCH 07/12] 07-yield-tasks --- task/07-yield-tasks.js | 55 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/task/07-yield-tasks.js b/task/07-yield-tasks.js index a2369790a..0db64a2c9 100644 --- a/task/07-yield-tasks.js +++ b/task/07-yield-tasks.js @@ -33,7 +33,14 @@ * */ function* get99BottlesOfBeer() { - throw new Error('Not implemented'); + let bottle = (n => n === 1 ? `1 bottle` : `${n} bottles`); + for (let i = 99; i > 0; i--) { + yield `${bottle(i)} of beer on the wall, ${bottle(i)} of beer.`; + if (i > 1) yield `Take one down and pass it around, ${bottle(i - 1)} of beer on the wall.`; + else yield `Take one down and pass it around, no more bottles of beer on the wall.`; + } + yield 'No more bottles of beer on the wall, no more bottles of beer.'; + yield 'Go to the store and buy some more, 99 bottles of beer on the wall.'; } @@ -47,7 +54,13 @@ function* get99BottlesOfBeer() { * */ function* getFibonacciSequence() { - throw new Error('Not implemented'); + let a, b, c; + yield a = 0; + yield b = 1; + while (true) { + yield c = a + b; + a = b; b = c; + } } @@ -82,7 +95,14 @@ function* getFibonacciSequence() { * */ function* depthTraversalTree(root) { - throw new Error('Not implemented'); + let q1 = [root]; + while (q1.length) { + let node = q1.pop(); + yield node; + if (node.children) { + q1.push(...node.children.reverse()); + } + } } @@ -108,7 +128,13 @@ function* depthTraversalTree(root) { * */ function* breadthTraversalTree(root) { - throw new Error('Not implemented'); + let q1 = [root]; + for (let node of q1) { + yield node; + if (node.children) { + q1.push(...node.children); + } + } } @@ -126,7 +152,26 @@ function* breadthTraversalTree(root) { * [ 1, 3, 5, ... ], [ -1 ] => [ -1, 1, 3, 5, ...] */ function* mergeSortedSequences(source1, source2) { - throw new Error('Not implemented'); + const firstSeq = source1(), + secondSeq = source2(); + + let first = firstSeq.next(), + second = secondSeq.next(); + + while (true) { + if (first.done || first.value > second.value) { + if (second.done) { + break; + } + + yield second.value; + second = secondSeq.next(); + continue; + } + + yield first.value; + first = firstSeq.next(); + } } From e8d5c9ebf68ec1b8b0ae716c3c41bbd2155ad7b6 Mon Sep 17 00:00:00 2001 From: AndreiHarbunou Date: Tue, 4 Jun 2024 18:02:50 +0300 Subject: [PATCH 08/12] 08-objects-tasks --- task/08-objects-tasks.js | 122 +++++++++++++++++++++++++++++++++++---- 1 file changed, 112 insertions(+), 10 deletions(-) diff --git a/task/08-objects-tasks.js b/task/08-objects-tasks.js index 610b1e7b2..4b53d3428 100644 --- a/task/08-objects-tasks.js +++ b/task/08-objects-tasks.js @@ -23,7 +23,12 @@ * console.log(r.getArea()); // => 200 */ function Rectangle(width, height) { - throw new Error('Not implemented'); + this.width = width; + this.height = height; +} + +Rectangle.prototype.getArea = function () { + return this.width * this.height; } @@ -38,7 +43,7 @@ function Rectangle(width, height) { * { width: 10, height : 20 } => '{"height":10,"width":20}' */ function getJSON(obj) { - throw new Error('Not implemented'); + return JSON.stringify(obj); } @@ -54,7 +59,7 @@ function getJSON(obj) { * */ function fromJSON(proto, json) { - throw new Error('Not implemented'); + return Object.setPrototypeOf(JSON.parse(json), proto); } @@ -105,35 +110,132 @@ function fromJSON(proto, json) { * * For more examples see unit tests. */ +let id = { + element: 0, + id: 1, + class: 2, + attr: 3, + pseudoClass: 4, + pseudoElement: 5 +} +class Selector { + constructor(selector) { + this.selector = selector; + this.counter = { + element: 0, + id: 0, + pseudoElement: 0 + } + this.prev_id = -1; + this.cur_id = -1; + } + + check() { + if (this.counter.element === 2 || + this.counter.id === 2 || + this.counter.pseudoElement === 2) { + throw new Error('Element, id and pseudo-element should not occur ' + + 'more then one time inside the selector'); + } + if (this.cur_id < this.prev_id) { + throw new Error('Selector parts should be arranged in the following ' + + 'order: element, id, class, attribute, pseudo-class, pseudo-element'); + } + this.prev_id = this.cur_id; + } + + element(value) { + this.cur_id = id.element; + this.counter.element++; + this.check(); + this.selector += value; + return this; + } + + id(value) { + this.cur_id = id.id; + this.counter.id++; + this.check(); + this.selector += '#' + value; + return this; + } + + class(value) { + this.cur_id = id.class; + this.check(); + this.selector += '.' + value; + return this; + } + + attr(value) { + this.cur_id = id.attr; + this.check(); + this.selector += '[' + value + ']'; + return this; + } + + pseudoClass(value) { + this.cur_id = id.pseudoClass; + this.check(); + this.selector += ':' + value; + return this; + } + + pseudoElement(value) { + this.cur_id = id.pseudoElement; + this.counter.pseudoElement++; + this.check(); + this.selector += '::' + value; + return this; + } + + combine(selector1, combinator, selector2) { + return new Selector(selector1.selector + ' ' + combinator + ' ' + selector2); + } + + stringify() { + return this.selector; + } +} const cssSelectorBuilder = { element: function(value) { - throw new Error('Not implemented'); + let obj = new Selector(''); + return obj.element(value); }, id: function(value) { - throw new Error('Not implemented'); + let obj = new Selector(''); + return obj.id(value); }, class: function(value) { - throw new Error('Not implemented'); + let obj = new Selector(''); + return obj.class(value); }, attr: function(value) { - throw new Error('Not implemented'); + let obj = new Selector(''); + return obj.attr(value); }, pseudoClass: function(value) { - throw new Error('Not implemented'); + let obj = new Selector(''); + return obj.pseudoClass(value); }, pseudoElement: function(value) { - throw new Error('Not implemented'); + let obj = new Selector(''); + return obj.pseudoElement(value); }, combine: function(selector1, combinator, selector2) { - throw new Error('Not implemented'); + return new Selector( + selector1.stringify() + + ' ' + combinator + ' ' + + selector2.stringify() + ); }, }; From 6f74357c2d6de08c9abfa9ebc36e7ab5e2137b2e Mon Sep 17 00:00:00 2001 From: AndreiHarbunou Date: Tue, 4 Jun 2024 18:15:57 +0300 Subject: [PATCH 09/12] 09-functions-n-clousers-tasks --- task/09-functions-n-closures-tasks.js | 41 +++++++++++++++++++++------ 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/task/09-functions-n-closures-tasks.js b/task/09-functions-n-closures-tasks.js index 6ba9dcedd..21bfeb507 100644 --- a/task/09-functions-n-closures-tasks.js +++ b/task/09-functions-n-closures-tasks.js @@ -26,7 +26,7 @@ * */ function getComposition(f,g) { - throw new Error('Not implemented'); + return x => f(g(x)); } @@ -47,7 +47,7 @@ function getComposition(f,g) { * */ function getPowerFunction(exponent) { - throw new Error('Not implemented'); + return x => Math.pow(x, exponent); } @@ -65,7 +65,13 @@ function getPowerFunction(exponent) { * getPolynom() => null */ function getPolynom() { - throw new Error('Not implemented'); + let k = Array.from(arguments).reverse(); + return function (x) { + let l = k.length; + if (l === 0) return null; + let _x = 1; + return k.reduce((p, e, i) => p + e * (_x *= x)); + } } @@ -84,7 +90,8 @@ function getPolynom() { * memoizer() => the same random number (next run, returns the previous cached result) */ function memoize(func) { - throw new Error('Not implemented'); + let memo = func(); + return () => memo; } @@ -104,7 +111,16 @@ function memoize(func) { * retryer() => 2 */ function retry(func, attempts) { - throw new Error('Not implemented'); + return () => { + var cnt = attempts; + while (cnt > 0) { + try { + return func(); + } catch (e) { + cnt--; + } + } + } } @@ -132,7 +148,13 @@ function retry(func, attempts) { * */ function logger(func, logFunc) { - throw new Error('Not implemented'); + return function () { + var str = func.name + '(' + JSON.stringify([...arguments]).slice(1, -1) + ')'; + logFunc(str + ' starts'); + let ans = func(...arguments); + logFunc(str + ' ends'); + return ans; + } } @@ -150,7 +172,10 @@ function logger(func, logFunc) { * partialUsingArguments(fn, 'a','b','c','d')() => 'abcd' */ function partialUsingArguments(fn) { - throw new Error('Not implemented'); + var arg = [...arguments].slice(1); + return function () { + return fn(...arg, ...arguments) + }; } @@ -171,7 +196,7 @@ function partialUsingArguments(fn) { * getId10() => 11 */ function getIdGeneratorFunction(startFrom) { - throw new Error('Not implemented'); + return () => startFrom++; } From 9d80309be13953db728464f8cc7b701af409193b Mon Sep 17 00:00:00 2001 From: AndreiHarbunou Date: Tue, 4 Jun 2024 18:22:01 +0300 Subject: [PATCH 10/12] 10-katas-1-tasks --- task/10-katas-1-tasks.js | 137 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 129 insertions(+), 8 deletions(-) diff --git a/task/10-katas-1-tasks.js b/task/10-katas-1-tasks.js index 5128b0695..48ed2da06 100644 --- a/task/10-katas-1-tasks.js +++ b/task/10-katas-1-tasks.js @@ -17,8 +17,31 @@ * ] */ function createCompassPoints() { - throw new Error('Not implemented'); - var sides = ['N','E','S','W']; // use array of cardinal directions only! + function transform(arr, func) { + let trn = arr.map(func); + let ans = []; + arr.forEach((e, i) => ans.push(e, trn[i])); + return ans; + } + + let sides = ['N', 'E', 'S', 'W']; // use array of cardinal directions only! + // get N, NE, E, .... + sides = transform(sides, (e, i, arr) => { + if (i % 2 === 0) return arr[i] + arr[i + 1]; + else return arr[(i + 1) % 4] + arr[i]; + }); + // get N, NNE, NE, .... + sides = transform(sides, (e, i, arr) => { + if (i % 2 === 0) return arr[i] + arr[i + 1]; + else return arr[(i + 1) % 8] + arr[i]; + }); + // get N, NbE, NNE, ... + sides = transform(sides, (e, i, arr) => { + if (i % 2 === 0) return arr[i] + 'b' + arr[(i + 4 - i % 4) % 16]; + else return arr[(i + 1) % 16] + 'b' + arr[i - i % 4]; + }); + const dAngle = 360 / sides.length; + return sides.map((e, i) => ({ 'abbreviation': e, 'azimuth': i * dAngle })); } @@ -55,8 +78,61 @@ function createCompassPoints() { * * 'nothing to do' => 'nothing to do' */ +class Node { + constructor(str) { + this.str = str || ''; + this.children = []; + } +} + +function createDigraph(head, str) { + let cur = head; + let headStack = [], tailStack = []; + for (let c of str) { + if (c === '{') { + let _head = new Node(); + let _tail = new Node(); + headStack.push(_head); + tailStack.push(_tail); + cur.children.push(_head); + cur = _head; + } else if (c === '}') { + let _root = headStack.pop(); + let _tail = tailStack.pop(); + cur.children.push(_tail); + cur = _tail; + } else if (c === ',' && headStack.length) { + let _root = headStack.slice(-1)[0]; + let _tail = tailStack.slice(-1)[0]; + cur.children.push(_tail); + cur = _root; + } else { + let node = new Node(c); + cur.children.push(node); + cur = node; + } + } +} function* expandBraces(str) { - throw new Error('Not implemented'); + let head = new Node(); + createDigraph(head, str); + + let q = [head], ans = []; + while (q.length) { + let node = q.slice(-1)[0]; + if (node.used) { + node.used = false; + q.pop(); + ans.pop(); + } else { + node.used = true; + q.push(...node.children); + ans.push(node.str); + if (!node.children.length) { + yield ans.join(''); + } + } + } } @@ -88,7 +164,15 @@ function* expandBraces(str) { * */ function getZigZagMatrix(n) { - throw new Error('Not implemented'); + let ans = Array.from({ 'length': n }, () => new Array(n)); + let v = 0; + for (let i = 0; i < 2 * n - 1; i++) + for (let j = 0; j < n; j++) { + let y = (i % 2 === 0 ? j : n - 1 - j), + x = i - y; + if (x >= 0 && x < n) ans[x][y] = v++; + } + return ans; } @@ -102,7 +186,7 @@ function getZigZagMatrix(n) { * NOTE that as in usual dominoes playing any pair [i, j] can also be treated as [j, i]. * * @params {array} dominoes - * @return {bool} + * @return {boolean} * * @example * @@ -113,7 +197,35 @@ function getZigZagMatrix(n) { * */ function canDominoesMakeRow(dominoes) { - throw new Error('Not implemented'); + let adjMatrix = Array.from({ length: 7 }, () => new Array(7).fill(0)); + for (let e of dominoes) { + adjMatrix[e[0]][e[1]]++; + adjMatrix[e[1]][e[0]]++; + } + + let degrees = adjMatrix.map(e => e.reduce((p, e) => p + e)); + let odds = degrees.reduce((p, e, i) => { + if (e % 2) p.push(i); + return p; + }, []); + if (odds.length > 2) return false; + + let start = (odds.length ? odds[0] : degrees.findIndex(e => e > 0)); + let stack = [start]; + while (stack.length) { + let from = stack.slice(-1)[0]; + if (degrees[from] === 0) { + stack.pop(); + } else { + let to = adjMatrix[from].findIndex(e => e); + adjMatrix[from][to]--; + adjMatrix[to][from]--; + degrees[from]--; + degrees[to]--; + stack.push(to); + } + } + return degrees.reduce((p, e) => p + e) === 0; } @@ -127,7 +239,7 @@ function canDominoesMakeRow(dominoes) { * The range syntax is to be used only for, and for every range that expands to more than two values. * * @params {array} nums - * @return {bool} + * @return {string} * * @example * @@ -137,7 +249,16 @@ function canDominoesMakeRow(dominoes) { * [ 1, 2, 4, 5] => '1,2,4,5' */ function extractRanges(nums) { - throw new Error('Not implemented'); + return nums.reduce((p, e, i) => { + if (p.end === e - 1) p.end = e; + if (p.end !== e || i === nums.length - 1) { + p.str += (p.begin === p.end) ? `,${p.begin}` : + (p.begin === p.end - 1) ? `,${p.begin},${p.end}` : + `,${p.begin}-${p.end}`; + p.begin = p.end = e; + } + return p; + }, { str: '', begin: NaN, end: NaN }).str.slice(9); } module.exports = { From 7035f761a4463c569a0160a01cd24738f3d48628 Mon Sep 17 00:00:00 2001 From: AndreiHarbunou Date: Tue, 4 Jun 2024 18:30:16 +0300 Subject: [PATCH 11/12] 11-katas-2-tasks --- task/11-katas-2-tasks.js | 79 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 4 deletions(-) diff --git a/task/11-katas-2-tasks.js b/task/11-katas-2-tasks.js index 2a1a745cd..287889fda 100644 --- a/task/11-katas-2-tasks.js +++ b/task/11-katas-2-tasks.js @@ -34,7 +34,21 @@ * */ function parseBankAccount(bankAccount) { - throw new Error('Not implemented'); + function transform(str) { + let ans = ''; + let lines = str.split('\n').slice(0, -1); + for (let j = 0; j < lines[0].length; j++) + for (let i = 0; i < lines.length; i++) { + ans += lines[i][j]; + } + return ans.match(/.{1,9}/g); + } + + let digits = ' _ _ _ _ _ _ _ _ \n' + + '| | | _| _||_||_ |_ ||_||_|\n' + + '|_| ||_ _| | _||_| ||_| _|\n'; + let map = new Map(transform(digits).map((e, i) => [e, i])); + return transform(bankAccount).reduce((p, e) => p * 10 + map.get(e), 0); } @@ -63,7 +77,10 @@ function parseBankAccount(bankAccount) { * 'characters.' */ function* wrapText(text, columns) { - throw new Error('Not implemented'); + let lines = text.match(new RegExp(`.{1,${columns}}( |$)`, 'g')); + for (let line of lines) { + yield line.trim(); + } } @@ -100,7 +117,28 @@ const PokerRank = { } function getPokerHandRank(hand) { - throw new Error('Not implemented'); + const suites = '♥♠♦♣', + numbers = 'A234567891JQK'; + let suitArr = Array.from(suites, () => 0), + numArr = Array.from(numbers, () => 0); + for (let card of hand) { + suitArr[suites.indexOf(card.slice(-1))]++; + numArr[numbers.indexOf(card[0])]++; + } + numArr.push(numArr[0]); // Ace card + let suitStr = suitArr.join(''), + numStr = numArr.join(''); + return (numStr.indexOf('11111') !== -1) && + (suitStr.indexOf('5') !== -1) ? PokerRank.StraightFlush : + (numStr.indexOf('4') !== -1) ? PokerRank.FourOfKind : + (numStr.indexOf('2') !== -1) && + (numStr.indexOf('3') !== -1) ? PokerRank.FullHouse : + (suitStr.indexOf('5') !== -1) ? PokerRank.Flush : + (numStr.indexOf('11111') !== -1) ? PokerRank.Straight : + (numStr.indexOf('3') !== -1) ? PokerRank.ThreeOfKind : + (numStr.match(/2.*2.+/)) ? PokerRank.TwoPairs : + (numStr.indexOf('2') !== -1) ? PokerRank.OnePair : + PokerRank.HighCard; } @@ -135,7 +173,40 @@ function getPokerHandRank(hand) { * '+-------------+\n' */ function* getFigureRectangles(figure) { - throw new Error('Not implemented'); + const lines = figure.split('\n').slice(0, -1), + dx = [0, 1, 0, -1, 0], + dy = [1, 0, -1, 0, 1], + reg = /[+|\-]/; + + function getRectangle(h, w) { + const edgeLine = '+' + '-'.repeat(w - 2) + '+\n', + midLine = '|' + ' '.repeat(w - 2) + '|\n'; + return edgeLine + midLine.repeat(h - 2) + edgeLine; + } + + function getSizes(x0, y0) { + let x = x0, y = y0, ind = -1; + let w = 1, h = 1; + while (1) { + let _x = x + dx[ind + 1]; + let _y = y + dy[ind + 1]; + if (lines[_x] && lines[_x][_y] && lines[_x][_y].match(reg)) ind++; + if (ind === -1 || ind === 4) return; + x += dx[ind]; + y += dy[ind]; + h = Math.max(h, x + 1 - x0); + w = Math.max(w, y + 1 - y0); + if (x === x0 && y === y0) return { h, w }; + if (!lines[x] || !lines[x][y] || !lines[x][y].match(reg)) return; + } + } + + for (let x = 0; x < lines.length; x++) + for (let y = 0; y < lines[0].length; y++) { + if (lines[x][y] !== '+') continue; + let sizes = getSizes(x, y); + if (sizes) yield getRectangle(sizes.h, sizes.w); + } } From ab8ffb22d9b708e498eb8840fdfc18f40887c695 Mon Sep 17 00:00:00 2001 From: AndreiHarbunou Date: Tue, 4 Jun 2024 18:39:13 +0300 Subject: [PATCH 12/12] 12-katas-3-tasks --- task/12-katas-3-tasks.js | 77 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 7 deletions(-) diff --git a/task/12-katas-3-tasks.js b/task/12-katas-3-tasks.js index 5299be87d..fa8347e70 100644 --- a/task/12-katas-3-tasks.js +++ b/task/12-katas-3-tasks.js @@ -28,7 +28,30 @@ * 'NULL' => false */ function findStringInSnakingPuzzle(puzzle, searchStr) { - throw new Error('Not implemented'); + function dfs(x, y, l) { //Depth first search + if (puzzle[x][y] !== searchStr[l]) return false; + if (l === searchStr.length - 1) return true; + used[x][y] = true; + for (let i = 0; i < 4; i++) { + let _x = x + dx[i], + _y = y + dy[i]; + if (!used[_x] || used[_x][_y]) continue; + if (dfs(_x, _y, l + 1)) return true; + } + return used[x][y] = false; //false + } + + let n = puzzle.length, + m = puzzle[0].length; + // out of recursion + let used = Array.from({ length: n }, () => new Array(m).fill(false)); + const dx = [-1, 1, 0, 0], + dy = [0, 0, -1, 1]; + for (let x = 0; x < n; x++) + for (let y = 0; y < m; y++) { + if (dfs(x, y, 0)) return true; + } + return false; } @@ -45,7 +68,29 @@ function findStringInSnakingPuzzle(puzzle, searchStr) { * 'abc' => 'abc','acb','bac','bca','cab','cba' */ function* getPermutations(chars) { - throw new Error('Not implemented'); + let arr = chars.split(''), + l = arr.length; + let swapElement = (a, b) => { + let tmp = arr[a]; + arr[a] = arr[b]; + arr[b] = tmp; + }; + arr.sort(); + while (1) { + yield arr.join(''); + let aInd = l - 2; + for (; aInd >= 0 && arr[aInd] > arr[aInd + 1]; aInd--) { + } + if (aInd === -1) return; + let bInd = l - 1; + for (; arr[bInd] < arr[aInd]; bInd--) { + } + swapElement(aInd, bInd); + let l2 = (l - aInd) >> 1; + for (let i = 1; i <= l2; i++) { + swapElement(aInd + i, l - i); + } + } } @@ -65,7 +110,11 @@ function* getPermutations(chars) { * [ 1, 6, 5, 10, 8, 7 ] => 18 (buy at 1,6,5 and sell all at 10) */ function getMostProfitFromStockQuotes(quotes) { - throw new Error('Not implemented'); + let max = +quotes.slice(-1); + return quotes.reverse().reduce((p, e) => { + max = Math.max(max, e); + return p + max - e; + }, 0); } @@ -91,12 +140,26 @@ function UrlShortener() { UrlShortener.prototype = { - encode: function(url) { - throw new Error('Not implemented'); + encode: function (url) { + let ans = ''; + let l = url.length; + for (let i = 1; i < l; i += 2) { + ans += String.fromCharCode( + url.charCodeAt(i - 1) + (url.charCodeAt(i) << 8) + ); + } + return (l % 2 ? ans + url[l - 1] : ans); }, - decode: function(code) { - throw new Error('Not implemented'); + decode: function (code) { + let ans = ''; + for (let i = 0; i < code.length; i++) { + ans += String.fromCharCode( + code.charCodeAt(i) & 0xff, + code.charCodeAt(i) >> 8 + ); + } + return (ans.slice(-1) === String.fromCharCode(0) ? ans.slice(0, -1) : ans); } }