javascript
exercises
exercises.js⚡javascript
/**
* 14.2 Math Object - Exercises
*
* Practice using Math methods for various calculations.
*/
/**
* Exercise 1: Dice Roller
*
* Create a function that simulates rolling multiple dice.
*
* @param {number} numDice - Number of dice to roll
* @param {number} sides - Number of sides per die (default: 6)
* @returns {object} - { rolls: number[], total: number, average: number }
*/
function rollDice(numDice, sides = 6) {
// Your code here
}
// console.log(rollDice(3));
// { rolls: [4, 2, 6], total: 12, average: 4 }
// console.log(rollDice(2, 20)); // D20 dice
// { rolls: [15, 8], total: 23, average: 11.5 }
/**
* Exercise 2: Temperature Converter
*
* Create functions to convert between Celsius, Fahrenheit, and Kelvin.
* Round results to 2 decimal places.
*
* Formulas:
* - F = C × 9/5 + 32
* - C = (F - 32) × 5/9
* - K = C + 273.15
*/
function celsiusToFahrenheit(celsius) {
// Your code here
}
function fahrenheitToCelsius(fahrenheit) {
// Your code here
}
function celsiusToKelvin(celsius) {
// Your code here
}
function kelvinToCelsius(kelvin) {
// Your code here
}
// console.log(celsiusToFahrenheit(100)); // 212
// console.log(fahrenheitToCelsius(32)); // 0
// console.log(celsiusToKelvin(0)); // 273.15
// console.log(kelvinToCelsius(0)); // -273.15
/**
* Exercise 3: Geometry Calculator
*
* Create a geometry object with methods for various shape calculations.
* Round all results to 4 decimal places.
*/
const geometry = {
// Circle methods
circleArea(radius) {
// Your code here
},
circumference(radius) {
// Your code here
},
// Rectangle methods
rectangleArea(width, height) {
// Your code here
},
rectanglePerimeter(width, height) {
// Your code here
},
rectangleDiagonal(width, height) {
// Your code here
},
// Triangle methods
triangleArea(base, height) {
// Your code here
},
// Pythagorean: find missing side
pythagorean(a, b, findHypotenuse = true) {
// Your code here
// If findHypotenuse is true, find c given a and b
// If false, find b given a (leg) and c (hypotenuse as 'b' parameter)
},
// Sphere methods
sphereVolume(radius) {
// Your code here
},
sphereSurfaceArea(radius) {
// Your code here
},
};
// console.log(geometry.circleArea(5)); // 78.5398
// console.log(geometry.circumference(5)); // 31.4159
// console.log(geometry.rectangleDiagonal(3, 4)); // 5
// console.log(geometry.triangleArea(10, 5)); // 25
// console.log(geometry.pythagorean(3, 4)); // 5 (hypotenuse)
// console.log(geometry.pythagorean(3, 5, false)); // 4 (other leg)
// console.log(geometry.sphereVolume(3)); // 113.0973
/**
* Exercise 4: Statistical Functions
*
* Create statistical functions that work with arrays of numbers.
*/
function mean(numbers) {
// Your code here
}
function median(numbers) {
// Your code here
}
function mode(numbers) {
// Your code here - return array of mode(s)
}
function standardDeviation(numbers) {
// Your code here
}
function variance(numbers) {
// Your code here
}
// console.log(mean([1, 2, 3, 4, 5])); // 3
// console.log(median([1, 2, 3, 4, 5])); // 3
// console.log(median([1, 2, 3, 4])); // 2.5
// console.log(mode([1, 2, 2, 3, 3, 3, 4])); // [3]
// console.log(mode([1, 1, 2, 2])); // [1, 2]
// console.log(standardDeviation([2, 4, 4, 4, 5, 5, 7, 9])); // ~2
// console.log(variance([2, 4, 4, 4, 5, 5, 7, 9])); // 4
/**
* Exercise 5: Angle Utilities
*
* Create functions for working with angles.
*/
function degreesToRadians(degrees) {
// Your code here
}
function radiansToDegrees(radians) {
// Your code here
}
function normalizeAngle(degrees) {
// Normalize angle to 0-360 range
// Your code here
}
function angleBetweenPoints(x1, y1, x2, y2) {
// Return angle in degrees from point 1 to point 2
// Your code here
}
function rotatePoint(x, y, angleDegrees, centerX = 0, centerY = 0) {
// Rotate point around center by angle
// Return { x, y }
// Your code here
}
// console.log(degreesToRadians(180)); // 3.14159...
// console.log(radiansToDegrees(Math.PI)); // 180
// console.log(normalizeAngle(450)); // 90
// console.log(normalizeAngle(-90)); // 270
// console.log(angleBetweenPoints(0, 0, 1, 1)); // 45
// console.log(rotatePoint(1, 0, 90)); // { x: 0, y: 1 }
/**
* Exercise 6: Random Utilities
*
* Create various random generation functions.
*/
function randomBetween(min, max, isInteger = true) {
// Your code here
}
function randomColor() {
// Return random hex color like "#A3F2C1"
// Your code here
}
function randomRGB() {
// Return { r, g, b } with values 0-255
// Your code here
}
function weightedRandom(items, weights) {
// Return random item based on weights
// items = ['common', 'rare', 'legendary']
// weights = [70, 25, 5] (percentages)
// Your code here
}
function generatePassword(length, options = {}) {
// options: { uppercase, lowercase, numbers, symbols }
// Default: all true
// Your code here
}
// console.log(randomBetween(1, 10)); // 1-10 integer
// console.log(randomBetween(0, 1, false)); // 0-1 float
// console.log(randomColor()); // "#A3F2C1"
// console.log(randomRGB()); // { r: 163, g: 242, b: 193 }
// console.log(weightedRandom(['common', 'rare', 'legendary'], [70, 25, 5]));
// console.log(generatePassword(12)); // "Kj3#mP9$nL2@"
/**
* Exercise 7: Financial Calculator
*
* Create financial calculation functions.
*/
function compoundInterest(principal, rate, time, n = 12) {
// A = P(1 + r/n)^(nt)
// principal: initial amount
// rate: annual interest rate (as decimal, e.g., 0.05 for 5%)
// time: years
// n: compounding frequency per year (default monthly)
// Your code here
}
function loanPayment(principal, annualRate, months) {
// Monthly payment for a loan
// M = P * (r(1+r)^n) / ((1+r)^n - 1)
// r = monthly rate, n = number of payments
// Your code here
}
function futureValue(payment, rate, periods) {
// Future value of regular payments
// FV = PMT * ((1+r)^n - 1) / r
// Your code here
}
// console.log(compoundInterest(1000, 0.05, 10)); // ~1647.01
// console.log(loanPayment(200000, 0.06, 360)); // ~1199.10
// console.log(futureValue(500, 0.005, 120)); // ~77641.14
/**
* Exercise 8: Distance and Position
*
* Create functions for 2D/3D distance calculations.
*/
function distance2D(x1, y1, x2, y2) {
// Your code here
}
function distance3D(x1, y1, z1, x2, y2, z2) {
// Your code here
}
function midpoint(x1, y1, x2, y2) {
// Return { x, y }
// Your code here
}
function isInsideCircle(pointX, pointY, circleX, circleY, radius) {
// Your code here
}
function isInsideRectangle(pointX, pointY, rectX, rectY, width, height) {
// Your code here
}
// console.log(distance2D(0, 0, 3, 4)); // 5
// console.log(distance3D(0, 0, 0, 1, 2, 2)); // 3
// console.log(midpoint(0, 0, 10, 10)); // { x: 5, y: 5 }
// console.log(isInsideCircle(1, 1, 0, 0, 5)); // true
// console.log(isInsideRectangle(5, 5, 0, 0, 10, 10)); // true
/**
* Exercise 9: Number Rounding Utilities
*
* Create flexible rounding functions.
*/
function roundTo(num, decimals) {
// Your code here
}
function roundToNearest(num, nearest) {
// Round to nearest multiple (e.g., nearest 5, 10, 0.25)
// Your code here
}
function roundUp(num, decimals = 0) {
// Your code here
}
function roundDown(num, decimals = 0) {
// Your code here
}
function bankersRounding(num, decimals = 0) {
// Round half to even (banker's rounding)
// 2.5 -> 2, 3.5 -> 4, 4.5 -> 4, 5.5 -> 6
// Your code here
}
// console.log(roundTo(3.14159, 2)); // 3.14
// console.log(roundToNearest(17, 5)); // 15
// console.log(roundToNearest(2.3, 0.25)); // 2.25
// console.log(roundUp(3.14, 1)); // 3.2
// console.log(roundDown(3.19, 1)); // 3.1
// console.log(bankersRounding(2.5)); // 2
// console.log(bankersRounding(3.5)); // 4
/**
* Exercise 10: Math Expression Evaluator
*
* Create a simple math expression evaluator that supports:
* - Basic operations: +, -, *, /
* - Powers: ^
* - Common functions: sqrt, abs, sin, cos, tan, log
* - Constants: pi, e
*
* Note: This is a simplified evaluator for learning purposes.
*/
function evaluateMath(expression) {
// Your code here
}
// console.log(evaluateMath("2 + 3")); // 5
// console.log(evaluateMath("sqrt(16)")); // 4
// console.log(evaluateMath("2^3")); // 8
// console.log(evaluateMath("pi * 2")); // 6.283...
// console.log(evaluateMath("sin(0)")); // 0
// console.log(evaluateMath("abs(-5)")); // 5
// ============================================
// SOLUTIONS
// ============================================
/*
// Solution 1
function rollDice(numDice, sides = 6) {
const rolls = [];
for (let i = 0; i < numDice; i++) {
rolls.push(Math.floor(Math.random() * sides) + 1);
}
const total = rolls.reduce((sum, roll) => sum + roll, 0);
return {
rolls,
total,
average: total / numDice
};
}
// Solution 2
function celsiusToFahrenheit(celsius) {
return Math.round((celsius * 9/5 + 32) * 100) / 100;
}
function fahrenheitToCelsius(fahrenheit) {
return Math.round(((fahrenheit - 32) * 5/9) * 100) / 100;
}
function celsiusToKelvin(celsius) {
return Math.round((celsius + 273.15) * 100) / 100;
}
function kelvinToCelsius(kelvin) {
return Math.round((kelvin - 273.15) * 100) / 100;
}
// Solution 3
const geometry = {
circleArea(radius) {
return Math.round(Math.PI * radius ** 2 * 10000) / 10000;
},
circumference(radius) {
return Math.round(2 * Math.PI * radius * 10000) / 10000;
},
rectangleArea(width, height) {
return Math.round(width * height * 10000) / 10000;
},
rectanglePerimeter(width, height) {
return Math.round(2 * (width + height) * 10000) / 10000;
},
rectangleDiagonal(width, height) {
return Math.round(Math.hypot(width, height) * 10000) / 10000;
},
triangleArea(base, height) {
return Math.round(0.5 * base * height * 10000) / 10000;
},
pythagorean(a, b, findHypotenuse = true) {
if (findHypotenuse) {
return Math.round(Math.hypot(a, b) * 10000) / 10000;
}
return Math.round(Math.sqrt(b ** 2 - a ** 2) * 10000) / 10000;
},
sphereVolume(radius) {
return Math.round((4/3) * Math.PI * radius ** 3 * 10000) / 10000;
},
sphereSurfaceArea(radius) {
return Math.round(4 * Math.PI * radius ** 2 * 10000) / 10000;
}
};
// Solution 4
function mean(numbers) {
return numbers.reduce((sum, n) => sum + n, 0) / numbers.length;
}
function median(numbers) {
const sorted = [...numbers].sort((a, b) => a - b);
const mid = Math.floor(sorted.length / 2);
return sorted.length % 2 === 0
? (sorted[mid - 1] + sorted[mid]) / 2
: sorted[mid];
}
function mode(numbers) {
const counts = {};
let maxCount = 0;
for (const num of numbers) {
counts[num] = (counts[num] || 0) + 1;
maxCount = Math.max(maxCount, counts[num]);
}
return Object.keys(counts)
.filter(key => counts[key] === maxCount)
.map(Number);
}
function variance(numbers) {
const avg = mean(numbers);
const squareDiffs = numbers.map(n => (n - avg) ** 2);
return mean(squareDiffs);
}
function standardDeviation(numbers) {
return Math.sqrt(variance(numbers));
}
// Solution 5
function degreesToRadians(degrees) {
return degrees * (Math.PI / 180);
}
function radiansToDegrees(radians) {
return radians * (180 / Math.PI);
}
function normalizeAngle(degrees) {
return ((degrees % 360) + 360) % 360;
}
function angleBetweenPoints(x1, y1, x2, y2) {
return radiansToDegrees(Math.atan2(y2 - y1, x2 - x1));
}
function rotatePoint(x, y, angleDegrees, centerX = 0, centerY = 0) {
const radians = degreesToRadians(angleDegrees);
const cos = Math.cos(radians);
const sin = Math.sin(radians);
const dx = x - centerX;
const dy = y - centerY;
return {
x: Math.round((cos * dx - sin * dy + centerX) * 10000) / 10000,
y: Math.round((sin * dx + cos * dy + centerY) * 10000) / 10000
};
}
// Solution 6
function randomBetween(min, max, isInteger = true) {
if (isInteger) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
return Math.random() * (max - min) + min;
}
function randomColor() {
const hex = Math.floor(Math.random() * 0xFFFFFF).toString(16);
return '#' + hex.padStart(6, '0').toUpperCase();
}
function randomRGB() {
return {
r: Math.floor(Math.random() * 256),
g: Math.floor(Math.random() * 256),
b: Math.floor(Math.random() * 256)
};
}
function weightedRandom(items, weights) {
const totalWeight = weights.reduce((sum, w) => sum + w, 0);
let random = Math.random() * totalWeight;
for (let i = 0; i < items.length; i++) {
random -= weights[i];
if (random <= 0) {
return items[i];
}
}
return items[items.length - 1];
}
function generatePassword(length, options = {}) {
const {
uppercase = true,
lowercase = true,
numbers = true,
symbols = true
} = options;
let chars = '';
if (uppercase) chars += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
if (lowercase) chars += 'abcdefghijklmnopqrstuvwxyz';
if (numbers) chars += '0123456789';
if (symbols) chars += '!@#$%^&*()_+-=[]{}|;:,.<>?';
if (!chars) return '';
let password = '';
for (let i = 0; i < length; i++) {
password += chars[Math.floor(Math.random() * chars.length)];
}
return password;
}
// Solution 7
function compoundInterest(principal, rate, time, n = 12) {
return Math.round(principal * Math.pow(1 + rate / n, n * time) * 100) / 100;
}
function loanPayment(principal, annualRate, months) {
const monthlyRate = annualRate / 12;
const payment = principal *
(monthlyRate * Math.pow(1 + monthlyRate, months)) /
(Math.pow(1 + monthlyRate, months) - 1);
return Math.round(payment * 100) / 100;
}
function futureValue(payment, rate, periods) {
const fv = payment * ((Math.pow(1 + rate, periods) - 1) / rate);
return Math.round(fv * 100) / 100;
}
// Solution 8
function distance2D(x1, y1, x2, y2) {
return Math.hypot(x2 - x1, y2 - y1);
}
function distance3D(x1, y1, z1, x2, y2, z2) {
return Math.hypot(x2 - x1, y2 - y1, z2 - z1);
}
function midpoint(x1, y1, x2, y2) {
return {
x: (x1 + x2) / 2,
y: (y1 + y2) / 2
};
}
function isInsideCircle(pointX, pointY, circleX, circleY, radius) {
return distance2D(pointX, pointY, circleX, circleY) <= radius;
}
function isInsideRectangle(pointX, pointY, rectX, rectY, width, height) {
return pointX >= rectX &&
pointX <= rectX + width &&
pointY >= rectY &&
pointY <= rectY + height;
}
// Solution 9
function roundTo(num, decimals) {
const factor = Math.pow(10, decimals);
return Math.round(num * factor) / factor;
}
function roundToNearest(num, nearest) {
return Math.round(num / nearest) * nearest;
}
function roundUp(num, decimals = 0) {
const factor = Math.pow(10, decimals);
return Math.ceil(num * factor) / factor;
}
function roundDown(num, decimals = 0) {
const factor = Math.pow(10, decimals);
return Math.floor(num * factor) / factor;
}
function bankersRounding(num, decimals = 0) {
const factor = Math.pow(10, decimals);
const shifted = num * factor;
const floor = Math.floor(shifted);
const decimal = shifted - floor;
if (decimal === 0.5) {
// Round to even
return (floor % 2 === 0 ? floor : floor + 1) / factor;
}
return Math.round(shifted) / factor;
}
// Solution 10
function evaluateMath(expression) {
// Replace constants
let expr = expression
.replace(/\bpi\b/gi, Math.PI.toString())
.replace(/\be\b/gi, Math.E.toString());
// Replace functions
expr = expr.replace(/sqrt\(([^)]+)\)/gi, (_, arg) => Math.sqrt(parseFloat(arg)));
expr = expr.replace(/abs\(([^)]+)\)/gi, (_, arg) => Math.abs(parseFloat(arg)));
expr = expr.replace(/sin\(([^)]+)\)/gi, (_, arg) => Math.sin(parseFloat(arg)));
expr = expr.replace(/cos\(([^)]+)\)/gi, (_, arg) => Math.cos(parseFloat(arg)));
expr = expr.replace(/tan\(([^)]+)\)/gi, (_, arg) => Math.tan(parseFloat(arg)));
expr = expr.replace(/log\(([^)]+)\)/gi, (_, arg) => Math.log(parseFloat(arg)));
// Replace ^ with **
expr = expr.replace(/\^/g, '**');
// Evaluate (simple and unsafe - for learning only!)
try {
return Function('"use strict"; return (' + expr + ')')();
} catch (e) {
return NaN;
}
}
*/