Skip to content

Commit 9f6b7d7

Browse files
authored
Merge branch 'master' into optimising
2 parents 5fe6169 + 5641b6f commit 9f6b7d7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+1899
-418
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
* @raklaptudirm
1+
* @raklaptudirm @appgurueu

.github/stale.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
# Number of days of inactivity before an issue becomes stale (a week)
2-
daysUntilStale: 7
1+
# Number of days of inactivity before an issue becomes stale (2 weeks)
2+
daysUntilStale: 14
33
# Number of days of inactivity before a stale issue is closed (a week)
44
daysUntilClose: 7
55
# Issues with these labels will never be considered stale
@@ -8,7 +8,7 @@ exemptLabels:
88
- help wanted
99
- OK to merge
1010
# Label to use when marking an issue as stale
11-
staleLabel: wontfix
11+
staleLabel: stale
1212
# Comment to post when marking an issue as stale. Set to `false` to disable
1313
markComment: >
1414
This issue has been automatically marked as stale because it has not had

.github/workflows/Ci.yml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
name: Continuous Integration
22

3-
on: [push, pull_request]
3+
on:
4+
push:
5+
branches:
6+
- master
7+
pull_request:
48

59
jobs:
610
build:
11+
name: Code style and tests
712
runs-on: ubuntu-latest
813
steps:
914
- uses: actions/checkout@v2
@@ -20,3 +25,14 @@ jobs:
2025

2126
- name: 💄 Code style
2227
run: npm run style
28+
29+
codespell:
30+
name: Check for spelling errors
31+
runs-on: ubuntu-latest
32+
steps:
33+
- uses: actions/checkout@v2
34+
- uses: codespell-project/actions-codespell@master
35+
with:
36+
# file types to ignore
37+
skip: "*.json,*.yml,DIRECTORY.md"
38+
ignore_words_list: "ba,esy,yse"

.github/workflows/Codespell.yml

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

.github/workflows/UpdateDirectory.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
# This GitHub Action updates the DIRECTORY.md file (if needed) when doing a git push
22
name: Update Directory
33

4-
on: [push]
4+
on:
5+
push:
6+
branches:
7+
- master
58

69
jobs:
710
updateDirectory:

Cache/LRUCache.js

