Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ds-algo #1856

Merged
merged 1 commit into from
Mar 13, 2022
Merged

ds-algo #1856

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
50 changes: 50 additions & 0 deletions docs/content/DS_ALGO/algorithms/Conversions/ArbitraryBase.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* Converts a string from one base to other
* @param {string} stringInBaseOne String in input base
* @param {string} baseOneCharacters Character set for the input base
* @param {string} baseTwoCharacters Character set for the output base
* @returns {string}
*/
const convertArbitraryBase = (stringInBaseOne, baseOneCharacters, baseTwoCharacters) => {
if ([stringInBaseOne, baseOneCharacters, baseTwoCharacters].map((arg) => typeof arg).some((type) => type !== 'string')) {
throw new TypeError('Only string arguments are allowed');
}
[baseOneCharacters, baseTwoCharacters].forEach((baseString) => {
const charactersInBase = [...baseString];
if (charactersInBase.length !== new Set(charactersInBase).size) {
throw new TypeError('Duplicate characters in character set are not allowed');
}
});
const reversedStringOneChars = [...stringInBaseOne].reverse();
const stringOneBase = baseOneCharacters.length;
let value = 0;
let placeValue = 1;
for (const digit of reversedStringOneChars) {
const digitNumber = baseOneCharacters.indexOf(digit);
if (digitNumber === -1) {
throw new TypeError(`Not a valid character: ${digit}`);
}
value += digitNumber * placeValue;
placeValue *= stringOneBase;
}
let stringInBaseTwo = '';
const stringTwoBase = baseTwoCharacters.length;
while (value > 0) {
const remainder = value % stringTwoBase;
stringInBaseTwo = baseTwoCharacters.charAt(remainder) + stringInBaseTwo;
value /= stringTwoBase;
}
const baseTwoZero = baseTwoCharacters.charAt(0);
return stringInBaseTwo.replace(new RegExp(`^${baseTwoZero}+`), '');
};

export { convertArbitraryBase };

// > convertArbitraryBase('98', '0123456789', '01234567')
// '142'

// > convertArbitraryBase('98', '0123456789', 'abcdefgh')
// 'bec'

// > convertArbitraryBase('129', '0123456789', '01234567')
// '201'
37 changes: 37 additions & 0 deletions docs/content/DS_ALGO/algorithms/Conversions/ArrayBufferToBase64.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// About base64: https://en.wikipedia.org/wiki/Base64

/**
* Converts an array of bytes to base64 encoding
* @param {ArrayBuffer} binaryData An ArrayBuffer which represents an array of bytes
* @returns {string} A string containing the base64 encoding of `binaryData`
*/
function bufferToBase64(binaryData) {
// The base64 encoding uses the following set of characters to encode any binary data as text
const base64Table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
// Every 3 bytes translates to 4 base64 characters, if we have less than 3 bytes we must append '=' chars as padding
const padding = 3 - (binaryData.byteLength % 3);
// Create an instance of Uint8Array, to read from the binaryData array buffer
const byteView = new Uint8Array(binaryData);
let result = '';

// Loop through all bytes in the buffer, in increments of 3 bytes
for (let i = 0; i < byteView.byteLength; i += 3) {
// Get the index for the next 4 base64 chars
const char1 = (byteView[i] & 252) >> 2;
const char2 = ((byteView[i] & 3) << 4) + ((byteView[i + 1] & 240) >> 4);
const char3 = ((byteView[i + 1] & 15) << 2) + ((byteView[i + 2] & 192) >> 6);
const char4 = byteView[i + 2] & 63;

result += base64Table[char1] + base64Table[char2] + base64Table[char3] + base64Table[char4];
}

// Add padding '=' chars if needed
if (padding !== 3) {
const paddedResult = result.slice(0, result.length - padding) + '='.repeat(padding);
return paddedResult;
}

return result;
}

export { bufferToBase64 };
47 changes: 47 additions & 0 deletions docs/content/DS_ALGO/algorithms/Conversions/Base64ToArrayBuffer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// About base64: https://en.wikipedia.org/wiki/Base64

/**
* Converts a base64 string to an array of bytes
* @param {string} b64 A base64 string
* @returns {ArrayBuffer} An ArrayBuffer representing the bytes encoded by the base64 string
*/
function base64ToBuffer(b64) {
// The base64 encoding uses the following set of characters to encode any binary data as text
const base64Table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
// Find the index of char '=' first occurrence
const paddingIdx = b64.indexOf('=');
// Remove padding chars from base64 string, if there are any
const b64NoPadding = paddingIdx !== -1 ? b64.slice(0, paddingIdx) : b64;
// Calculate the length of the result buffer
const bufferLength = Math.floor((b64NoPadding.length * 6) / 8);
// Create the result buffer
const result = new ArrayBuffer(bufferLength);
// Create an instance of Uint8Array, to write to the `result` buffer
const byteView = new Uint8Array(result);

// Loop through all chars in the base64 string, in increments of 4 chars, and in increments of 3 bytes
for (let i = 0, j = 0; i < b64NoPadding.length; i += 4, j += 3) {
// Get the index of the next 4 base64 chars
const b64Char1 = base64Table.indexOf(b64NoPadding[i]);
const b64Char2 = base64Table.indexOf(b64NoPadding[i + 1]);
let b64Char3 = base64Table.indexOf(b64NoPadding[i + 2]);
let b64Char4 = base64Table.indexOf(b64NoPadding[i + 3]);

// If base64 chars 3 and 4 don't exit, then set them to 0
if (b64Char3 === -1) b64Char3 = 0;
if (b64Char4 === -1) b64Char4 = 0;

// Calculate the next 3 bytes
const byte1 = (b64Char1 << 2) + ((b64Char2 & 48) >> 4);
const byte2 = ((b64Char2 & 15) << 4) + ((b64Char3 & 60) >> 2);
const byte3 = ((b64Char3 & 3) << 6) + b64Char4;

byteView[j] = byte1;
byteView[j + 1] = byte2;
byteView[j + 2] = byte3;
}

return result;
}

export { base64ToBuffer };
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export default function binaryToDecimal(binaryString) {
let decimalNumber = 0;
const binaryDigits = binaryString.split('').reverse(); // Splits the binary number into reversed single digits
binaryDigits.forEach((binaryDigit, index) => {
decimalNumber += binaryDigit * Math.pow(2, index); // Summation of all the decimal converted digits
});
return decimalNumber;
}
75 changes: 75 additions & 0 deletions docs/content/DS_ALGO/algorithms/Conversions/BinaryToHex.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
const pad = (num, padlen) => {
const pad = new Array(1 + padlen).join(0);
return (pad + num).slice(-pad.length);
};

const hexLookup = (bin) => {
let binary = bin;
if (binary.length < 4) {
binary = pad(binary, 4);
}
switch (binary) {
case '0000':
return '0';
case '0001':
return '1';
case '0010':
return '2';
case '0011':
return '3';
case '0100':
return '4';
case '0101':
return '5';
case '0110':
return '6';
case '0111':
return '7';
case '1000':
return '8';
case '1001':
return '9';
case '1010':
return 'A';
case '1011':
return 'B';
case '1100':
return 'C';
case '1101':
return 'D';
case '1110':
return 'E';
case '1111':
return 'F';
}
};
const binaryToHex = (binaryString) => {
/*
Function for convertung Binary to Hex

1. The conversion will start from Least Significant Digit (LSB) to the Most Significant Bit (MSB).
2. We divide the bits into sections of 4-bits starting from LSB to MSB.
3. If the MSB get less than 4 bits, then we pad 0s to the front of it.

For Example:
Binary String = '1001101'

1. Divide it to 2 parts => ['100', '1101']
2. Pad 0s the MSB so it'll be => ['0100', '1101']
3. Use the lookup table and merge them, therefore the result is 4D.

*/

let result = '';
binaryString = binaryString.split('');
for (let i = binaryString.length - 1; i >= 0; i = i - 4) {
if (i >= 3) {
result += hexLookup(binaryString.slice(i - 3, i + 1).join(''));
} else {
result += hexLookup(binaryString.slice(0, i + 1).join(''));
}
}
return result.split('').reverse().join('');
};

export default binaryToHex;
49 changes: 49 additions & 0 deletions docs/content/DS_ALGO/algorithms/Conversions/DateDayDifference.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
DateDayDifference Method
------------------------
DateDayDifference method calculates the number of days between two dates.

Algorithm & Explanation : https://ncalculators.com/time-date/date-difference-calculator.htm
*/

