From e9934aed97f82d0cc393d95bed9e5389184ad169 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=9F=D0=B0=D0=B2=D0=B5=D0=BB=20=D0=93=D0=B5=D1=80=D0=B0?=
 =?UTF-8?q?=D1=81=D0=B8=D0=BC=D1=91=D0=BD=D0=BE=D0=BA=20=28=D0=BD=D0=BE?=
 =?UTF-8?q?=D1=83=D1=82=D0=B1=D1=83=D0=BA=29?= <pavel.gmk@outlook.com>
Date: Thu, 15 Oct 2020 18:57:14 +0300
Subject: [PATCH] =?UTF-8?q?=D0=93=D0=BE=D1=82=D0=BE=D0=B2=D0=BE=D0=B5=20?=
 =?UTF-8?q?=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 task/01-strings-tasks.js            |  84 +++++--
 task/02-numbers-tasks.js            |  43 ++--
 task/03-date-tasks.js               |  28 ++-
 task/04-arrays-tasks.js             | 376 ++++++++++++++++++----------
 task/05-regex-tasks.js              |  13 +-
 task/06-conditions-n-loops-tasks.js | 253 ++++++++++++++++---
 6 files changed, 576 insertions(+), 221 deletions(-)

diff --git a/task/01-strings-tasks.js b/task/01-strings-tasks.js
index e28054657..0a9e41232 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.concat(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 new RegExp("Hello, (.+)!").exec(value)[1]
 }
 
 
