javascript
exercises
exercises.js⚡javascript
/**
* 8.3 BigInt - Exercises
*/
/**
* Exercise 1: BigInt Creation
* Create BigInt values in different ways
*/
function createBigInts() {
// TODO: Create and return an object with:
// - literal: BigInt literal for 9007199254740993
// - fromNumber: BigInt from the number 1000
// - fromString: BigInt from string "123456789012345678901234567890"
// - fromHex: BigInt from hex string "0xFFFFFFFFFFFFFFFF"
// - negative: Negative BigInt literal for -9007199254740993
return {
// Your code here
};
}
// Test:
// const bigInts = createBigInts();
// console.log(bigInts.literal === 9007199254740993n);
/**
* Exercise 2: Safe Arithmetic
* Perform operations that would overflow with Number
*/
function safeLargeMultiply(a, b) {
// TODO: Multiply two large numbers safely using BigInt
// Parameters can be number or string
// Return result as string
}
// Test:
// console.log(safeLargeMultiply("9007199254740991", "9007199254740991"));
/**
* Exercise 3: Factorial with BigInt
* Calculate factorial of large numbers
*/
function bigFactorial(n) {
// TODO: Calculate n! using BigInt
// Return the BigInt result
}
// Test:
// console.log(bigFactorial(50)); // Should be exact, not exponential notation
// console.log(bigFactorial(100).toString().length); // 158 digits
/**
* Exercise 4: Power of Two
* Work with large powers
*/
function powerOfTwo(exponent) {
// TODO: Calculate 2^exponent using BigInt
// Return { value: BigInt, digits: number }
}
// Test:
// const p = powerOfTwo(1000);
// console.log(p.digits); // 302
/**
* Exercise 5: Type Conversion Helper
* Create utilities for BigInt conversion
*/
const bigIntUtils = {
// TODO: Implement these methods:
// fromNumber(n): Safely convert number to BigInt
// Throw error if not safe integer
// toNumber(big): Convert BigInt to number
// Throw error if would lose precision
// toString(big, radix): Convert to string with radix
// fromJSON(str): Parse BigInt from JSON-safe string format
// toJSON(big): Convert BigInt to JSON-safe format
};
// Test:
// console.log(bigIntUtils.fromNumber(123)); // 123n
// console.log(bigIntUtils.toNumber(123n)); // 123
/**
* Exercise 6: BigInt Comparison
* Compare and sort BigInt values
*/
function sortBigInts(arr) {
// TODO: Sort array of BigInt values in ascending order
// Handle both BigInt and string representations
}
function findMinMax(arr) {
// TODO: Find min and max in array of BigInts
// Return { min: BigInt, max: BigInt }
}
// Test:
// const arr = [100n, 5n, 9999999999999999999999n, 42n];
// console.log(sortBigInts(arr));
/**
* Exercise 7: Binary Operations
* Perform bitwise operations with BigInt
*/
function bitwiseOperations(a, b) {
// TODO: Return object with all bitwise operations
// - and, or, xor, not_a, not_b
// - leftShift (a << 2), rightShift (a >> 2)
}
function countBits(n) {
// TODO: Count number of 1 bits in BigInt
}
// Test:
// console.log(countBits(255n)); // 8
/**
* Exercise 8: Financial Calculator
* Precise financial calculations with BigInt
*/
class PreciseMoney {
// TODO: Implement money class using BigInt cents
// constructor(dollars, cents) or constructor(totalCents)
// add(other): PreciseMoney
// subtract(other): PreciseMoney
// multiply(factor): PreciseMoney
// divide(divisor): PreciseMoney
// format(): string like "$1,234.56"
// static parse(str): PreciseMoney from string like "$1,234.56"
}
// Test:
// const price = new PreciseMoney(99, 99);
// const total = price.multiply(1000000);
// console.log(total.format()); // "$99,990,000.00"
/**
* Exercise 9: Snowflake ID Generator
* Generate Twitter-style snowflake IDs
*/
class SnowflakeGenerator {
// TODO: Implement snowflake ID generator
// Format: timestamp (42 bits) | worker (5 bits) | process (5 bits) | sequence (12 bits)
// constructor(workerId, processId)
// generate(): BigInt - generate next ID
// parse(id): { timestamp, workerId, processId, sequence }
// static EPOCH: BigInt - custom epoch (e.g., 2020-01-01)
}
// Test:
// const gen = new SnowflakeGenerator(1, 1);
// const id1 = gen.generate();
// const id2 = gen.generate();
// console.log(id1 < id2); // true
/**
* Exercise 10: Arbitrary Precision Math
* Implement mathematical functions for BigInt
*/
const bigMath = {
// TODO: Implement these functions
// sqrt(n): Integer square root (floor)
// gcd(a, b): Greatest common divisor
// lcm(a, b): Least common multiple
// modPow(base, exp, mod): Modular exponentiation
// isPrime(n): Check if prime (simple method ok)
// fibonacci(n): nth Fibonacci number
};
// Test:
// console.log(bigMath.sqrt(100n)); // 10n
// console.log(bigMath.gcd(48n, 18n)); // 6n
// console.log(bigMath.fibonacci(100)); // 354224848179261915075n
/**
* BONUS CHALLENGES
*/
/**
* Bonus 1: BigInt Range Iterator
* Create an iterator for BigInt ranges
*/
function* bigIntRange(start, end, step = 1n) {
// TODO: Yield BigInt values from start to end (exclusive)
// Handle both positive and negative steps
}
// Test:
// for (const n of bigIntRange(0n, 10n, 2n)) {
// console.log(n); // 0n, 2n, 4n, 6n, 8n
// }
/**
* Bonus 2: RSA-like Encryption Demo
* Simple public key cryptography demo
*/
class SimpleRSA {
// TODO: Implement simplified RSA
// constructor(p, q): Two prime numbers
// encrypt(message): BigInt
// decrypt(cipher): BigInt
}
/**
* Bonus 3: Arbitrary Base Conversion
* Convert BigInt between different bases
*/
function convertBase(value, fromBase, toBase) {
// TODO: Convert string representation between bases
// Support bases 2-36
}
// Test:
// console.log(convertBase('FF', 16, 10)); // "255"
// console.log(convertBase('255', 10, 2)); // "11111111"
// ============================================
// SOLUTION KEY (for reference)
// ============================================
/*
// Exercise 1 Solution:
function createBigInts() {
return {
literal: 9007199254740993n,
fromNumber: BigInt(1000),
fromString: BigInt("123456789012345678901234567890"),
fromHex: BigInt("0xFFFFFFFFFFFFFFFF"),
negative: -9007199254740993n
};
}
// Exercise 2 Solution:
function safeLargeMultiply(a, b) {
return (BigInt(a) * BigInt(b)).toString();
}
// Exercise 3 Solution:
function bigFactorial(n) {
let result = 1n;
for (let i = 2n; i <= BigInt(n); i++) {
result *= i;
}
return result;
}
// Exercise 4 Solution:
function powerOfTwo(exponent) {
const value = 2n ** BigInt(exponent);
return { value, digits: value.toString().length };
}
// Exercise 5 Solution:
const bigIntUtils = {
fromNumber(n) {
if (!Number.isSafeInteger(n)) {
throw new Error('Number is not a safe integer');
}
return BigInt(n);
},
toNumber(big) {
const num = Number(big);
if (BigInt(num) !== big) {
throw new Error('Precision would be lost');
}
return num;
},
toString(big, radix = 10) {
return big.toString(radix);
},
fromJSON(str) {
return BigInt(str);
},
toJSON(big) {
return big.toString();
}
};
// Exercise 7 Solution:
function countBits(n) {
let count = 0n;
while (n > 0n) {
count += n & 1n;
n >>= 1n;
}
return count;
}
// Exercise 10 Solution (partial):
const bigMath = {
sqrt(n) {
if (n < 0n) throw new Error('Cannot sqrt negative');
if (n < 2n) return n;
let x = n;
let y = (x + 1n) / 2n;
while (y < x) {
x = y;
y = (x + n / x) / 2n;
}
return x;
},
gcd(a, b) {
a = a < 0n ? -a : a;
b = b < 0n ? -b : b;
while (b) {
[a, b] = [b, a % b];
}
return a;
},
lcm(a, b) {
return (a * b) / this.gcd(a, b);
},
modPow(base, exp, mod) {
let result = 1n;
base = base % mod;
while (exp > 0n) {
if (exp % 2n === 1n) {
result = (result * base) % mod;
}
exp = exp / 2n;
base = (base * base) % mod;
}
return result;
},
fibonacci(n) {
if (n <= 1) return BigInt(n);
let a = 0n, b = 1n;
for (let i = 2; i <= n; i++) {
[a, b] = [b, a + b];
}
return b;
}
};
*/
console.log('Complete the exercises above!');
console.log('Check the solution key at the bottom for guidance.');