Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 5ac898f

Browse files
Merge branch 'TheAlgorithms:master' into master
2 parents e99c722 + d94929e commit 5ac898f

File tree

13 files changed

+188
-60
lines changed

13 files changed

+188
-60
lines changed

‎.github/workflows/Ci.yml‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ jobs:
1111
name: Code style and tests
1212
runs-on: ubuntu-latest
1313
steps:
14-
- uses: actions/checkout@v2
15-
- uses: actions/setup-node@v2
14+
- uses: actions/checkout@v3
15+
- uses: actions/setup-node@v3
1616
with:
1717
node-version: "16.x"
1818
cache: npm
@@ -30,7 +30,7 @@ jobs:
3030
name: Check for spelling errors
3131
runs-on: ubuntu-latest
3232
steps:
33-
- uses: actions/checkout@v2
33+
- uses: actions/checkout@v3
3434
- uses: codespell-project/actions-codespell@master
3535
with:
3636
# file types to ignore

‎Bit-Manipulation/LogTwo.js‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* https://handwiki.org/wiki/Binary_logarithm
3+
* Approximate log2 using only bitwise operators
4+
* @param {number} n
5+
* @returns {number} Log2 approximation equal to floor(log2(n))
6+
*/
7+
export const logTwo = (n) => {
8+
let result = 0
9+
while (n >> 1) {
10+
n >>= 1
11+
result++
12+
}
13+
return result
14+
}

‎Bit-Manipulation/test/LogTwo.test.js‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { logTwo } from '../LogTwo'
2+
3+
for (let i = 1; i < 100; i++) {
4+
test('log2(' + i + ')', () => {
5+
expect(logTwo(i)).toBe(Math.floor(Math.log2(i)))
6+
})
7+
}

‎Ciphers/CaesarsCipher.js‎ renamed to ‎Ciphers/CaesarCipher.js‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* @param {number} rotation - the number of rotation, expect real number ( > 0)
77
* @return {string} - decrypted string
88
*/
9-
const caesarsCipher = (str, rotation) => {
9+
const caesarCipher = (str, rotation) => {
1010
if (typeof str !== 'string' || !Number.isInteger(rotation) || rotation < 0) {
1111
throw new TypeError('Arguments are invalid')
1212
}
@@ -29,4 +29,4 @@ const caesarsCipher = (str, rotation) => {
2929
})
3030
}
3131

32-
export default caesarsCipher
32+
export default caesarCipher

‎Ciphers/test/CaesarCipher.test.js‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import caesarCipher from '../CaesarCipher'
2+
3+
describe('Testing the caesarsCipher function', () => {
4+
it('Test - 1, Testing for invalid types', () => {
5+
expect(() => caesarCipher(false, 3)).toThrow()
6+
expect(() => caesarCipher('false', -1)).toThrow()
7+
expect(() => caesarCipher('true', null)).toThrow()
8+
})
9+
10+
it('Test - 2, Testing for valid string and rotation', () => {
11+
expect(caesarCipher('middle-Outz', 2)).toBe('okffng-Qwvb')
12+
expect(caesarCipher('abcdefghijklmnopqrstuvwxyz', 3)).toBe('defghijklmnopqrstuvwxyzabc')
13+
expect(caesarCipher('Always-Look-on-the-Bright-Side-of-Life', 5)).toBe('Fqbfdx-Qttp-ts-ymj-Gwnlmy-Xnij-tk-Qnkj')
14+
expect(caesarCipher('THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG', 23)).toBe('QEB NRFZH YOLTK CLU GRJMP LSBO QEB IXWV ALD')
15+
})
16+
})

‎Ciphers/test/CaesarsCipher.test.js‎

Lines changed: 0 additions & 16 deletions
This file was deleted.

‎Conversions/DateToDay.js‎

Lines changed: 33 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,54 +9,52 @@
99
algorithm shown below gives us the number of the day and
1010
finally converts it to the name of the day.
1111
12-
Algorithm & Explanation : https://cs.uwaterloo.ca/~alopez-o/math-faq/node73.html
12+
Algorithm & Explanation : https://en.wikipedia.org/wiki/Zeller%27s_congruence
1313
*/
1414