Lines changed: 120 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,146 @@
11
class LRUCache {
22
// LRU Cache to store a given capacity of data
3+
#capacity
4+
5+
/**
6+
* @param {number} capacity - the capacity of LRUCache
7+
* @returns {LRUCache} - sealed
8+
*/
39
constructor (capacity) {
4-
this.cache = new Map()
5-
this.capacity = capacity
10+
if (!Number.isInteger(capacity) || capacity < 0) {
11+
throw new TypeError('Invalid capacity')
12+
}
13+
14+
this.#capacity = ~~capacity
15+
this.misses = 0
616
this.hits = 0
7-
this.miss = 0
17+
this.cache = new Map()
18+
19+
return Object.seal(this)
20+
}
21+
22+
get info () {
23+
return Object.freeze({
24+
misses: this.misses,
25+
hits: this.hits,
26+
capacity: this.capacity,
27+
size: this.size
28+
})
29+
}
30+
31+
get size () {
32+
return this.cache.size
833
}
934

10-
cacheInfo () {
11-
// Return the details for the cache instance [hits, misses, capacity, current_size]
12-
return `CacheInfo(hits=${this.hits}, misses=${this.miss}, capacity=${this.capacity}, current size=${this.cache.size})`
35+
get capacity () {
36+
return this.#capacity
1337
}
1438

39+
set capacity (newCapacity) {
40+
if (newCapacity < 0) {
41+
throw new RangeError('Capacity should be greater than 0')
42+
}
43+
44+
if (newCapacity < this.capacity) {
45+
let diff = this.capacity - newCapacity
46+
47+
while (diff--) {
48+
this.#removeLeastRecentlyUsed()
49+
}
50+
}
51+
52+
this.#capacity = newCapacity
53+
}
54+
55+
/**
56+
* delete oldest key existing in map by the help of iterator
57+
*/
58+
#removeLeastRecentlyUsed () {
59+
this.cache.delete(this.cache.keys().next().value)
60+
}
61+
62+
/**
63+
* @param {string} key
64+
* @returns {*}
65+
*/
66+
has (key) {
67+
key = String(key)
68+
69+
return this.cache.has(key)
70+
}
71+
72+
/**
73+
* @param {string} key
74+
* @param {*} value
75+
*/
1576
set (key, value) {
77+
key = String(key)
1678
// Sets the value for the input key and if the key exists it updates the existing key
17-
if (this.cache.size === this.capacity) {
18-
// delete oldest key existing in map
19-
this.cache.delete(this.cache.keys().next().value)
79+
if (this.size === this.capacity) {
80+
this.#removeLeastRecentlyUsed()
2081
}
82+
2183
this.cache.set(key, value)
2284
}
2385

86+
/**
87+
* @param {string} key
88+
* @returns {*}
89+
*/
2490
get (key) {
91+
key = String(key)
2592
// Returns the value for the input key. Returns null if key is not present in cache
2693
if (this.cache.has(key)) {
2794
const value = this.cache.get(key)
95+
2896
// refresh the cache to update the order of key
2997
this.cache.delete(key)
3098
this.cache.set(key, value)
31-
this.hits += 1
99+
100+
this.hits++
32101
return value
33-
} else {
34-
this.miss += 1
35-
return null
36102
}
103+
104+
this.misses++
105+
return null
106+
}
107+
108+
/**
109+
* @param {JSON} json
110+
* @returns {LRUCache}
111+
*/
112+
parse (json) {
113+
const { misses, hits, cache } = JSON.parse(json)
114+
115+
this.misses += misses ?? 0
116+
this.hits += hits ?? 0
117+
118+
for (const key in cache) {
119+
this.set(key, cache[key])
120+
}
121+
122+
return this
123+
}
124+
125+
/**
126+
* @param {number} indent
127+
* @returns {JSON} - string
128+
*/
129+
toString (indent) {
130+
const replacer = (_, value) => {
131+
if (value instanceof Set) {
132+
return [...value]
133+
}
134+
135+
if (value instanceof Map) {
136+
return Object.fromEntries(value)
137+
}
138+
139+
return value
140+
}
141+
142+
return JSON.stringify(this, replacer, indent)
37143
}
38144
}
39145

40-
export { LRUCache }
146+
export default LRUCache

Cache/test/LRUCache.test.js

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
1-
import { LRUCache } from '../LRUCache'
1+
import LRUCache from '../LRUCache'
22
import { fibonacciCache } from './cacheTest'
33

4-
describe('LRUCache', () => {
5-
it('Example 1 (Small Cache, size=2)', () => {
6-
const cache = new LRUCache(2)
4+
describe('Testing LRUCache', () => {
5+
it('Testing with invalid capacity', () => {
6+
expect(() => new LRUCache()).toThrow()
7+
expect(() => new LRUCache('Invalid')).toThrow()
8+
expect(() => new LRUCache(-1)).toThrow()
9+
expect(() => new LRUCache(Infinity)).toThrow()
10+
})
11+
12+
it('Example 1 (Small Cache, size = 2)', () => {
13+
const cache = new LRUCache(1) // initially capacity
14+
15+
cache.capacity++ // now the capacity is increasing by one
16+
717
cache.set(1, 1)
818
cache.set(2, 2)
919

@@ -24,14 +34,41 @@ describe('LRUCache', () => {
2434
expect(cache.get(3)).toBe(3)
2535
expect(cache.get(4)).toBe(4)
2636

27-
expect(cache.cacheInfo()).toBe('CacheInfo(hits=6, misses=3, capacity=2, current size=2)')
37+
expect(cache.info).toEqual({
38+
misses: 3,
39+
hits: 6,
40+
capacity: 2,
41+
size: 2
42+
})
43+
44+
const json = '{"misses":3,"hits":6,"cache":{"3":3,"4":4}}'
45+
expect(cache.toString()).toBe(json)
46+
47+
// merge with json
48+
cache.parse(json)
49+
50+
cache.capacity-- // now the capacity decreasing by one
51+
52+
expect(cache.info).toEqual({
53+
misses: 6,
54+
hits: 12,
55+
capacity: 1,
56+
size: 1
57+
})
2858
})
2959

30-
it('Example 2 (Computing Fibonacci Series, size=100)', () => {
60+
it('Example 2 (Computing Fibonacci Series, size = 100)', () => {
3161
const cache = new LRUCache(100)
62+
3263
for (let i = 1; i <= 100; i++) {
3364
fibonacciCache(i, cache)
3465
}
35-
expect(cache.cacheInfo()).toBe('CacheInfo(hits=193, misses=103, capacity=100, current size=98)')
66+
67+
expect(cache.info).toEqual({
68+
misses: 103,
69+
hits: 193,
70+
capacity: 100,
71+
size: 98
72+
})
3673
})
3774
})

Ciphers/Atbash.js

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,24 @@
1-
/*
2-
The Atbash cipher is a particular type of monoalphabetic cipher
3-
formed by taking the alphabet and mapping it to its reverse,
4-
so that the first letter becomes the last letter,
5-
the second letter becomes the second to last letter, and so on.
6-
*/
7-
81
/**
9-
* Decrypt a Atbash cipher
10-
* @param {String} str - string to be decrypted/encrypt
11-
* @return {String} decrypted/encrypted string
2+
* @function Atbash - Decrypt a Atbash cipher
3+
* @description - The Atbash cipher is a particular type of monoalphabetic cipher formed by taking the alphabet and mapping it to its reverse, so that the first letter becomes the last letter, the second letter becomes the second to last letter, and so on.
4+
* @param {string} str - string to be decrypted/encrypt
5+
* @return {string} decrypted/encrypted string
6+
* @see - [wiki](https://en.wikipedia.org/wiki/Atbash)
127
*/
13-
function Atbash (message) {
14-
let decodedString = ''
15-
for (let i = 0; i < message.length; i++) {
16-
if (/[^a-zA-Z]/.test(message[i])) {
17-
decodedString += message[i]
18-
} else if (message[i] === message[i].toUpperCase()) {
19-
decodedString += String.fromCharCode(90 + 65 - message.charCodeAt(i))
20-
} else {
21-
decodedString += String.fromCharCode(122 + 97 - message.charCodeAt(i))
22-
}
8+
const Atbash = (str) => {
9+
if (typeof str !== 'string') {
10+
throw new TypeError('Argument should be string')
2311
}
24-
return decodedString
25-
}
2612

27-
export { Atbash }
13+
return str.replace(/[a-z]/gi, (char) => {
14+
const charCode = char.charCodeAt()
15+
16+
if (/[A-Z]/.test(char)) {
17+
return String.fromCharCode(90 + 65 - charCode)
18+
}
19+
20+
return String.fromCharCode(122 + 97 - charCode)
21+
})
22+
}
2823

29-
// > Atbash('HELLO WORLD')
30-
// 'SVOOL DLIOW'
24+
export default Atbash

0 commit comments

Comments
 (0)