@@ -84,7 +84,7 @@ function extractNameFromTemplate(value) {
  *   'cat'       => 'c'
  */
 function getFirstChar(value) {
-    throw new Error('Not implemented');
+    return value.substring(0,1)
 }
 
 /**
@@ -99,7 +99,7 @@ function getFirstChar(value) {
  *   '\tHello, World! ' => 'Hello, World!'
  */
 function removeLeadingAndTrailingWhitespaces(value) {
-    throw new Error('Not implemented');
+    return value.trim()
 }
 
 /**
@@ -114,12 +114,12 @@ function removeLeadingAndTrailingWhitespaces(value) {
  *   'cat', 3 => 'catcatcat'
  */
 function repeatString(value, count) {
-    throw new Error('Not implemented');
+    return value.repeat(count)
 }
 
 /**
  * Remove the first occurrence of string inside another string
- * 
+ *
  * @param {string} str
  * @param {string} value
  * @return {string}
@@ -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>' => 'a'
  */
 function unbracketTag(str) {
-    throw new Error('Not implemented');
+    return str.replace('<', '').replace('>', '')
 }
 
 
@@ -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,25 @@ function extractEmails(str) {
  *
  */
 function getRectangleString(width, height) {
-    throw new Error('Not implemented');
+    var horizontalChar = '─';
+    var verticalChar = '│';
+    var innerChar = ' ';
+    var breakChar = '\n';
+    var str = '';
+
+    for(var h = 1; h <= height; h++) {
+        switch (h) {
+            case 1:
+                str += '┌' + horizontalChar.repeat(width-2) + '┐' + breakChar
+                break
+            case height:
+                str += '└' + horizontalChar.repeat(width-2) + '┘' + breakChar
+                break
+            default:
+                str += verticalChar + innerChar.repeat(width-2) + verticalChar + breakChar
+        }
+    }
+    return str
 }
 
 
@@ -221,7 +239,25 @@ function getRectangleString(width, height) {
  *
  */
 function encodeToRot13(str) {
-    throw new Error('Not implemented');
+    var amount = 13
+    var output = ""
+
+    for (var i = 0; i < str.length; i++) {
+        var c = str[i]
+        if (c.match(/[a-z]/i)) {
+            var code = str.charCodeAt(i)
+
+            if (code >= 65 && code <= 90) {
+                c = String.fromCharCode(((code - 65 + amount) % 26) + 65)
+            }
+            else if (code >= 97 && code <= 122) {
+                c = String.fromCharCode(((code - 97 + amount) % 26) + 97)
+            }
+        }
+        output += c
+    }
+
+    return output
 }
 
 /**
@@ -238,36 +274,42 @@ function encodeToRot13(str) {
  *   isString(new String('test')) => true
  */
 function isString(value) {
-    throw new Error('Not implemented');
+    return Object.prototype.toString.call(value) === "[object String]"
 }
 
 
 /**
  * Returns playid card id.
- * 
+ *
  * Playing cards inittial deck inclides the cards in the following order:
- * 
+ *
  *  '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♠'
- * 
+ *
  * (see https://en.wikipedia.org/wiki/Standard_52-card_deck)
  * Function returns the zero-based index of specified card in the initial deck above.
- * 
+ *
  * @param {string} value
  * @return {number}
  *
  * @example
  *   'A♣' => 0
- *   '2♣' => 1 
+ *   '2♣' => 1
  *   '3♣' => 2
  *     ...
  *   'Q♠' => 50
  *   'K♠' => 51
  */
 function getCardId(value) {
-    throw new Error('Not implemented');
+    const colors = '♣♦♥♠',
+        nums = 'A234567891JQK';
+
+    let color = value[value.length - 1],
+        num = value[0];
+
+    return colors.indexOf(color) * 13 + nums.indexOf(num);
 }
 
 
diff --git a/task/02-numbers-tasks.js b/task/02-numbers-tasks.js
index c9ed20208..aec4e864f 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 Math.PI * radius * 2;
 }
 
 /**
@@ -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,9 @@ function getAverage(value1, value2) {
  *   (-5,0) (10,-10) => 18.027756377319946
  */
 function getDistanceBetweenPoints(x1, y1, x2, y2) {
-    throw new Error('Not implemented');
+    var a = x1 - x2;
+    var b = y1 - y2;
+    return Math.sqrt(a*a + b*b)
 }
 
 /**
@@ -89,7 +91,7 @@ function getDistanceBetweenPoints(x1, y1, x2, y2) {
  *   5*x = 0         => 0
  */
 function getLinearEquationRoot(a, b) {
-    throw new Error('Not implemented');
+    return -1 * b/a
 }
 
 
@@ -111,7 +113,11 @@ 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 +133,7 @@ function getAngleBetweenVectors(x1, y1, x2, y2) {
  *     0     => 0
  */
 function getLastDigit(value) {
-    throw new Error('Not implemented');
+    return Math.abs(value) % 10
 }
 
 
@@ -143,7 +149,7 @@ function getLastDigit(value) {
  * '-525.5'     => -525.5
  */
 function parseNumberFromString(value) {
-    throw new Error('Not implemented');
+    return Number(value)
 }
 
 /**
@@ -160,7 +166,7 @@ function parseNumberFromString(value) {
  *   1,2,3   => 3.741657386773941
  */
 function getParallelipidedDiagonal(a,b,c) {
-    throw new Error('Not implemented');
+    return Math.sqrt(a*a + b*b + c*c)
 }
 
 /**
@@ -169,7 +175,7 @@ function getParallelipidedDiagonal(a,b,c) {
  * @param {number} num
  * @param {number} pow
  * @return {number}
- *  
+ *
  * @example:
  *   1234, 0  => 1234
  *   1234, 1  => 1230
@@ -181,7 +187,10 @@ function getParallelipidedDiagonal(a,b,c) {
  *   1678, 3  => 2000
  */
 function roundToPowerOfTen(num, pow) {
-    throw new Error('Not implemented');
+    if (num % Math.pow(10, pow) >= 5 * Math.pow(10, pow - 1)) {
+        return num + ( Math.pow(10, pow) - num % Math.pow(10, pow));
+    }
+    return num - (num % Math.pow(10, pow));
 }
 
 /**
@@ -190,7 +199,7 @@ function roundToPowerOfTen(num, pow) {
  *
  * @param {number} n
  * @return {bool}
- * 
+ *
  * @example:
  *   4 => false
  *   5 => true
@@ -202,7 +211,11 @@ 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 +234,7 @@ function isPrime(n) {
  *   toNumber(new Number(42), 0) => 42
  */
 function toNumber(value, def) {
-    throw new Error('Not implemented');
+    return typeof +value == 'number' && !isNaN(+value) ? +value : def;
 }
 
 module.exports = {
@@ -237,4 +250,4 @@ module.exports = {
     roundToPowerOfTen: roundToPowerOfTen,
     isPrime: isPrime,
     toNumber: toNumber
-};
+};
\ No newline at end of file
diff --git a/task/03-date-tasks.js b/task/03-date-tasks.js
index 83c6266bc..5dd6b4d83 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,10 @@ function parseDataFromIso8601(value) {
  *    Date(2015,1,1)    => false
  */
 function isLeapYear(date) {
-   throw new Error('Not implemented');
+    var year = date.getFullYear()
+    if (year % 400 === 0) return true
+    if (year % 100 === 0) return false
+    return year % 4 === 0
 }
 
 
@@ -76,14 +79,14 @@ 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);
 }
 
 
 /**
  * Returns the angle (in radians) between the hands of an analog clock for the specified Greenwich time.
  * If you have problem with solution please read: https://en.wikipedia.org/wiki/Clock_angle_problem
- * 
+ *
  * @param {date} date
  * @return {number}
  *
@@ -94,7 +97,18 @@ function timeSpanToString(startDate, endDate) {
  *    Date.UTC(2016,3,5,21, 0) => Math.PI/2
  */
 function angleBetweenClockHands(date) {
-    throw new Error('Not implemented');
+    let hour = date.getUTCHours();
+    if (hour > 12) {
+        hour -= 12;
+    }
+    let minutes = date.getUTCMinutes();
+    let hours = 0.5 * (60 * hour + minutes);
+    minutes *= 6;
+    let diff = hours - minutes;
+    if (diff > 180) {
+        diff -= 180;
+    }
+    return Math.PI * Math.abs(diff) / 180;
 }
 
 
@@ -104,4 +118,4 @@ module.exports = {
     isLeapYear: isLeapYear,
     timeSpanToString: timeSpanToString,
     angleBetweenClockHands: angleBetweenClockHands
-};
+};
\ No newline at end of file
diff --git a/task/04-arrays-tasks.js b/task/04-arrays-tasks.js
index ff3a4c019..a58454a53 100644
--- a/task/04-arrays-tasks.js
+++ b/task/04-arrays-tasks.js
@@ -9,257 +9,292 @@
  *                                                                                           *
  *********************************************************************************************/
 
- 
+
 /**
  * Returns an index of the specified element in array or -1 if element is not found
- * 
+ *
  * @param {array} arr
  * @param {any} value
  * @return {number}
- * 
+ *
  * @example
- *    ['Ace', 10, true], 10    => 1 
- *    ['Array', 'Number', 'string'], 'Date'    => -1 
+ *    ['Ace', 10, true], 10    => 1
+ *    ['Array', 'Number', 'string'], 'Date'    => -1
  *    [0, 1, 2, 3, 4, 5], 5    => 5
  */
 function findElement(arr, value) {
-   throw new Error('Not implemented');
+    return arr.indexOf(value)
 }
 
 /**
  * Generates an array of odd numbers of the specified length
- * 
+ *
  * @param {number} len
  * @return {array}
- * 
+ *
  * @example
- *    1 => [ 1 ] 
- *    2 => [ 1, 3 ] 
+ *    1 => [ 1 ]
+ *    2 => [ 1, 3 ]
  *    5 => [ 1, 3, 5, 7, 9 ]
  */
 function generateOdds(len) {
-   throw new Error('Not implemented');
+    let arr = new Array(len);
+    arr.fill(1);
+    return arr.map((elem, index) =>
+    {
+        return index*2 + 1;
+    });
 }
 
 
 /**
  * Returns the doubled array - elements of the specified array are repeated twice using original order
- * 
+ *
  * @param {array} arr
  * @return {array}
- * 
+ *
  * @example
- *    ['Ace', 10, true]  => ['Ace', 10, true,   'Ace', 10, true]  
+ *    ['Ace', 10, true]  => ['Ace', 10, true,   'Ace', 10, true]
  *    [0, 1, 2, 3, 4, 5] => [0, 1, 2, 3, 4, 5,   0, 1, 2, 3, 4, 5]
- *    [] => [] 
+ *    [] => []
  */
 function doubleArray(arr) {
-   throw new Error('Not implemented');
+    arr.map(elem =>
+    {
+        return arr.push(elem);
+    });
+    return arr;
 }
 
 
 /**
  * Returns an array of positive numbers from the specified array in original order
- * 
+ *
  * @param {array} arr
  * @return {array}
- * 
+ *
  * @example
  *    [ 0, 1, 2, 3, 4, 5 ] => [ 1, 2, 3, 4, 5 ]
  *    [-1, 2, -5, -4, 0] => [ 2 ]
- *    [] => [] 
+ *    [] => []
  */
 function getArrayOfPositives(arr) {
-   throw new Error('Not implemented');
+    return arr.filter(function(value) {
+        return value > 0;
+    });
 }
 
 /**
  * Returns the array with strings only in the specified array (in original order)
- * 
+ *
  * @param {array} arr
  * @return {array}
- * 
+ *
  * @example
  *    [ 0, 1, 'cat', 3, true, 'dog' ] => [ 'cat', 'dog' ]
  *    [ 1, 2, 3, 4, 5 ] => []
  *    [ 'cat, 'dog', 'raccon' ] => [ 'cat', 'dog', 'racoon' ]
  */
 function getArrayOfStrings(arr) {
-   throw new Error('Not implemented');
+    return arr.filter(function(value) {
+        return Object.prototype.toString.call(value) === "[object String]"
+    });
 }
 
 /**
  * Removes falsy values from the specified array
  * Falsy values: false, null, 0, "", undefined, and NaN.
  * (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean#Description)
- * 
+ *
  * @param {array} arr
  * @return {array}
- * 
+ *
  * @example
  *    [ 0, false, 'cat', NaN, true, '' ] => [ 'cat', true ]
  *    [ 1, 2, 3, 4, 5, 'false' ]         => [ 1, 2, 3, 4, 5, 'false' ]
  *    [ false, 0, NaN, '', undefined ]   => [ ]
  */
 function removeFalsyValues(arr) {
-   throw new Error('Not implemented');
+    return arr.filter(function(value) {
+        return Boolean(value);
+    });
 }
 
 /**
  * Returns the array of useprcase strings from the specified array
- * 
+ *
  * @param {array} arr
  * @return {array}
- * 
+ *
  * @example
  *    [ 'permanent-internship', 'glutinous-shriek', 'multiplicative-elevation' ] => [ 'PERMANENT-INTERNSHIP', 'GLUTINOUS-SHRIEK', 'MULTIPLICATIVE-ELEVATION' ]
  *    [ '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())
 }
 
 
 /**
  * Returns the array of string lengths from the specified string array.
- * 
+ *
  * @param {array} arr
  * @return {array}
- * 
+ *
  * @example
  *    [ '', 'a', 'bc', 'def', 'ghij' ]  => [ 0, 1, 2, 3, 4 ]
  *    [ 'angular', 'react', 'ember' ] => [ 7, 5, 5 ]
  */
 function getStringsLength(arr) {
-   throw new Error('Not implemented');
+    return arr.map(value => value.length)
 }
 
 /**
  * Inserts the item into specified array at specified index
- * 
+ *
  * @param {array} arr
  * @param {any} item
- * @param {number} index 
- * 
+ * @param {number} index
+ *
  * @example
  *    [ 1, 3, 4, 5 ], 2, 1  => [ 1, 2, 3, 4, 5 ]
  *    [ 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);
 }
 
 /**
  * Returns the n first items of the specified array
- * 
+ *
  * @param {array} arr
- * @param {number} n 
- * 
+ * @param {number} n
+ *
  * @example
  *    [ 1, 3, 4, 5 ], 2  => [ 1, 2 ]
  *    [ 'a', 'b', 'c', 'd'], 3  => [ 'a', 'b', 'c' ]
  */
 function getHead(arr, n) {
-   throw new Error('Not implemented');
+    return arr.slice(0, n)
 }
 
 
 /**
  * Returns the n last items of the specified array
- * 
+ *
  * @param {array} arr
- * @param {number} n 
- * 
+ * @param {number} n
+ *
  * @example
  *    [ 1, 3, 4, 5 ], 2  => [ 4, 5 ]
  *    [ '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))
 }
 
 
 /**
  * Returns CSV represebtation of two-dimentional numeric array.
  * https://en.wikipedia.org/wiki/Comma-separated_values
- * 
+ *
  * @param {array} arr
  * @return {string}
- * 
+ *
  * @example
  *    [
  *       [  0, 1, 2, 3, 4 ],
  *       [ 10,11,12,13,14 ],
  *       [ 20,21,22,23,24 ],
  *       [ 30,31,32,33,34 ]
- *    ] 
- *           => 
+ *    ]
+ *           =>
  *     '0,1,2,3,4\n'
  *    +'10,11,12,13,14\n'
  *    +'20,21,22,23,24\n'
  *    +'30,31,32,33,34'
  */
 function toCsvText(arr) {
-   throw new Error('Not implemented');
+    let arrStr = arr.map((elem, index) =>
+    {
+        if (index != arr.length-1)
+            return elem.join(',') + '\n';
+        else
+            return elem.join(',');
+    }).join('');
+    return arrStr;
 }
 
 /**
  * Transforms the numeric array into the according array of squares:
  *   f(x) = x * x
- * 
+ *
  * @param {array} arr
  * @return {array}
- * 
+ *
  * @example
  *   [ 0, 1, 2, 3, 4, 5 ] => [ 0, 1, 4, 9, 16, 25 ]
  *   [ 10, 100, -1 ]      => [ 100, 10000, 1 ]
  */
 function toArrayOfSquares(arr) {
-   throw new Error('Not implemented');
+    return arr.map(value => value*value)
 }
 
 
 /**
  * Transforms the numeric array to the according moving sum array:
- *     f[n] = x[0] + x[1] + x[2] +...+ x[n] 
+ *     f[n] = x[0] + x[1] + x[2] +...+ x[n]
  *  or f[n] = f[n-1] + x[n]
- * 
+ *
  * @param {array} arr
  * @return {array}
- * 
+ *
  * Example :
  *   [ 1, 1, 1, 1, 1 ]        => [ 1, 2, 3, 4, 5 ]
  *   [ 10, -10, 10, -10, 10 ] => [ 10, 0, 10, 0, 10 ]
- *   [ 0, 0, 0, 0, 0]         => [ 0, 0, 0, 0, 0] 
+ *   [ 0, 0, 0, 0, 0]         => [ 0, 0, 0, 0, 0]
  *   [ 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');
+    let sum = arr[0];
+    return arr.map((elem, index) =>
+    {
+        if (index != 0)
+        {
+            elem += sum;
+            sum = elem;
+            return elem;
+        }
+        else
+            return elem;
+    });
 }
 
 /**
  * Returns every second item from the specified array:
- * 
+ *
  * @param {array} arr
  * @return {array}
- * 
+ *
  * Example :
  * [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] => [ 2, 4, 6, 8, 10 ]
  * [ 'a', 'b', 'c' , null ]  => [ "b", null ]
  * [ "a" ] => []
  */
 function getSecondItems(arr) {
-   throw new Error('Not implemented');
+    return arr.filter(function(item, index) {
+        return index % 2 == 1;
+    });
 }
 
 
 /**
  * Propagates every item in sequence its position times
- * Returns an array that consists of: one first item, two second items, tree third items etc. 
- * 
- * @param {array} arr 
+ * Returns an array that consists of: one first item, two second items, tree third items etc.
+ *
+ * @param {array} arr
  * @return {array}
- * 
+ *
  * @example :
  *  [] => []
  *  [ 1 ] => [ 1 ]
@@ -268,13 +303,21 @@ 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 myArr = [];
+    let helpArr = [];
+    arr.map((elem, index) =>
+    {
+        helpArr.length = index+1;
+        helpArr.fill(elem);
+        return Array.prototype.push.apply(myArr, helpArr);
+    });
+    return myArr;
 }
 
 
-/** 
+/**
  * Returns the 3 largest numbers from the specified array
- * 
+ *
  * @param {array} arr
  * @return {array}
  *
@@ -286,16 +329,17 @@ 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
- * 
+ *
  * @param {array} arr
  * @return {number}
- * 
+ *
  * @example
  *   [ ]          => 0
  *   [ -1, 0, 1 ] => 1
@@ -304,15 +348,21 @@ function get3TopItems(arr) {
  *   [ 1, '2' ] => 1
  */
 function getPositivesCount(arr) {
-   throw new Error('Not implemented');
+    let sum = 0;
+    arr.map(elem =>
+    {
+        if (typeof(elem) == 'number' && elem > 0)
+            return sum++;
+    });
+    return sum;
 }
- 
-/** 
+
+/**
  * Sorts digit names
- * 
+ *
  * @param {array} arr
  * @return {array}
- * 
+ *
  * @example
  *   [] => []
  *   [ 'nine','one' ]                 => [ 'one', 'nine' ]
@@ -321,15 +371,19 @@ function getPositivesCount(arr) {
  *   [ 'one','one','one','zero' ]     => [ 'zero','one','one','one' ]
  */
 function sortDigitNamesByNumericOrder(arr) {
-   throw new Error('Not implemented');
+    let alph = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
+    return arr.sort((a, b) =>
+    {
+        return alph.indexOf(a)-alph.indexOf(b);
+    });
 }
 
-/** 
+/**
  * Returns the sum of all items in the specified array of numbers
- * 
+ *
  * @param {array} arr
  * @return {number}
- * 
+ *
  * @example
  *   [] => 0
  *   [ 1, 2, 3 ]           => 6
@@ -337,15 +391,15 @@ 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
- * 
+ *
  * @param {array} arr
  * @return {array}
- * 
+ *
  * @example
  *  [] => 0
  *  [ 1, '', 3 ] => 1
@@ -353,49 +407,51 @@ function getItemsSum(arr) {
  *  [ null, undefined, NaN, false, 0, '' ]  => 6
  */
 function getFalsyValuesCount(arr) {
-   throw new Error('Not implemented');
+    return arr.filter(function(value) {
+        return !Boolean(value);
+    }).length;
 }
 
 /**
- * Returns a number of all occurences of the specified item in an array  
- * 
+ * Returns a number of all occurences of the specified item in an array
+ *
  * @param {array} arr
- * @param {any} item 
+ * @param {any} item
  * @return {number}
- * 
+ *
  * @example
  *    [ 0, 0, 1, 1, 1, 2 ], 1 => 3
  *    [ 1, 2, 3, 4, 5 ], 0 => 0
  *    [ 'a','b','c','c' ], 'c'=> 2
- *    [ null, undefined, null ], null => 2 
+ *    [ null, undefined, null ], null => 2
  *    [ true, 0, 1, 'true' ], true => 1
  */
 function findAllOccurences(arr, item) {
-   throw new Error('Not implemented');
+    return arr.reduce(function(n, val) {return n + (val === item);}, 0);
 }
 
 /**
- * Concatenates all elements from specified array into single string with ',' delimeter  
- * 
- * @param {array} arr 
+ * Concatenates all elements from specified array into single string with ',' delimeter
+ *
+ * @param {array} arr
  * @return {string}
- * 
+ *
  * @example
  *    [0, false, 'cat', NaN, true, '']  => '0,false,cat,NaN,true,'
  *    [1, 2, 3, 4, 5]                   => '1,2,3,4,5'
  *    ['rock', 'paper', 'scissors']     => 'rock,paper,scissors'
  */
 function toStringList(arr) {
-   throw new Error('Not implemented');
+    return arr.join(',')
 }
 
 
 /**
  * Sorts the specified array by country name first and city name (if countries are equal) in ascending order.
- * 
+ *
  * @param {array} arr
  * @return {array}
- * 
+ *
  * @example
  *    [
  *      { country: 'Russia',  city: 'Moscow' },
@@ -404,7 +460,7 @@ function toStringList(arr) {
  *      { country: 'Russia',  city: 'Saint Petersburg' },
  *      { country: 'Poland',  city: 'Krakow' },
  *      { country: 'Belarus', city: 'Brest' }
- *    ]  
+ *    ]
  *                      =>
  *    [
  *      { country: 'Belarus', city: 'Brest' },
@@ -415,38 +471,54 @@ function toStringList(arr) {
  *      { country: 'Russia',  city: 'Saint Petersburg' }
  */
 function sortCitiesArray(arr) {
-   throw new Error('Not implemented');
+    return arr.sort(function (a, b) {
+        var aCountry = a.country;
+        var bCountry = b.country;
+        var aCity = a.city;
+        var bCity = b.city;
+
+        if(aCountry == bCountry) {
+            return (aCity < bCity) ? -1 : (aCity > bCity) ? 1 : 0;
+        }
+        else {
+            return (aCountry < bCountry) ? -1 : 1;
+        }
+    });
 }
 
 /**
  * Creates an indentity matrix of the specified size
- * 
+ *
  * @param {number} n
  * @return {array}
- * 
+ *
  * @example
  *     1  => [[1]]
- *  
+ *
  *     2 => [[1,0],
  *           [0,1]]
- * 
+ *
  *          [[1,0,0,0,0],
  *           [0,1,0,0,0],
  *     5 =>  [0,0,1,0,0],
  *           [0,0,0,1,0],
- *           [0,0,0,0,1]]   
+ *           [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);
+        });
+    });
 }
 
 /**
  * Creates an array of integers from the specified start to end (inclusive)
- * 
+ *
  * @param {number} start
  * @param {number} end
  * @return {array}
- * 
+ *
  * @example
  *     1, 5  => [ 1, 2, 3, 4, 5 ]
  *    -2, 2  => [ -2, -1, 0, 1, 2 ]
@@ -454,7 +526,12 @@ function getIdentityMatrix(n) {
  *     3, 3   => [ 3 ]
  */
 function getIntervalArray(start, end) {
-   throw new Error('Not implemented');
+    let arr = new Array(end - start + 1);
+    arr.fill(start);
+    return arr.map((elem, index) =>
+    {
+        return elem = index + start;
+    });
 }
 
 /**
@@ -462,14 +539,21 @@ function getIntervalArray(start, end) {
  *
  * @param {array} arr
  * @return {array}
- * 
+ *
  * @example
  *   [ 1, 2, 3, 3, 2, 1 ] => [ 1, 2, 3 ]
  *   [ 'a', 'a', 'a', 'a' ]  => [ 'a' ]
  *   [ 1, 1, 2, 2, 3, 3, 4, 4] => [ 1, 2, 3, 4]
  */
 function distinct(arr) {
-   throw new Error('Not implemented');
+    let myArr = [];
+    arr.map(elem =>
+    {
+        if (myArr.indexOf(elem) == -1)
+            myArr.push(elem);
+        return myArr;
+    });
+    return myArr;
 }
 
 /**
@@ -491,19 +575,27 @@ function distinct(arr) {
  *      { country: 'Belarus', city: 'Grodno' },
  *      { country: 'Belarus', city: 'Minsk' },
  *      { country: 'Poland', city: 'Lodz' }
- *     ], 
- *     item => item.country, 
+ *     ],
+ *     item => item.country,
  *     item => item.city
  *   )
- *            => 
+ *            =>
  *   Map {
  *    "Belarus" => ["Brest", "Grodno", "Minsk"],
- *    "Russia" => ["Omsk", "Samara"], 
+ *    "Russia" => ["Omsk", "Samara"],
  *    "Poland" => ["Lodz"]
  *   }
  */
 function group(array, keySelector, valueSelector) {
-   throw new Error('Not implemented');
+    let _map = new Map();
+    array.map((x, ind) =>
+    {
+        if( _map.has(keySelector(x)) )
+            _map.get(keySelector(x)).push(valueSelector(x));
+        else
+            _map.set(keySelector(x), [valueSelector(x)]);
+    });
+    return _map;
 }
 
 
@@ -513,13 +605,18 @@ function group(array, keySelector, valueSelector) {
  * @param {array} arr
  * @param {Function} childrenSelector, a transform function to apply to each element that returns an array of children
  * @return {array}
- * 
+ *
  * @example
  *   [[1, 2], [3, 4], [5, 6]], (x) => x     =>   [ 1, 2, 3, 4, 5, 6 ]
  *   ['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 myArr = [];
+    arr.map(elem =>
+    {
+        myArr.push(...childrenSelector(elem));
+    });
+    return myArr;
 }
 
 
@@ -529,37 +626,44 @@ function selectMany(arr, childrenSelector) {
  * @param {array} arr
  * @param {array} indexes
  * @return {any} element from array
- * 
+ *
  * @example
- *   [[1, 2], [3, 4], [5, 6]], [0,0]  => 1        (arr[0][0]) 
- *   ['one','two','three'], [2]       => 'three'  (arr[2]) 
+ *   [[1, 2], [3, 4], [5, 6]], [0,0]  => 1        (arr[0][0])
+ *   ['one','two','three'], [2]       => 'three'  (arr[2])
  *   [[[ 1, 2, 3]]], [ 0, 0, 1 ]      => 2        (arr[0][0][1])
  */
 function getElementByIndexes(arr, indexes) {
-    throw new Error('Not implemented');
+    if(indexes.length == 1)
+        return arr[indexes[0]];
+    else
+        return getElementByIndexes(arr[indexes[0]], indexes.splice(1, indexes.length - 1));
 }
 
 
 /**
  * Swaps the head and tail of the specified array:
- * the head (first half) of array move to the end, the tail (last half) move to the start. 
+ * the head (first half) of array move to the end, the tail (last half) move to the start.
  * The middle element (if exists) leave on the same position.
- * 
- *  
+ *
+ *
  * @param {array} arr
  * @return {array}
- * 
+ *
  * @example
  *   [ 1, 2, 3, 4, 5 ]   =>  [ 4, 5, 3, 1, 2 ]
- *    \----/   \----/         
- *     head     tail 
+ *    \----/   \----/
+ *     head     tail
+ *
+ *   [ 1, 2 ]  => [ 2, 1 ]
+ *   [ 1, 2, 3, 4, 5, 6, 7, 8 ]   =>  [ 5, 6, 7, 8, 1, 2, 3, 4 ]
  *
- *   [ 1, 2 ]  => [ 2, 1 ] 
- *   [ 1, 2, 3, 4, 5, 6, 7, 8 ]   =>  [ 5, 6, 7, 8, 1, 2, 3, 4 ]   
- * 
  */
 function swapHeadAndTail(arr) {
-    throw new Error('Not implemented');
+    let hlen = Math.floor(arr.length/2);
+    let headArr = arr.slice(0, hlen);
+    let middleArr = arr.slice(hlen, hlen + (arr.length & 1));
+    let tailArr = arr.slice(arr.length - hlen, arr.length);
+    return tailArr.concat(middleArr).concat(headArr);
 }
 
 
@@ -595,4 +699,4 @@ module.exports = {
     selectMany: selectMany,
     getElementByIndexes: getElementByIndexes,
     swapHeadAndTail: swapHeadAndTail
-};
+};
\ No newline at end of file
diff --git a/task/05-regex-tasks.js b/task/05-regex-tasks.js
index b1c60f2d4..777f58b88 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+',}');
 }
 
 
@@ -126,4 +127,4 @@ module.exports = {
     getRegexForIPv4: getRegexForIPv4,
     getRegexForSSN: getRegexForSSN,
     getPasswordValidator: getPasswordValidator
-};
+};
\ No newline at end of file
diff --git a/task/06-conditions-n-loops-tasks.js b/task/06-conditions-n-loops-tasks.js
index 249194c34..91f61e106 100644
--- a/task/06-conditions-n-loops-tasks.js
+++ b/task/06-conditions-n-loops-tasks.js
@@ -30,7 +30,16 @@
  *
  */
 function getFizzBuzz(num) {
-    throw new Error('Not implemented');
+    if (num % 3 == 0 && num % 5 == 0)
+        return 'FizzBuzz';
+    else
+    if (num % 3 == 0)
+        return 'Fizz';
+    else
+    if (num % 5 == 0)
+        return 'Buzz';
+    else
+        return num;
 }
 
 
@@ -46,7 +55,13 @@ 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 +78,12 @@ function getFactorial(n) {
  *   -1,1  =>  0  ( = -1 + 0 + 1 )
  */
 function getSumBetweenNumbers(n1, n2) {
-    throw new Error('Not implemented');
+    let sum = 0;
+    for (let i = n1; i <= n2; i++)
+    {
+        sum += i;
+    }
+    return sum;
 }
 
 
@@ -82,30 +102,30 @@ 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;
 }
 
 
 /**
  * Returns true, if two specified axis-aligned rectangles overlap, otherwise false.
- * Each rectangle representing by object 
+ * Each rectangle representing by object
  *  {
  *     top: 5,
  *     left: 5,
  *     width: 20,
  *     height: 10
  *  }
- * 
+ *
  *  (5;5)
- *     -------------  
- *     |           | 
+ *     -------------
+ *     |           |
  *     |           |  height = 10
- *     ------------- 
- *        width=20    
- * 
+ *     -------------
+ *        width=20
+ *
  * NOTE: Please use canvas coordinate space (https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes#The_grid),
  * it differs from Cartesian coordinate system.
- * 
+ *
  * @param {object} rect1
  * @param {object} rect2
  * @return {bool}
@@ -113,33 +133,34 @@ function isTriangle(a,b,c) {
  * @example:
  *   { top: 0, left: 0, width: 10, height: 10 },
  *   { top: 5, left: 5, width: 20, height: 20 }    =>  true
- * 
+ *
  *   { top: 0, left: 0, width: 10, height: 10 },
  *   { top:20, left:20, width: 20, height: 20 }    =>  false
- *  
+ *
  */
 function doRectanglesOverlap(rect1, rect2) {
-    throw new Error('Not implemented');
+    return (Math.max(rect1.left, rect2.left) <= Math.min(rect1.left + rect1.width, rect2.left + rect2.width) && Math.max(rect1.top, rect2.top) <=
+        Math.min(rect1.top + rect1.height, rect2.top + rect2.height));
 }
 
 
 /**
  * Returns true, if point lies inside the circle, otherwise false.
- * Circle is an object of 
+ * Circle is an object of
  *  {
  *     center: {
- *       x: 5,       
+ *       x: 5,
  *       y: 5
- *     },        
+ *     },
  *     radius: 20
  *  }
- * 
- * Point is object of 
+ *
+ * Point is object of
  *  {
  *     x: 5,
  *     y: 5
  *  }
- * 
+ *
  * @param {object} circle
  * @param {object} point
  * @return {bool}
@@ -147,10 +168,12 @@ function doRectanglesOverlap(rect1, rect2) {
  * @example:
  *   { center: { x:0, y:0 }, radius:10 },  { x:0, y:0 }     => true
  *   { center: { x:0, y:0 }, radius:10 },  { x:10, y:10 }   => false
- *   
+ *
  */
 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 +189,29 @@ function isInsideCircle(circle, point) {
  *   'entente' => null
  */
 function findFirstSingleChar(str) {
-    throw new Error('Not implemented');
+    let charArr = [];
+    let countArr = [];
+    let isExst;
+    for (let i = 0; i < str.length; i++)
+    {
+        isExst = false;
+        if (charArr.indexOf(str[i]) != -1)
+        {
+            isExst = true;
+            countArr[charArr.indexOf(str[i])] += 1;
+        }
+        if (!isExst)
+        {
+            charArr.push(str[i]);
+            countArr.push(1);
+        }
+    }
+    for (let i = 0; i<countArr.length; i++)
+    {
+        if (countArr[i] == 1)
+            return charArr[i];
+    }
+    return null;
 }
 
 
@@ -192,7 +237,26 @@ function findFirstSingleChar(str) {
  *
  */
 function getIntervalString(a, b, isStartIncluded, isEndIncluded) {
-    throw new Error('Not implemented');
+    let tempStr = '';
+    let tempEndStr = '';
+    if (isStartIncluded)
+        tempStr = '[';
+    else
+        tempStr = '(';
+    if (isEndIncluded)
+        tempEndStr = ']';
+    else
+        tempEndStr = ')';
+    if(a > b)
+    {
+        tempStr += b + ', ' + a + tempEndStr;
+    }
+    else
+    {
+        tempStr += a + ', ' + b + tempEndStr;
+    }
+    return tempStr;
+
 }
 
 
@@ -209,7 +273,7 @@ function getIntervalString(a, b, isStartIncluded, isEndIncluded) {
  * 'noon' => 'noon'
  */
 function reverseString(str) {
-    throw new Error('Not implemented');
+    return [...str].reverse().join('');
 }
 
 
@@ -226,7 +290,9 @@ function reverseString(str) {
  *   34143 => 34143
  */
 function reverseInteger(num) {
-    throw new Error('Not implemented');
+    let str = '';
+    str += num;
+    return [...str].reverse().join('');
 }
 
 
@@ -251,7 +317,17 @@ 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 +346,15 @@ 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;
 }
 
 
@@ -293,10 +377,29 @@ function getDigitalRoot(num) {
  *   '[[][][[]]]' => true
  *   '[[][]][' => false
  *   '{)' = false
- *   '{[(<{[]}>)]}' = true 
+ *   '{[(<{[]}>)]}' = 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 +435,49 @@ function isBracketsBalanced(str) {
  *
  */
 function timespanToHumanString(startDate, endDate) {
-    throw new Error('Not implemented');
+    let ms_in = {
+        s:  1000,
+        m:  60000,
+        h:  3600000,
+        d:  86400000,
+        mn: 2592000000,
+        y:  31104000000
+    }
+    function rnd(x){
+        return -Math.round(-x);
+    }
+    let t = endDate.getTime() - startDate.getTime();
+    if (t >= 546 * ms_in.d)
+        return rnd(t/ms_in.y) + ' years ago';
+    else
+    if(345 * ms_in.d < t && t <= 545  * ms_in.d)
+        return 'a year ago';
+    else
+    if(45 * ms_in.d < t && t <= 345 * ms_in.d)
+        return rnd(t/ms_in.mn) + ' months ago';
+    else
+    if(25 * ms_in.d < t && t <= 45 * ms_in.d)
+        return 'a month ago';
+    else
+    if(36 * ms_in.h < t && t <= 25 * ms_in.d)
+        return rnd(t/ms_in.d) + ' days ago';
+    else
+    if(22 * ms_in.h < t && t <= 36 * ms_in.h)
+        return 'a day ago';
+    else
+    if(90 * ms_in.m < t && t <= 22 * ms_in.h)
+        return rnd(t/ms_in.h) + ' hours ago';
+    else
+    if(45 * ms_in.m < t && t <= 90 * ms_in.m)
+        return 'an hour ago';
+    else
+    if(90 * ms_in.s < t && t <= 45 * ms_in.m)
+        return rnd(t/ms_in.m) + ' minutes ago';
+    else
+    if(45 * ms_in.s < t && t <= 90 * ms_in.s)
+        return 'a minute ago';
+    else
+        return 'a few seconds ago';
 }
 
 
@@ -356,7 +501,7 @@ function timespanToHumanString(startDate, endDate) {
  *    365, 10 => '365'
  */
 function toNaryString(num, n) {
-    throw new Error('Not implemented');
+    return num.toString(n);
 }
 
 
@@ -396,7 +541,21 @@ function getCommonDirectoryPath(pathes) {
  *
  */
 function getMatrixProduct(m1, m2) {
-    throw new Error('Not implemented');
+    let n = m1.length, m = m2[0].length;
+    let ans = new Array(n);
+    for (let i=0; i < n; i++)
+    {
+        ans[i]=new Array(m);
+    }
+    for (let i = 0; i < m; i++)
+        for (let j = 0; j < n; j++)
+            ans[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++)
+                ans[i][j] += m1[i][k] * m2[k][j];
+    return ans;
 }
 
 
@@ -431,7 +590,29 @@ 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;
 }
 
 
@@ -454,4 +635,4 @@ module.exports = {
     getCommonDirectoryPath: getCommonDirectoryPath,
     getMatrixProduct: getMatrixProduct,
     evaluateTicTacToePosition : evaluateTicTacToePosition
-};
+};
\ No newline at end of file