15-
// March is taken as the first month of the year.
16-
const calcMonthList = {
17-
1: 11,
18-
2: 12,
19-
3: 1,
20-
4: 2,
21-
5: 3,
22-
6: 4,
23-
7: 5,
24-
8: 6,
25-
9: 7,
26-
10: 8,
27-
11: 9,
28-
12: 10
29-
}
30-
31-
// show the week day in a number : Sunday - Saturday => 0 - 6
32-
const daysNameList = { // weeks-day
33-
0: 'Sunday',
34-
1: 'Monday',
35-
2: 'Tuesday',
36-
3: 'Wednesday',
37-
4: 'Thursday',
38-
5: 'Friday',
39-
6: 'Saturday'
40-
}
15+
// Array holding name of the day: Saturday - Sunday - Friday => 0 - 1 - 6
16+
const daysNameArr = ['Saturday', 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
4117

4218
const DateToDay = (date) => {
4319
// firstly, check that input is a string or not.
4420
if (typeof date !== 'string') {
4521
return new TypeError('Argument is not a string.')
4622
}
4723
// extract the date
48-
const [day, month, year] = date.split('/').map((x) => Number(x))
24+
let [day, month, year] = date.split('/').map((x) => Number(x))
4925
// check the data are valid or not.
50-
if (day < 0 || day > 31 || month > 12 || month < 0) {
26+
if (day < 1 || day > 31 || month > 12 || month < 1) {
5127
return new TypeError('Date is not valid.')
5228
}
53-
// divide year to century and yearDigit value.
54-
const yearDigit = (year % 100)
29+
30+
// In case of Jan and Feb:
31+
// Year: we consider it as previous year
32+
// e.g., 1/1/1987 here year is 1986 (-1)
33+
// Month: we consider value as 13 & 14 respectively
34+
if (month < 3) {
35+
year--
36+
month += 12
37+
}
38+
39+
// divide year into century and the last two digits of the century
40+
const yearDigits = year % 100
5541
const century = Math.floor(year / 100)
56-
// Apply the algorithm shown above
57-
const weekDay = Math.abs((day + Math.floor((2.6 * calcMonthList[month]) - 0.2) - (2 * century) + yearDigit + Math.floor(yearDigit / 4) + Math.floor(century / 4)) % 7)
58-
// return the weekDay name.
59-
return daysNameList[weekDay]
42+
43+
/*
44+
In mathematics, remainders of divisions are usually defined to always be positive;
45+
As an example, -2 mod 7 = 5.
46+
Many programming languages including JavaScript implement the remainder of `n % m` as `sign(n) * (abs(n) % m)`.
47+
This means the result has the same sign as the numerator. Here, `-2 % 7 = -1 * (2 % 7) = -2`.
48+
49+
To ensure a positive numerator, the formula is adapted: `- 2 * century` is replaced with `+ 5 * century`
50+
which does not alter the resulting numbers mod 7 since `7 - 2 = 5`
51+
52+
The following example shows the issue with modulo division:
53+
Without the adaption, the formula yields `weekDay = -6` for the date 2/3/2014;
54+
With the adaption, it yields the positive result `weekDay = 7 - 6 = 1` (Sunday), which is what we need to index the array
55+
*/
56+
const weekDay = (day + Math.floor((month + 1) * 2.6) + yearDigits + Math.floor(yearDigits / 4) + Math.floor(century / 4) + 5 * century) % 7
57+
return daysNameArr[weekDay] // name of the weekday
6058
}
6159

6260
// Example : DateToDay("18/12/2020") => Friday

‎Conversions/test/DateToDay.test.js‎

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { DateToDay } from '../DateToDay'
22

3-
test('The date 18/02/2001 is Monday', () => {
3+
test('The date 18/02/2001 is Sunday', () => {
44
const res = DateToDay('18/02/2001')
5-
expect(res).toBe('Monday')
5+
expect(res).toBe('Sunday')
66
})
77

88
test('The date 18/12/2020 is Friday', () => {
@@ -14,7 +14,22 @@ test('The date 12/12/2012 is Wednesday', () => {
1414
const res = DateToDay('12/12/2012')
1515
expect(res).toBe('Wednesday')
1616
})
17-
test('The date 01/01/2001 is Friday', () => {
17+
test('The date 01/01/2001 is Monday', () => {
1818
const res = DateToDay('01/01/2001')
19-
expect(res).toBe('Friday')
19+
expect(res).toBe('Monday')
20+
})
21+
22+
test('The date 1/1/2020 is Wednesday', () => {
23+
const res = DateToDay('1/1/2020')
24+
expect(res).toBe('Wednesday')
25+
})
26+
27+
test('The date 2/3/2014 is Sunday', () => {
28+
const res = DateToDay('2/3/2014')
29+
expect(res).toBe('Sunday')
30+
})
31+
32+
test('The date 28/2/2017 is Tuesday', () => {
33+
const res = DateToDay('28/2/2017')
34+
expect(res).toBe('Tuesday')
2035
})
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Author: IcarusTheFly (https://github.com/IcarusTheFly)
3+
* Catalan Numbers explanation can be found in the following links:
4+
* Wikipedia: https://en.wikipedia.org/wiki/Catalan_number
5+
* Brilliant: https://brilliant.org/wiki/catalan-numbers
6+
*/
7+
8+
/**
9+
* @function catalanNumbers
10+
* @description Returns all catalan numbers from index 0 to n
11+
* @param {number} n
12+
* @returns {number[]} Array with the catalan numbers from 0 to n
13+
*/
14+
15+
export const catalanNumbers = (n) => {
16+
if (n === 0) {
17+
return [1]
18+
}
19+
const catList = [1, 1]
20+
21+
for (let i = 2; i <= n; i++) {
22+
let newNumber = 0
23+
for (let j = 0; j < i; j++) {
24+
newNumber += catList[j] * catList[i - j - 1]
25+
}
26+
catList.push(newNumber)
27+
}
28+
29+
return catList
30+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { catalanNumbers } from '../CatalanNumbers'
2+
3+
describe('Testing catalanNumbers function', () => {
4+
test('should return the expected array for inputs from 0 to 20', () => {
5+
const expectedOutput = [
6+
1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900,
7+
2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420
8+
]
9+
10+
for (let i = 0; i <= 20; i++) {
11+
expect(catalanNumbers(i)).toStrictEqual(expectedOutput.slice(0, i + 1))
12+
}
13+
})
14+
})

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /