From 53f2470283b81ced6688d0e716fa4259beae3621 Mon Sep 17 00:00:00 2001 From: birukov01 <154227459+birukov01@users.noreply.github.com> Date: Tue, 7 May 2024 15:01:59 +0300 Subject: [PATCH 01/13] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a81b5c08a..8e7cb4374 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ To start javascript assignments please follow the next steps: git commit -m "Update the links" git push origin master ``` -* Open https://github.com/rolling-scopes-school/js-assignments and test the build icon. Now it will run all tests and update status once you push changes to github. Keep this icon green! +* Open https://github.com/birukov01/js-assignments and test the build icon. Now it will run all tests and update status once you push changes to github. Keep this icon green! ### How to setup work environment From 9f4fe55e74166c7411f740a00732a0c2bf902bc0 Mon Sep 17 00:00:00 2001 From: birukov01 <154227459+birukov01@users.noreply.github.com> Date: Sat, 11 May 2024 17:29:53 +0300 Subject: [PATCH 02/13] Update 01-strings-tasks.js --- task/01-strings-tasks.js | 115 ++++++++++++++++++++++++++++++++++----- 1 file changed, 100 insertions(+), 15 deletions(-) diff --git a/task/01-strings-tasks.js b/task/01-strings-tasks.js index e28054657..ab8af63f9 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,10 @@ function getStringFromTemplate(firstName, lastName) { * 'Hello, Chuck Norris!' => 'Chuck Norris' */ function extractNameFromTemplate(value) { - throw new Error('Not implemented'); + let str = ''; + let i = value.indexOf(' ') + 1; + for (; value[i] != '!'; i++) str += value[i]; + return str; } @@ -84,7 +87,7 @@ function extractNameFromTemplate(value) { * 'cat' => 'c' */ function getFirstChar(value) { - throw new Error('Not implemented'); + return value[0]; } /** @@ -99,7 +102,17 @@ function getFirstChar(value) { * '\tHello, World! ' => 'Hello, World!' */ function removeLeadingAndTrailingWhitespaces(value) { - throw new Error('Not implemented'); + let str = ''; + let l = 0; + let t = value.length - 1; + while (value[l] == ' ' || value[l] == '\t') l++; + while (value[t] == ' ' || value[t] == '\t') t--; + while (l <= t) + { + str += value[l]; + l++; + } + return str; } /** @@ -114,7 +127,9 @@ function removeLeadingAndTrailingWhitespaces(value) { * 'cat', 3 => 'catcatcat' */ function repeatString(value, count) { - throw new Error('Not implemented'); + let str = ''; + for (let i = 0; i < count; i++) str += value; + return str; } /** @@ -130,7 +145,18 @@ function repeatString(value, count) { * 'ABABAB','BA' => 'ABAB' */ function removeFirstOccurrences(str, value) { - throw new Error('Not implemented'); + let strN = ''; + let posV = str.indexOf(value); + for (let i = 0; i < str.length; i++) + { + if (i == posV) + { + i += value.length; + if (str[posV - 1] == ' ' && str[i] == ' ') i++; + } + strN += str[i]; + } + return strN; } /** @@ -145,7 +171,11 @@ function removeFirstOccurrences(str, value) { * '' => 'a' */ function unbracketTag(str) { - throw new Error('Not implemented'); + let strN = ''; + for (let i = 0; i < str.length; i++) + if (str[i] != '<' && str[i] != '>') + strN += str[i]; + return strN; } @@ -160,7 +190,7 @@ function unbracketTag(str) { * 'abcdefghijklmnopqrstuvwxyz' => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' */ function convertToUpperCase(str) { - throw new Error('Not implemented'); + return str.toUpperCase(); } /** @@ -174,7 +204,21 @@ function convertToUpperCase(str) { * 'info@gmail.com' => ['info@gmail.com'] */ function extractEmails(str) { - throw new Error('Not implemented'); + let arr = []; + let iS = 0; + let iA = 0; + while (iS < str.length) + { + if (str[iS] == ';') iS++; + arr[iA] = ''; + while (str[iS] != ';' && iS < str.length) + { + arr[iA] += str[iS]; + iS++; + } + iA++; + } + return arr; } /** @@ -201,7 +245,20 @@ function extractEmails(str) { * */ function getRectangleString(width, height) { - throw new Error('Not implemented'); + let str = ''; + str += ' ┌'; + for (let i = 0; i < width - 2; i++) str += '─'; + str += '┐\n'; + for (let i = 0; i < height - 2; i++) + { + str += ' │'; + for (let i = 0; i < width - 2; i++) str += ' '; + str += '│\n'; + } + str += ' └'; + for (let i = 0; i < width - 2; i++) str += '─'; + str += '┘\n'; + return str; } @@ -221,7 +278,21 @@ function getRectangleString(width, height) { * */ function encodeToRot13(str) { - throw new Error('Not implemented'); + let strN = ''; + let a = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz'; + let p; + for (let i = 0; i < str.length; i++) + { + p = a.indexOf(str[i]); + if (p == -1) strN += str[i]; + else + { + p += 26; + if (p > 51) p -= 52; + strN += a[p]; + } + } + return strN; } /** @@ -238,7 +309,7 @@ function encodeToRot13(str) { * isString(new String('test')) => true */ function isString(value) { - throw new Error('Not implemented'); + return Object.prototype.toString.call(value) === "[object String]"; } @@ -267,7 +338,21 @@ function isString(value) { * 'K♠' => 51 */ function getCardId(value) { - throw new Error('Not implemented'); + let str1 = 'A23456789dJQK'; + let str2 = '♣♦♥♠'; + let p1; + let p2; + if (value[1] == '0') + { + p1 = str1.indexOf('d'); + p2 = str2.indexOf(value[2]); + } + else + { + p1 = str1.indexOf(value[0]); + p2 = str2.indexOf(value[1]); + } + return p2 * 13 + p1; } From 21ce4a0087a29a24a536dad6f6b894711bb6c645 Mon Sep 17 00:00:00 2001 From: birukov01 <154227459+birukov01@users.noreply.github.com> Date: Sat, 11 May 2024 19:13:34 +0300 Subject: [PATCH 03/13] Update 02-numbers-tasks.js --- task/02-numbers-tasks.js | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/task/02-numbers-tasks.js b/task/02-numbers-tasks.js index c9ed20208..623214127 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 + 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.pow(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2), 0.5); } /** @@ -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,9 @@ function getLinearEquationRoot(a, b) { * (0,1) (1,2) => 0 */ function getAngleBetweenVectors(x1, y1, x2, y2) { - throw new Error('Not implemented'); + var angle = Math.atan2(y2, x2) - Math.atan2(y1, x1) + if (angle < 0) angle += 2 * Math.PI; + return angle } /** @@ -127,7 +129,7 @@ function getAngleBetweenVectors(x1, y1, x2, y2) { * 0 => 0 */ function getLastDigit(value) { - throw new Error('Not implemented'); + return value%10; } @@ -143,7 +145,7 @@ function getLastDigit(value) { * '-525.5' => -525.5 */ function parseNumberFromString(value) { - throw new Error('Not implemented'); + return Number(value); } /** @@ -160,7 +162,7 @@ function parseNumberFromString(value) { * 1,2,3 => 3.741657386773941 */ function getParallelipidedDiagonal(a,b,c) { - throw new Error('Not implemented'); + return Math.pow(Math.pow(a,2) + Math.pow(b,2) + Math.pow(c,2), 0.5); } /** @@ -181,7 +183,9 @@ function getParallelipidedDiagonal(a,b,c) { * 1678, 3 => 2000 */ function roundToPowerOfTen(num, pow) { - throw new Error('Not implemented'); + let a = Math.pow(10, pow); + let b = Math.round(num / a); + return b*a; } /** @@ -202,7 +206,9 @@ function roundToPowerOfTen(num, pow) { * 17 => true */ function isPrime(n) { - throw new Error('Not implemented'); + for(let i = 2; i < n / 2 + 1; i++) + if (n % i == 0) return false; + return true; } /** @@ -221,7 +227,9 @@ function isPrime(n) { * toNumber(new Number(42), 0) => 42 */ function toNumber(value, def) { - throw new Error('Not implemented'); + const num = Number(value); + if(isNaN(num)) return def; + else return num; } module.exports = { From b0ff33a6a00061088f170ff8a73cf5fb33cc3d8c Mon Sep 17 00:00:00 2001 From: birukov01 <154227459+birukov01@users.noreply.github.com> Date: Sat, 11 May 2024 20:30:59 +0300 Subject: [PATCH 04/13] Update 03-date-tasks.js --- task/03-date-tasks.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/task/03-date-tasks.js b/task/03-date-tasks.js index 83c6266bc..f34ff8953 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 Date.parse(value); } /** @@ -37,7 +37,7 @@ function parseDataFromRfc2822(value) { * '2016-01-19T08:07:37Z' => Date() */ function parseDataFromIso8601(value) { - throw new Error('Not implemented'); + return Date.parse(value); } @@ -56,7 +56,8 @@ function parseDataFromIso8601(value) { * Date(2015,1,1) => false */ function isLeapYear(date) { - throw new Error('Not implemented'); + let year = date.getFullYear(); + return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0); } @@ -76,7 +77,7 @@ 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'); + return (new Date(endDate - startDate)).toISOString().slice(11, -1); } @@ -94,7 +95,11 @@ function timeSpanToString(startDate, endDate) { * Date.UTC(2016,3,5,21, 0) => Math.PI/2 */ function angleBetweenClockHands(date) { - throw new Error('Not implemented'); + const hoursArrow = 0.5 * (60 * (date.getUTCHours() % 12) + date.getUTCMinutes()); + const minutesArrow = 6 * date.getUTCMinutes(); + let angle = Math.abs(hoursArrow - minutesArrow); + if (angle > 180) angle = 360 - angle; + return (angle * Math.PI / 180); } From a0cc60b85413aaca5aa098836fe41bd621e47e26 Mon Sep 17 00:00:00 2001 From: birukov01 <154227459+birukov01@users.noreply.github.com> Date: Sun, 12 May 2024 19:24:17 +0300 Subject: [PATCH 05/13] Update 04-arrays-tasks.js --- task/04-arrays-tasks.js | 125 ++++++++++++++++++++++++++++------------ 1 file changed, 89 insertions(+), 36 deletions(-) diff --git a/task/04-arrays-tasks.js b/task/04-arrays-tasks.js index ff3a4c019..007c42653 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,12 @@ function findElement(arr, value) { * 5 => [ 1, 3, 5, 7, 9 ] */ function generateOdds(len) { - throw new Error('Not implemented'); + function iter(n, current, acc) + { + if (n == len) return acc; + return iter(n + 1, current + 2, acc.concat(current)) + } + return iter(0, 1, []); } @@ -54,7 +59,7 @@ function generateOdds(len) { * [] => [] */ function doubleArray(arr) { - throw new Error('Not implemented'); + return arr.concat(arr); } @@ -70,7 +75,7 @@ function doubleArray(arr) { * [] => [] */ function getArrayOfPositives(arr) { - throw new Error('Not implemented'); + return arr.filter(function(value){return value > 0;}); } /** @@ -85,7 +90,7 @@ function getArrayOfPositives(arr) { * [ 'cat, 'dog', 'raccon' ] => [ 'cat', 'dog', 'racoon' ] */ function getArrayOfStrings(arr) { - throw new Error('Not implemented'); + return arr.filter((x) => typeof(x) === 'string'); } /** @@ -102,7 +107,7 @@ function getArrayOfStrings(arr) { * [ false, 0, NaN, '', undefined ] => [ ] */ function removeFalsyValues(arr) { - throw new Error('Not implemented'); + return arr.filter(function(value){return Boolean(value);}); } /** @@ -116,7 +121,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(value => value.toUpperCase()); } @@ -131,7 +136,7 @@ function getUpperCaseStrings(arr) { * [ 'angular', 'react', 'ember' ] => [ 7, 5, 5 ] */ function getStringsLength(arr) { - throw new Error('Not implemented'); + return arr.map(value => value.length); } /** @@ -143,10 +148,11 @@ function getStringsLength(arr) { * * @example * [ 1, 3, 4, 5 ], 2, 1 => [ 1, 2, 3, 4, 5 ] - * [ 1, 'b', 'c'], 0, 'x' => [ 'x', 1, 'b', 'c' ] + * [ 1, 'b', 'c'], 'x', 0 => [ 'x', 1, 'b', 'c' ] */ function insertItem(arr, item, index) { - throw new Error('Not implemented'); + let arr1 = arr.splice(index, 0, item); + return arr; } /** @@ -156,11 +162,11 @@ function insertItem(arr, item, index) { * @param {number} n * * @example - * [ 1, 3, 4, 5 ], 2 => [ 1, 2 ] + * [ 1, 3, 4, 5 ], 2 => [ 1, 3 ] * [ 'a', 'b', 'c', 'd'], 3 => [ 'a', 'b', 'c' ] */ function getHead(arr, n) { - throw new Error('Not implemented'); + return arr.splice(0,n); } @@ -175,7 +181,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(Math.max(arr.length - n, 1)); } @@ -200,7 +206,7 @@ function getTail(arr, n) { * +'30,31,32,33,34' */ function toCsvText(arr) { - throw new Error('Not implemented'); + return arr.join('\n'); } /** @@ -215,7 +221,7 @@ function toCsvText(arr) { * [ 10, 100, -1 ] => [ 100, 10000, 1 ] */ function toArrayOfSquares(arr) { - throw new Error('Not implemented'); + return arr.map(value => value * value); } @@ -234,7 +240,7 @@ 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'); + return arr.map((x, y, arr) => arr.slice(0, y + 1).reduce((fs, val) => fs + val)); } /** @@ -249,7 +255,7 @@ function getMovingSum(arr) { * [ "a" ] => [] */ function getSecondItems(arr) { - throw new Error('Not implemented'); + return arr.filter((x, y) => y % 2 === 1); } @@ -268,7 +274,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'); + let newArray = []; + arr.map((x, y) => {newArray = newArray.concat(new Array(y + 1).fill(x)); return x;}); + return newArray; } @@ -286,9 +294,10 @@ function propagateItemsByPositionIndex(arr) { * [ 10, 10, 10, 10 ] => [ 10, 10, 10 ] */ function get3TopItems(arr) { - throw new Error('Not implemented'); + arr.sort(function(a, b){return b-a}); + return arr.slice(0,3); } - + /** * Returns the number of positive numbers from specified array @@ -304,9 +313,9 @@ function get3TopItems(arr) { * [ 1, '2' ] => 1 */ function getPositivesCount(arr) { - throw new Error('Not implemented'); + return arr.filter((x) => (x > 0) && (Number(x) === x)).length; } - + /** * Sorts digit names * @@ -321,7 +330,12 @@ function getPositivesCount(arr) { * [ 'one','one','one','zero' ] => [ 'zero','one','one','one' ] */ function sortDigitNamesByNumericOrder(arr) { - throw new Error('Not implemented'); + const digitsComparator = (a, b) => + { + const mapper = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine']; + return mapper.indexOf(a) - mapper.indexOf(b); + } + return arr.sort(digitsComparator); } /** @@ -337,9 +351,9 @@ function sortDigitNamesByNumericOrder(arr) { * [ 1, 10, 100, 1000 ] => 1111 */ function getItemsSum(arr) { - throw new Error('Not implemented'); + return arr.reduce((a, b) => a + b, 0); } - + /** * Returns the number of all falsy value in the specified array * @@ -353,7 +367,7 @@ function getItemsSum(arr) { * [ null, undefined, NaN, false, 0, '' ] => 6 */ function getFalsyValuesCount(arr) { - throw new Error('Not implemented'); + return arr.filter((x) => !x).length; } /** @@ -371,7 +385,7 @@ function getFalsyValuesCount(arr) { * [ true, 0, 1, 'true' ], true => 1 */ function findAllOccurences(arr, item) { - throw new Error('Not implemented'); + return arr.reduce(function(n, value){return n + (value === item);}, 0); } /** @@ -386,7 +400,7 @@ function findAllOccurences(arr, item) { * ['rock', 'paper', 'scissors'] => 'rock,paper,scissors' */ function toStringList(arr) { - throw new Error('Not implemented'); + return arr.join(','); } @@ -415,7 +429,13 @@ function toStringList(arr) { * { country: 'Russia', city: 'Saint Petersburg' } */ function sortCitiesArray(arr) { - throw new Error('Not implemented'); + return arr.sort((a, b) => + { + if (a.country > b.country) return 1; + if (a.country < b.country) return -1; + if (a.city > b.city)return 1; + return -1; + }); } /** @@ -437,7 +457,11 @@ function sortCitiesArray(arr) { * [0,0,0,0,1]] */ function getIdentityMatrix(n) { - throw new Error('Not implemented'); + return new Array(n).fill(0).map((x, y) => new Array(n).fill(0).map((x, y_) => + { + if (y === y_) return 1; + return 0; + })); } /** @@ -454,7 +478,7 @@ function getIdentityMatrix(n) { * 3, 3 => [ 3 ] */ function getIntervalArray(start, end) { - throw new Error('Not implemented'); + return Array(end - start + 1).fill().map((x, y) => start + y); } /** @@ -469,7 +493,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((x, y) => arr.indexOf(x) === y); } /** @@ -503,7 +527,19 @@ function distinct(arr) { * } */ function group(array, keySelector, valueSelector) { - throw new Error('Not implemented'); + const map = new Map(); + array.map((x) => [keySelector(x), valueSelector(x)]).map((x) => + { + if (map.has(x[0])) map.set(x[0], map.get(x[0]).concat(x[1])); + else + { + const arr = Array(1); + arr[0] = x[1]; + map.set(x[0], arr); + } + return x; + }); + return map; } @@ -519,7 +555,9 @@ 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'); + let retArr = []; + arr.map(childrenSelector).map((x) => retArr = retArr.concat(x)); + return retArr; } @@ -536,7 +574,7 @@ 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 arr.join().split(',')[indexes.reduce((accumulator, value) => accumulator + value)]; } @@ -559,7 +597,22 @@ function getElementByIndexes(arr, indexes) { * */ function swapHeadAndTail(arr) { - throw new Error('Not implemented'); + let mid = Math.floor(arr.length / 2); + if((arr.length - (mid * 2)) != 0) + { + let arrMid=arr[mid]; + let head = arr.slice(0, mid); + let tail = arr.slice(mid + 1); + let newArr = []; + return newArr.concat(tail, arrMid, head); + } + else + { + let head = arr.slice(0, mid); + let tail = arr.slice(mid); + let newArr = []; + return newArr.concat(tail, head); + } } From 97ce60d3eed012f0626d7286af2448cfc31287c1 Mon Sep 17 00:00:00 2001 From: birukov01 <154227459+birukov01@users.noreply.github.com> Date: Sun, 12 May 2024 20:25:37 +0300 Subject: [PATCH 06/13] Update 05-regex-tasks.js --- task/05-regex-tasks.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/task/05-regex-tasks.js b/task/05-regex-tasks.js index b1c60f2d4..b26e83c32 100644 --- a/task/05-regex-tasks.js +++ b/task/05-regex-tasks.js @@ -31,7 +31,8 @@ * @return {RegExp} */ function getRegexForGuid() { - throw new Error('Not implemented'); + let reg = '[0-9a-f]'; + return new RegExp('^{' + reg + '{8}-' + reg + '{4}-' + reg + '{4}-' + reg + '{4}-' + reg + '{12}}$', 'i'); } @@ -53,7 +54,7 @@ function getRegexForGuid() { * */ function getRegexForPitSpot() { - throw new Error('Not implemented'); + return new RegExp(/.*p.t.*/); } @@ -72,7 +73,7 @@ function getRegexForPitSpot() { * @return {RegExp} */ function getRegexForIPv4() { - throw new Error('Not implemented'); + return /^(([0-2][0-9]{2}|[0-9]{1,2})\.){3}([0-2][0-9]{2}|[0-9]{1,2})$/; } @@ -91,7 +92,7 @@ function getRegexForIPv4() { * @return {RegExp} */ function getRegexForSSN() { - throw new Error('Not implemented'); + return /\d{2}[1-9]-\d{1}[1-9]-\d{3}[1-9]/; } @@ -116,7 +117,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 174d0e7e489e1cd856d4a1a3b6468d7483f888fc Mon Sep 17 00:00:00 2001 From: birukov01 <154227459+birukov01@users.noreply.github.com> Date: Tue, 14 May 2024 11:24:22 +0300 Subject: [PATCH 07/13] Update 06-conditions-n-loops-tasks.js --- task/06-conditions-n-loops-tasks.js | 167 +++++++++++++++++++++++++--- 1 file changed, 149 insertions(+), 18 deletions(-) diff --git a/task/06-conditions-n-loops-tasks.js b/task/06-conditions-n-loops-tasks.js index 249194c34..e2e877932 100644 --- a/task/06-conditions-n-loops-tasks.js +++ b/task/06-conditions-n-loops-tasks.js @@ -30,7 +30,10 @@ * */ function getFizzBuzz(num) { - throw new Error('Not implemented'); + if((num % 3 === 0) && (num % 5 === 0)) return 'FizzBuzz'; + else if(num % 5 === 0) return'Buzz'; + else if (num % 3 === 0) return 'Fizz'; + return num; } @@ -46,7 +49,9 @@ function getFizzBuzz(num) { * 10 => 3628800 */ function getFactorial(n) { - throw new Error('Not implemented'); + if (n < 0) return -1; + else if (n === 0) return 1; + else return (n * getFactorial(n - 1)); } @@ -63,7 +68,9 @@ function getFactorial(n) { * -1,1 => 0 ( = -1 + 0 + 1 ) */ function getSumBetweenNumbers(n1, n2) { - throw new Error('Not implemented'); + let count = 0; + for(let i = n1; i <=n2; i++ ) count +=i; + return count; } @@ -82,7 +89,7 @@ function getSumBetweenNumbers(n1, n2) { * 10,10,10 => true */ function isTriangle(a,b,c) { - throw new Error('Not implemented'); + return a < b + c && b < a + c && c < a + b; } @@ -119,7 +126,12 @@ function isTriangle(a,b,c) { * */ function doRectanglesOverlap(rect1, rect2) { - throw new Error('Not implemented'); + return !( + rect1.left + rect1.width < rect2.left || + rect2.left + rect2.width < rect1.left || + rect1.top + rect1.height < rect2.top || + rect2.top + rect2.height < rect1.top + ); } @@ -150,7 +162,9 @@ function doRectanglesOverlap(rect1, rect2) { * */ function isInsideCircle(circle, point) { - throw new Error('Not implemented'); + let dx = point.x - circle.center.x; + let dy = point.y - circle.center.y; + return (dx * dx + dy * dy) < (circle.radius * circle.radius); } @@ -166,7 +180,9 @@ function isInsideCircle(circle, point) { * 'entente' => null */ function findFirstSingleChar(str) { - throw new Error('Not implemented'); + for (let i = 0; i < str.length; i++) + if (str.indexOf(str[i]) == str.lastIndexOf(str[i])) return str[i]; + return null; } @@ -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].reverse().join(''); } @@ -226,7 +246,9 @@ function reverseString(str) { * 34143 => 34143 */ function reverseInteger(num) { - throw new Error('Not implemented'); + let str = ''; + str += num; + return [...str].reverse().join(''); } @@ -251,7 +273,16 @@ function reverseInteger(num) { * 4916123456789012 => false */ function isCreditCardNumber(ccn) { - throw new Error('Not implemented'); + ccn = [...String(ccn)].reverse(); + ccn = ccn.reduce(function(sum, val, ind) + { + let dig = Number(val); + if(ind % 2) dig *= 2; + sum += Math.floor(dig / 10); + sum += dig % 10; + return sum; + }, 0); + return (ccn * 3) % 10 == 0; } @@ -270,7 +301,18 @@ function isCreditCardNumber(ccn) { * 165536 (1+6+5+5+3+6 = 26, 2+6 = 8) => 8 */ function getDigitalRoot(num) { - throw new Error('Not implemented'); + do + { + let sum = 0; + while(num > 0) + { + sum += num % 10; + num = Math.floor(num / 10); + } + num = sum; + } + while(num > 9); + return num; } @@ -296,7 +338,24 @@ function getDigitalRoot(num) { * '{[(<{[]}>)]}' = true */ function isBracketsBalanced(str) { - throw new Error('Not implemented'); + let pair = + { + '>' : '<', + ')' : '(', + ']' : '[', + '}' : '{' + } + let res = [...str].reduce(function(acc, x, ind) + { + if (['(', '{', '[', '<'].indexOf(x) != -1) acc.push(x); + else + { + if (acc.length > 0 && acc[acc.length - 1] == pair[x]) acc.pop(); + else acc.push(x); + } + return acc; + }, []); + return res.length == 0; } @@ -332,7 +391,44 @@ function isBracketsBalanced(str) { * */ function timespanToHumanString(startDate, endDate) { - throw new Error('Not implemented'); + const diff = (endDate - startDate) / 1000; + const minute = 60; + const hour = minute * 60; + const day = hour * 24; + const month = day * 30; + const year = day * 365; + if (diff <= 45) return "a few seconds ago"; + else if (diff <= 90) return "a minute ago"; + else if (diff <= minute * 45) + { + let x = diff % minute; + if (x !== 30) return `${Math.round(diff / minute)} minutes ago`; + else return `${Math.floor(diff / minute)} minutes ago`; + } + else if (diff <= minute * 90) return "an hour ago"; + else if (diff <= hour * 22) + { + let x = diff % hour; + if (x !== (30 * 60)) return `${Math.round(diff / hour)} hours ago`; + else return `${Math.floor(diff / hour)} hours ago`; + } + else if (diff <= day * 1.5) return "a day ago"; + else if (diff <= day * 25) + { + let x = diff % day; + if (x !== (12 * 60 * 60)) return `${Math.round(diff / day)} days ago`; + else return `${Math.floor(diff / day)} days ago`; + + } + else if (diff <= day * 45) return "a month ago"; + else if (diff <= day * 345) + { + let x = diff % (day * 365); + if (x !== (15 * 24 * 60 * 60)) return `${Math.round(diff / month)} months ago`; + else return `${Math.floor(diff / month)} months ago`; + } + else if (diff <= day * 545) return "a year ago"; + else return `${Math.round(diff / year)} years ago`; } @@ -356,7 +452,7 @@ function timespanToHumanString(startDate, endDate) { * 365, 10 => '365' */ function toNaryString(num, n) { - throw new Error('Not implemented'); + return num.toString(n); } @@ -373,7 +469,15 @@ function toNaryString(num, n) { * ['/web/favicon.ico', '/web-scripts/dump', '/webalizer/logs'] => '/' */ function getCommonDirectoryPath(pathes) { - throw new Error('Not implemented'); + let answer = ''; + pathes = pathes.map(path => path.split('/')); + while(pathes.length != 0) { + let tmp = pathes[0].shift(); + for (let i = 1; i < pathes.length; i++) + if(pathes[i].shift() != tmp) return answer; + answer += tmp + '/'; + } + return answer; } @@ -396,7 +500,18 @@ function getCommonDirectoryPath(pathes) { * */ function getMatrixProduct(m1, m2) { - throw new Error('Not implemented'); + let n = m1.length, m = m2[0].length; + let answer = new Array(n); + for (let i = 0; i < n; i++) + answer[i] = new Array(m); + for (let i = 0; i < m; i++) + for (let j = 0; j < n; j++) + answer[i][j] = 0; + for(let i = 0; i < n; i++) + for(let j = 0; j < m; j++) + for(let k = 0; k < m1[0].length; k++) + answer[i][j] += m1[i][k] * m2[k][j]; + return answer; } @@ -431,7 +546,23 @@ function getMatrixProduct(m1, m2) { * */ function evaluateTicTacToePosition(position) { - throw new Error('Not implemented'); + for (let i = 0; i < position.length; i++){ + if ((position[i][0] === position[i][1]) && (position[i][0] === position[i][2]) && (typeof position[i][0] != 'undefined')) + return position[i][0]; + } + let fl1 = true, fl2 = true; + for (let x = 1; x < position.length; x++){ + if (position[x][x] !== position[0][0]) fl1 = false; + if (position[x][position.length - 1 - x] !== position[0][2]) fl2 = false; + } + if (fl1 && typeof position[0][0] != undefined) return position[0][0]; + if (fl2 && typeof position[0][2] != undefined) return position[0][2]; + + for (let i = 0; i < position.length; i++) { + if ((position[0][i] === position[1][i]) && (position[0][i] === position[2][i]) && (typeof position[0][i] !== 'undefined')) + return position[0][i]; + } + return undefined; } From ce132a7738ce035419a31f59073a53392c1b6926 Mon Sep 17 00:00:00 2001 From: birukov01 <154227459+birukov01@users.noreply.github.com> Date: Tue, 14 May 2024 13:31:54 +0300 Subject: [PATCH 08/13] Update 07-yield-tasks.js --- task/07-yield-tasks.js | 73 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 68 insertions(+), 5 deletions(-) diff --git a/task/07-yield-tasks.js b/task/07-yield-tasks.js index a2369790a..0b4d498dc 100644 --- a/task/07-yield-tasks.js +++ b/task/07-yield-tasks.js @@ -33,7 +33,21 @@ * */ function* get99BottlesOfBeer() { - throw new Error('Not implemented'); + let count = 99; + while (count >= 3) + { + yield count + ' bottles of beer on the wall, ' + count + ' bottles of beer.'; + yield 'Take one down and pass it around, ' + --count + ' bottles of beer on the wall.'; + } + if (count == 2) + { + yield count + ' bottles of beer on the wall, ' + count + ' bottles of beer.'; + yield 'Take one down and pass it around, ' + --count + ' bottle of beer on the wall.'; + } + yield '1 bottle of beer on the wall, 1 bottle of beer.'; + 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 +61,18 @@ function* get99BottlesOfBeer() { * */ function* getFibonacciSequence() { - throw new Error('Not implemented'); + yield 0; + yield 1; + let last = 0; + let current = 1; + let new_val = 1; + while (true) + { + yield new_val; + last = current; + current = new_val; + new_val = last + current; + } } @@ -82,7 +107,13 @@ 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 +139,14 @@ function* depthTraversalTree(root) { * */ function* breadthTraversalTree(root) { - throw new Error('Not implemented'); + let nodes = [root]; + for (let i = 0; i < nodes.length; i++) { + yield nodes[i]; + if ('children' in nodes[i]) { + for (let j = 0; j < nodes[i].children.length; j++) + nodes.push(nodes[i].children[j]); + } + } } @@ -126,7 +164,32 @@ function* breadthTraversalTree(root) { * [ 1, 3, 5, ... ], [ -1 ] => [ -1, 1, 3, 5, ...] */ function* mergeSortedSequences(source1, source2) { - throw new Error('Not implemented'); + let src1 = source1(); + let src2 = source2(); + let i = src1.next().value; + let j = src2.next().value; + while (true) { + if ((i == undefined) && (j != undefined)) + { + yield j; + j = src2.next().value; + } + else if ((j == undefined) && (i != undefined)) + { + yield i; + i = src1.next().value; + } + else if ((i < j) && (i != undefined) && (j != undefined)) + { + yield i; + i = src1.next().value; + } + else if ((i >= j) && (i != undefined) && (j != undefined)) + { + yield j; + j = src2.next().value; + } + } } From 09c2d3a3cd42c6b7f62810f8fceef669ca3532cd Mon Sep 17 00:00:00 2001 From: birukov01 <154227459+birukov01@users.noreply.github.com> Date: Tue, 14 May 2024 19:06:23 +0300 Subject: [PATCH 09/13] Update 08-objects-tasks.js --- task/08-objects-tasks.js | 102 ++++++++++++++++++++++++++++++++++----- 1 file changed, 91 insertions(+), 11 deletions(-) diff --git a/task/08-objects-tasks.js b/task/08-objects-tasks.js index 610b1e7b2..cf65cd075 100644 --- a/task/08-objects-tasks.js +++ b/task/08-objects-tasks.js @@ -23,7 +23,9 @@ * console.log(r.getArea()); // => 200 */ function Rectangle(width, height) { - throw new Error('Not implemented'); + this.width = width; + this.height = height; + this.getArea = () => {return this.width * this.height} } @@ -38,7 +40,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,8 +56,12 @@ function getJSON(obj) { * */ function fromJSON(proto, json) { - throw new Error('Not implemented'); -} + let jsonObj = JSON.parse(json); + let obj = Object.create(proto); + for (let field in proto.prototype) obj[field] = proto[field]; + for (let field in jsonObj) obj[field] = jsonObj[field] + return Object.setPrototypeOf(jsonObj, proto); +}var r = fromJSON(Rectangle.prototype, '{"width":10, "height":20}'); /** @@ -106,34 +112,108 @@ function fromJSON(proto, json) { * For more examples see unit tests. */ + + +const CssSelector = (function () { + const extraPartsErrorMsg = 'Element, id and pseudo-element should not occur more then one time inside the selector'; + const invalidOrderErrorMsg = 'Selector parts should be arranged in the following order: element, id, class, attribute, pseudo-class, pseudo-element'; + const map = new WeakMap(); + const State = Object.freeze({ + ELEMENT: 0, + ID: 1, + CLASS: 2, + ATTR: 3, + PSEUDO_CLASS: 4, + PSEUDO_ELEMENT: 5, + COMBINED_SELECTOR: 10 + }); + function internal(ref) { + if (!map.get(ref)) map.set(ref, {}); + return map.get(ref); + } + function addPart(scope, value, validState, nextState) { + const selector = internal(scope); + if (selector.alreadyCalled[validState]) throw new Error(extraPartsErrorMsg); + if (selector.currentState > validState) throw new Error(invalidOrderErrorMsg); + if (nextState) selector.alreadyCalled[validState] = true; + scope.selector += value; + selector.currentState = nextState || validState; + return scope; + } + function CssSelector(selector, state) { + this.selector = selector || ''; + internal(this).currentState = state || State.ELEMENT; + internal(this).alreadyCalled = {}; + } + + CssSelector.prototype = { + + element: function (value) { + return addPart(this, value, State.ELEMENT, State.ID); + }, + + id: function (value) { + return addPart(this, `#${value}`, State.ID, State.CLASS); + }, + + class: function (value) { + return addPart(this, `.${value}`, State.CLASS); + }, + + attr: function (value) { + return addPart(this, `[${value}]`, State.ATTR); + }, + + pseudoClass: function (value) { + return addPart(this, `:${value}`, State.PSEUDO_CLASS); + }, + + pseudoElement: function (value) { + return addPart(this, `::${value}`, State.PSEUDO_ELEMENT, State.COMBINED_SELECTOR); + }, + + combine: function (second, combinator) { + const combinedSelector = `${this.selector} ${combinator} ${second.selector}`; + return new CssSelector(combinedSelector, State.COMBINED_SELECTOR); + }, + + stringify: function () { + return this.selector; + } + }; + + return CssSelector; + +}()); + const cssSelectorBuilder = { element: function(value) { - throw new Error('Not implemented'); + return new CssSelector().element(value); }, id: function(value) { - throw new Error('Not implemented'); + return new CssSelector().id(value); }, class: function(value) { - throw new Error('Not implemented'); + return new CssSelector().class(value); }, attr: function(value) { - throw new Error('Not implemented'); + return new CssSelector().attr(value); }, pseudoClass: function(value) { - throw new Error('Not implemented'); + return new CssSelector().pseudoClass(value); }, pseudoElement: function(value) { - throw new Error('Not implemented'); + return new CssSelector().pseudoElement(value); }, combine: function(selector1, combinator, selector2) { - throw new Error('Not implemented'); + return selector1.combine(selector2, combinator); }, }; From 5944b4e8467f993d967dc6762910091d9bddf224 Mon Sep 17 00:00:00 2001 From: birukov01 <154227459+birukov01@users.noreply.github.com> Date: Tue, 14 May 2024 22:49:20 +0300 Subject: [PATCH 10/13] Update 09-functions-n-closures-tasks.js --- task/09-functions-n-closures-tasks.js | 58 +++++++++++++++++++++------ 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/task/09-functions-n-closures-tasks.js b/task/09-functions-n-closures-tasks.js index 6ba9dcedd..608fb03f3 100644 --- a/task/09-functions-n-closures-tasks.js +++ b/task/09-functions-n-closures-tasks.js @@ -26,7 +26,9 @@ * */ function getComposition(f,g) { - throw new Error('Not implemented'); + return function (x) { + return f(g(x)); + } } @@ -47,7 +49,9 @@ function getComposition(f,g) { * */ function getPowerFunction(exponent) { - throw new Error('Not implemented'); + return function (number) { + return Math.pow(number, exponent); + } } @@ -65,7 +69,10 @@ function getPowerFunction(exponent) { * getPolynom() => null */ function getPolynom() { - throw new Error('Not implemented'); + let tmp = Array.from(arguments).reverse(); + return (x) => { + return tmp.reduce((prev, curr, index) => prev+curr*Math.pow(x,index),0); + }; } @@ -84,7 +91,10 @@ function getPolynom() { * memoizer() => the same random number (next run, returns the previous cached result) */ function memoize(func) { - throw new Error('Not implemented'); + let cashed = func(); + return function() { + return cashed + } } @@ -104,15 +114,25 @@ function memoize(func) { * retryer() => 2 */ function retry(func, attempts) { - throw new Error('Not implemented'); + return()=>{ + for (var i = 0; i < attempts;) + { + try{ + return func(); + } + catch(err){ + i += 1; + } + } + return i; + }; } - /** * Returns the logging wrapper for the specified method, * Logger has to log the start and end of calling the specified function. * Logger has to log the arguments of invoked function. - * The fromat of output log is: + * The format of output log is: * (, ,...,) starts * (, ,...,) ends * @@ -124,7 +144,7 @@ function retry(func, attempts) { * @example * * var cosLogger = logger(Math.cos, console.log); - * var result = cosLogger(Math.PI)); // -1 + * var result = cosLogger(Math.PI); // -1 * * log from console.log: * cos(3.141592653589793) starts @@ -132,7 +152,13 @@ function retry(func, attempts) { * */ function logger(func, logFunc) { - throw new Error('Not implemented'); + return function(...props) { + const str = `${func.name}(${JSON.stringify(Array.from(props)).slice(1, -1)}) `; + logFunc(str + 'starts'); + const result = func.apply(null, props); + logFunc(str + 'ends'); + return result; + }; } @@ -150,7 +176,10 @@ function logger(func, logFunc) { * partialUsingArguments(fn, 'a','b','c','d')() => 'abcd' */ function partialUsingArguments(fn) { - throw new Error('Not implemented'); + let arg = Array.from(arguments).slice(1); + return function () { + return fn.apply(null, arg.concat(Array.from(arguments))); + } } @@ -162,7 +191,7 @@ function partialUsingArguments(fn) { * * @example * var getId4 = getIdGenerator(4); - * var getId10 = gerIdGenerator(10); + * var getId10 = getIdGenerator(10); * getId4() => 4 * getId10() => 10 * getId4() => 5 @@ -171,7 +200,12 @@ function partialUsingArguments(fn) { * getId10() => 11 */ function getIdGeneratorFunction(startFrom) { - throw new Error('Not implemented'); + let scope = startFrom; + return () => { + const toReturn = scope; + scope += 1; + return toReturn; + }; } From fb8110839a69690df10d53d437f76695806df0bd Mon Sep 17 00:00:00 2001 From: birukov01 <154227459+birukov01@users.noreply.github.com> Date: Tue, 14 May 2024 23:26:24 +0300 Subject: [PATCH 11/13] Update 10-katas-1-tasks.js --- task/10-katas-1-tasks.js | 161 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 155 insertions(+), 6 deletions(-) diff --git a/task/10-katas-1-tasks.js b/task/10-katas-1-tasks.js index 5128b0695..4bce440d5 100644 --- a/task/10-katas-1-tasks.js +++ b/task/10-katas-1-tasks.js @@ -17,8 +17,27 @@ * ] */ function createCompassPoints() { - throw new Error('Not implemented'); - var sides = ['N','E','S','W']; // use array of cardinal directions only! + let resArr = [], direction = "", degrees = 0; + var sides = ['N', 'E', 'S', 'W']; // use array of cardinal directions only! + for (let i = 0; i < sides.length; i++) { + let btwcardinal = (i == 0 || i == 2) ? (sides[i] + sides[i + 1]) + : (sides[i == 3 ? 0 : i + 1] + sides[i]); + for (let count = 0; count < 8; count++) { + switch (count) { + case 0: direction = sides[i]; break; + case 1: direction = sides[i] + 'b' + sides[i == 3 ? 0 : i + 1]; break; + case 2: direction = sides[i] + btwcardinal; break; + case 3: direction = btwcardinal + "b" + sides[i]; break; + case 4: direction = btwcardinal; break; + case 5: direction = btwcardinal + "b" + sides[i == 3 ? 0 : i + 1]; break; + case 6: direction = sides[i == 3 ? 0 : i + 1] + btwcardinal; break; + case 7: direction = sides[i == 3 ? 0 : i + 1] + "b" + sides[i]; break; + } + resArr.push({ abbreviation: direction, azimuth: degrees }); + degrees += 11.25; + } + } + return resArr; } @@ -56,7 +75,68 @@ function createCompassPoints() { * 'nothing to do' => 'nothing to do' */ function* expandBraces(str) { - throw new Error('Not implemented'); + const OPEN_BR = '{'; + const CLOSE_BR = '}'; + const SEPARATOR = ','; + + yield* parse(str); + + function parse(str) { + let items = ['']; + let pos = 0; + while (str[pos]) + if (str[pos] !== OPEN_BR) items = combine(items, [readUntil([OPEN_BR])]); + else + { + pos += 1; + items = combine(items, parseExpr()); + } + return items; + + function parseExpr() { + let items = []; + let sepCount = 0; + while (str[pos] !== CLOSE_BR) + if (str[pos] === SEPARATOR) + { + pos += 1; + sepCount += 1; + } + else items = items.concat(parseExprPart()); + if (items.length < sepCount + 1) items.push(''); + pos += 1; + return items; + } + + function parseExprPart() { + let items = ['']; + while (str[pos] !== SEPARATOR && str[pos] !== CLOSE_BR) + if (str[pos] !== OPEN_BR) items = combine(items, [readUntil([SEPARATOR, OPEN_BR, CLOSE_BR])]); + else + { + pos += 1; + items = combine(items, parseExpr()); + } + return items; + } + + function combine(leftItems, rightItems) { + const res = []; + for (let left of leftItems) + for (let right of rightItems) + res.push(left + right); + return res; + } + + function readUntil(chars) { + let res = ''; + while (str[pos] && chars.every(x => x !== str[pos])) { + res += str[pos]; + pos += 1; + } + return res; + } + } } @@ -88,7 +168,26 @@ function* expandBraces(str) { * */ function getZigZagMatrix(n) { - throw new Error('Not implemented'); + let mtx = []; + for (var i = 0; i < n; i++) mtx[i] = []; + var i = 1, j = 1; + for (var e = 0; e < n * n; e++) + { + mtx[i - 1][j - 1] = e; + if ((i + j) % 2 == 0) + { + if (j < n) j++; + else i += 2; + if (i > 1) i--; + } + else + { + if (i < n) i++; + else j += 2; + if (j > 1) j--; + } + } + return mtx; } @@ -113,7 +212,42 @@ function getZigZagMatrix(n) { * */ function canDominoesMakeRow(dominoes) { - throw new Error('Not implemented'); + let res = "" + dominoes.shift(); + let i = 0; + while (dominoes.length != 0) + { + if (dominoes[i][0] == res[0]) + { + res = dominoes[i].reverse() + res; + dominoes.splice(i, 1); + i = 0; + continue; + } + if (dominoes[i][1] == res[0]) + { + res = dominoes[i] + res; + dominoes.splice(i, 1); + i = 0; + continue; + } + if (dominoes[i][0] == res[res.length - 1]) + { + res = res + dominoes[i]; + dominoes.splice(i, 1); + i = 0; + continue; + } + if (dominoes[i][1] == res[res.length - 1]) + { + res = res + dominoes[i].reverse(); + dominoes.splice(i, 1); + i = 0; + continue; + } + i++; + if (i == dominoes.length) return false; + } + return true; } @@ -137,7 +271,22 @@ function canDominoesMakeRow(dominoes) { * [ 1, 2, 4, 5] => '1,2,4,5' */ function extractRanges(nums) { - throw new Error('Not implemented'); + let res = ""; + for (let j = 0; j < nums.length; j++) + { + let i = 0; + if ((nums[j + 1] - nums[j] == 1) && (nums[j + 2] - nums[j] == 2)) + { + while (nums[j + 1] - nums[j] == 1) { + i++; + j++; + } + res += `${nums[j - i]}-${nums[j]},`; + + } + else res += nums[j] + ","; + } + return res.slice(0, res.length - 1); } module.exports = { From 5430fd9bb2c3d8959cd8c54689704a3be3731366 Mon Sep 17 00:00:00 2001 From: birukov01 <154227459+birukov01@users.noreply.github.com> Date: Wed, 15 May 2024 16:00:37 +0300 Subject: [PATCH 12/13] Update 11-katas-2-tasks.js --- task/11-katas-2-tasks.js | 176 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 172 insertions(+), 4 deletions(-) diff --git a/task/11-katas-2-tasks.js b/task/11-katas-2-tasks.js index 2a1a745cd..fea5cefcd 100644 --- a/task/11-katas-2-tasks.js +++ b/task/11-katas-2-tasks.js @@ -34,7 +34,20 @@ * */ function parseBankAccount(bankAccount) { - throw new Error('Not implemented'); + const numbers = { + ' _ | ||_|': 0, + ' | |': 1, + ' _ _||_ ': 2, + ' _ _| _|': 3, + ' |_| |': 4, + ' _ |_ _|': 5, + ' _ |_ |_|': 6, + ' _ | |': 7, + ' _ |_||_|': 8, + ' _ |_| _|': 9 + }; + let res = bankAccount.split('\n').slice(0, 3).map(item => item.match(/.../g)); + return +res[0].map((item, index) => numbers[item + res[1][index] + res[2][index]]).join(""); } @@ -63,8 +76,24 @@ function parseBankAccount(bankAccount) { * 'characters.' */ function* wrapText(text, columns) { - throw new Error('Not implemented'); + if (text.length < columns) + { + yield text; + return; + } + let num = 0; + let prevNum = 0; + let str = ""; + while ((num != -1) && (num <= columns)) + { + prevNum = num; + num = text.indexOf(' ', num + 1); + } + str = text.slice(0, prevNum); + yield str; + yield* wrapText(text.slice(prevNum + 1), columns); } +let t = wrapText('The String global object is a constructor for strings, or a sequence of characters.', 26) /** @@ -100,7 +129,108 @@ const PokerRank = { } function getPokerHandRank(hand) { - throw new Error('Not implemented'); + let rang = { + J: 11, + Q: 12, + K: 13, + A: 14 + } + let typeOfCard = { + '♥': 1, + '♦': 2, + '♠': 3, + '♣': 4 + } + let numberHand = hand.map((item, ind) => { + let _rang = item.slice(0, -1); + let _typeOfCard = item.slice(-1); + return rang[_rang] ? `${rang[_rang]}${typeOfCard[_typeOfCard]}` : `${_rang}${typeOfCard[_typeOfCard]}`; + }); + + switch (true) { + case (isSomeFlush(numberHand)): return isInOrderHand(numberHand) + ? PokerRank.StraightFlush : PokerRank.Flush; + case (isSomeOfKind(numberHand, 4)): return PokerRank.FourOfKind; + case (isFullHouseOrTwoPairs(numberHand, 3)): return PokerRank.FullHouse; + case (isInOrderHand(numberHand)): return PokerRank.Straight; + case (isSomeOfKind(numberHand, 3)): return PokerRank.ThreeOfKind; + case (isFullHouseOrTwoPairs(numberHand, 2)): return PokerRank.TwoPairs; + case (isSomeOfKind(numberHand, 2)): return PokerRank.OnePair; + default: return PokerRank.HighCard; + + } +} +function isSomeFlush(hand) { + let arr = hand.filter((item, i, arr) => { + return item.slice(-1) === arr[0].slice(-1); + }); + return arr.length == hand.length; +} +function isInOrderHand(hand) { + let arr = hand.map((item, i) => +item.slice(0, -1)).sort((a, b) => a - b).filter((item, i, arr) => { + return arr[i + 1] ? (((arr[i + 1] == 14) && (arr[0] == 2)) + ? true : (arr[i + 1] - arr[i] == 1)) : ((arr[i] == 14) && (arr[0] == 2)) + ? true : (arr[i] - arr[i - 1] == 1); + + }); + return arr.length == hand.length; +} +function isFullHouseOrTwoPairs(hand, kind) { + hand.sort(); + if (isSomeOfKind(hand, kind)) + { + let arr = fixSizeOfArray(hand); + return isSomeOfKind(arr, 2); + } + return false; +} + +function fixSizeOfArray(hand) { + let arr = hand.map((item, i) => { + return item.slice(0, -1); + }); + let obj = {}; + for (let index = 0; index < arr.length; index++) + obj[arr[index]] ? obj[arr[index]]++ : obj[arr[index]] = 1; + let max = 0; + let nameEl = ""; + for (let key in obj) + if (obj[key] > max) + { + max = obj[key]; + nameEl = key; + } + let newarr = hand.filter((item, i) => { + return nameEl != item.slice(0, -1); + }); + return newarr; +} + +function isSomeOfKind(hand, kind) { + let arr = hand.map((item, i) => { + return item.slice(0, -1); + }); + let obj = {}; + for (let index = 0; index < arr.length; index++) + obj[arr[index]] ? obj[arr[index]]++ : obj[arr[index]] = 1; + let max = 0; + for (let key in obj) + if (obj[key] > max) max = obj[key]; + return max == kind; +} +function isTwoPairs(hand) { + hand.sort(); + if (isSomeOfKind(hand, 2)) + { + let arr1 = hand.filter((item, i, arr) => { + return arr[i + 1] ? arr[i].slice(0, -1) === arr[i + 1].slice(0, -1) + : arr[i].slice(0, -1) === arr[i - 1].slice(0, -1); + }); + hand.splice(hand.indexOf(arr1[0]), 2); + return isSomeOfKind(hand, 2); + + } + return false; } @@ -135,7 +265,45 @@ function getPokerHandRank(hand) { * '+-------------+\n' */ function* getFigureRectangles(figure) { - throw new Error('Not implemented'); + let a = figure.split('\n'); + let answer = []; + let check = function bar(n, m) { + let i; + let j; + for (i = m; ; i++) + { + if (a[n - 1][i] == undefined || a[n - 1][i] == ' ' || a[n] == undefined) return; + if (a[n][i] != ' ') break; + } + let w = i; + for (j = n; ; j++) + { + if (a[j] == undefined || a[j][w] == ' ') return; + if (a[j][w - 1] != ' ') break; + } + let h = j; + for (i = w - 1; ; i--) + { + if (a[h][i] == undefined || a[h][i] == ' ' || a[h - 1] == undefined) return; + if (a[h - 1][i] != ' ') break; + } + if (i + 1 != m) return; + for (j = h - 1; ; j--) + { + if (a[j] == undefined || a[j][m - 1] == ' ') return; + if (a[j][m] != ' ') break; + } + if (j + 1 != n) return; + n = h - n; + m = w - m; + answer.push('+' + '-'.repeat(m) + '+\n' + ('|' + ' '.repeat(m) + '|\n').repeat(n) + '+' + '-'.repeat(m) + '+\n'); + } + + a.pop(); + a.forEach((v, i) => v.split('').forEach((v, j) => { + if (v == '+') check(i + 1, j + 1); + })); + for (let index = 0; index < answer.length; index++) yield answer[index]; } From bf38757e9b63168068bf802b50c125ec130274d8 Mon Sep 17 00:00:00 2001 From: birukov01 <154227459+birukov01@users.noreply.github.com> Date: Wed, 15 May 2024 18:30:41 +0300 Subject: [PATCH 13/13] Update 12-katas-3-tasks.js --- task/12-katas-3-tasks.js | 100 ++++++++++++++++++++++++++++++++++----- 1 file changed, 89 insertions(+), 11 deletions(-) diff --git a/task/12-katas-3-tasks.js b/task/12-katas-3-tasks.js index 5299be87d..7ac4e076f 100644 --- a/task/12-katas-3-tasks.js +++ b/task/12-katas-3-tasks.js @@ -28,7 +28,58 @@ * 'NULL' => false */ function findStringInSnakingPuzzle(puzzle, searchStr) { - throw new Error('Not implemented'); + class RouteMap { + constructor() { + this._route = {}; + this._width = puzzle[0].length; + this._height = puzzle.length; + } + + _key(x, y) { + return `${x},${y}`; + } + + markAvailable(x, y) { + this._route[this._key(x, y)] = false; + } + + markVisited(x, y) { + this._route[this._key(x, y)] = true; + } + + isAvailable(x, y) { + return x >= 0 + && x < this._width + && y >= 0 + && y < this._height + && !this._route[this._key(x, y)]; + } + } + + function* getSiblings(x, y) { + yield [x - 1, y]; + yield [x + 1, y]; + yield [x, y - 1]; + yield [x, y + 1]; + } + + function checkRoute(x, y, search, route) { + if (!route.isAvailable(x, y) || puzzle[y][x] !== search[0]) return false; + if (search.length === 1) return true; + route.markVisited(x, y); + const nextSearch = search.slice(1); + for (let [sx, sy] of getSiblings(x, y)) + if (checkRoute(sx, sy, nextSearch, route)) return true; + route.markAvailable(x, y); + return false; + } + + for (let y = 0; y < puzzle.length; ++y) { + for (let x = 0; x < puzzle[0].length; ++x) { + if (checkRoute(x, y, searchStr, new RouteMap())) return true; + } + } + return false; } @@ -44,8 +95,24 @@ function findStringInSnakingPuzzle(puzzle, searchStr) { * 'ab' => 'ab','ba' * 'abc' => 'abc','acb','bac','bca','cab','cba' */ + function Perm(chars) { + let ret = []; + if (chars.length == 1) return [chars]; + if (chars.length == 2) return chars != chars[1] + chars[0] ? [chars, chars[1] + chars[0]] : [chars]; + chars.split('').forEach(function (chr, idx, arr) { + let sub = [...arr]; + sub.splice(idx, 1); + Perm(sub.join('')).forEach(function (perm) { + ret.push(chr + perm); + }); + }); + return ret.filter((elem, pos, arr) => { + return arr.indexOf(elem) == pos; + }); +} function* getPermutations(chars) { - throw new Error('Not implemented'); + let ret = Perm(chars); + for (let i = 0; i < ret.length; i++) yield ret[i]; } @@ -65,7 +132,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'); + if (!quotes.length) return 0; + let maxNum = Math.max.apply(null, quotes); + let indMax = quotes.lastIndexOf(maxNum); + return quotes.slice(0, indMax).reduce((prev, curr) => prev += maxNum - curr, 0) + + getMostProfitFromStockQuotes(quotes.slice(indMax + 1)); } @@ -90,14 +161,21 @@ function UrlShortener() { } UrlShortener.prototype = { - - encode: function(url) { - throw new Error('Not implemented'); - }, - - decode: function(code) { - throw new Error('Not implemented'); - } + encode: function (url) { + var res = ''; + for (let i = 0; i * 2 < url.length; i++) + res += String.fromCodePoint(url.codePointAt(2 * i) * 256 + (url.codePointAt(2 * i + 1) || 0)) + return res; + }, + decode: function (code) { + var res = ''; + for (let i = 0; i < code.length; i++) + { + let c = code.codePointAt(i); + res += String.fromCodePoint(c / 256 | 0) + (c % 256 ? String.fromCodePoint(c % 256) : ''); + } + return res; + } }