// Internal method for make calculations easier
const isLeap = (year) => {
if (year % 400 === 0) return true;
else if (year % 100 === 0) return false;
else if (year % 4 === 0) return true;
else return false;
};
const DateToDay = (dd, mm, yyyy) => {
return Math.floor(
365 * (yyyy - 1) + (yyyy - 1) / 4 - (yyyy - 1) / 100 + (yyyy - 1) / 400 + dd + (367 * mm - 362) / 12 + (mm <= 2 ? 0 : isLeap(yyyy) ? -1 : -2)
);
};

const DateDayDifference = (date1, date2) => {
// firstly, check that both input are string or not.
if (typeof date1 !== 'string' && typeof date2 !== 'string') {
return new TypeError('Argument is not a string.');
}
// extract the first date
const [firstDateDay, firstDateMonth, firstDateYear] = date1.split('/').map((ele) => Number(ele));
// extract the second date
const [secondDateDay, secondDateMonth, secondDateYear] = date2.split('/').map((ele) => Number(ele));
// check the both data are valid or not.
if (
firstDateDay < 0 ||
firstDateDay > 31 ||
firstDateMonth > 12 ||
firstDateMonth < 0 ||
secondDateDay < 0 ||
secondDateDay > 31 ||
secondDateMonth > 12 ||
secondDateMonth < 0
) {
return new TypeError('Date is not valid.');
}
return Math.abs(DateToDay(secondDateDay, secondDateMonth, secondDateYear) - DateToDay(firstDateDay, firstDateMonth, firstDateYear));
};

// Example : DateDayDifference('17/08/2002', '10/10/2020') => 6630

export { DateDayDifference };
67 changes: 67 additions & 0 deletions docs/content/DS_ALGO/algorithms/Conversions/DateToDay.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
DateToDay Method
----------------
The DateToDay method takes a date in string format and
returns the name of a day. The approach behind this method
is very simple, we first take a string date and check
whether their date is valid or not, if the date is valid
then we do this But apply the algorithm shown below. The
algorithm shown below gives us the number of the day and
finally converts it to the name of the day.

Algorithm & Explanation : https://cs.uwaterloo.ca/~alopez-o/math-faq/node73.html
*/

// March is taken as the first month of the year.
const calcMonthList = {
1: 11,
2: 12,
3: 1,
4: 2,
5: 3,
6: 4,
7: 5,
8: 6,
9: 7,
10: 8,
11: 9,
12: 10
};

// show the week day in a number : Sunday - Saturday => 0 - 6
const daysNameList = {
// weeks-day
0: 'Sunday',
1: 'Monday',
2: 'Tuesday',
3: 'Wednesday',
4: 'Thursday',
5: 'Friday',
6: 'Saturday'
};

const DateToDay = (date) => {
// firstly, check that input is a string or not.
if (typeof date !== 'string') {
return new TypeError('Argument is not a string.');
}
// extract the date
const [day, month, year] = date.split('/').map((x) => Number(x));
// check the data are valid or not.
if (day < 0 || day > 31 || month > 12 || month < 0) {
return new TypeError('Date is not valid.');
}
// divide year to century and yearDigit value.
const yearDigit = year % 100;
const century = Math.floor(year / 100);
// Apply the algorithm shown above
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
);
// return the weekDay name.
return daysNameList[weekDay];
};

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

export { DateToDay };
19 changes: 19 additions & 0 deletions docs/content/DS_ALGO/algorithms/Conversions/DecimalToBinary.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
function decimalToBinary(num) {
const bin = [];
while (num > 0) {
bin.unshift(num % 2);
num >>= 1; // basically /= 2 without remainder if any
}
return bin.join('');
}

export { decimalToBinary };

// > decimalToBinary(2)
// '10'

// > decimalToBinary(7)
// '111'

// > decimalToBinary(35)
// '100011'
28 changes: 28 additions & 0 deletions docs/content/DS_ALGO/algorithms/Conversions/DecimalToHex.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
function intToHex(num) {
switch (num) {
case 10:
return 'A';
case 11:
return 'B';
case 12:
return 'C';
case 13:
return 'D';
case 14:
return 'E';
case 15:
return 'F';
}
return num;
}

function decimalToHex(num) {
const hexOut = [];
while (num > 15) {
hexOut.unshift(intToHex(num % 16));
num = Math.floor(num / 16);
}
return intToHex(num) + hexOut.join('');
}

export { decimalToHex };
Loading