javascript

exercises

exercises.js
/**
 * ============================================
 * 3.5 BITWISE OPERATORS - EXERCISES
 * ============================================
 */

// ============================================
// EXERCISE 1: Binary Conversions
// ============================================
/**
 * Task: Convert these numbers to binary strings and back
 *
 * 1. Convert 42 to binary string
 * 2. Convert binary string "110110" to decimal
 * 3. Create a number using binary literal for value 25
 */

// Your code here:

// console.log("Exercise 1:");
// console.log("42 in binary:", binary42);
// console.log("'110110' as decimal:", decimal);
// console.log("Binary literal for 25:", binaryLiteral);

// ============================================
// EXERCISE 2: Check Even/Odd with Bitwise AND
// ============================================
/**
 * Task: Create a function isOdd(n) that returns true if n is odd
 * using bitwise AND operator (not modulo!)
 *
 * Hint: Odd numbers have 1 as their last bit
 */

// Your code here:

// console.log("Exercise 2:");
// console.log("isOdd(5):", isOdd(5));   // true
// console.log("isOdd(8):", isOdd(8));   // false
// console.log("isOdd(0):", isOdd(0));   // false

// ============================================
// EXERCISE 3: Permission System
// ============================================
/**
 * Task: Implement a simple permission system
 *
 * Define these permission flags:
 * - VIEW = 1
 * - EDIT = 2
 * - CREATE = 4
 * - DELETE = 8
 *
 * Then implement:
 * 1. hasPermission(perms, perm) - check if permission exists
 * 2. addPermission(perms, perm) - add a permission
 * 3. removePermission(perms, perm) - remove a permission
 */

// Define flags:

// Implement functions:

// Test:
// let userPerms = VIEW | EDIT;  // Start with VIEW and EDIT
// console.log("Exercise 3:");
// console.log("Has VIEW?", hasPermission(userPerms, VIEW));       // true
// console.log("Has DELETE?", hasPermission(userPerms, DELETE));   // false
// userPerms = addPermission(userPerms, CREATE);
// console.log("After adding CREATE:", userPerms);                 // 7
// userPerms = removePermission(userPerms, EDIT);
// console.log("After removing EDIT:", userPerms);                 // 5

// ============================================
// EXERCISE 4: Swap Without Temp Variable
// ============================================
/**
 * Task: Swap two variables x and y using XOR without a temp variable
 *
 * Start with: x = 15, y = 27
 * After swap: x = 27, y = 15
 */

let x = 15,
  y = 27;
// Your code here (3 XOR operations):

// console.log("Exercise 4:");
// console.log("After swap: x =", x, ", y =", y);

// ============================================
// EXERCISE 5: Fast Multiplication and Division
// ============================================
/**
 * Task: Implement fast multiplication and division functions using bit shifts
 *
 * 1. multiplyBy2(n) - multiply by 2
 * 2. multiplyBy16(n) - multiply by 16
 * 3. divideBy2(n) - divide by 2 (integer division)
 * 4. divideBy8(n) - divide by 8 (integer division)
 */

// Your code here:

// console.log("Exercise 5:");
// console.log("7 × 2 =", multiplyBy2(7));    // 14
// console.log("7 × 16 =", multiplyBy16(7));  // 112
// console.log("100 ÷ 2 =", divideBy2(100));  // 50
// console.log("100 ÷ 8 =", divideBy8(100));  // 12

// ============================================
// EXERCISE 6: Get Bit at Position
// ============================================
/**
 * Task: Create a function getBit(n, pos) that returns the bit (0 or 1)
 * at position pos in number n (0-indexed from right)
 *
 * Example: getBit(13, 2) should return 1
 * 13 = 1101 in binary, bit at position 2 is 1
 */

// Your code here:

// console.log("Exercise 6:");
// console.log("getBit(13, 0):", getBit(13, 0));  // 1
// console.log("getBit(13, 1):", getBit(13, 1));  // 0
// console.log("getBit(13, 2):", getBit(13, 2));  // 1
// console.log("getBit(13, 3):", getBit(13, 3));  // 1

// ============================================
// EXERCISE 7: Set Bit at Position
// ============================================
/**
 * Task: Create a function setBit(n, pos) that sets the bit at position pos
 * to 1 and returns the new number
 *
 * Example: setBit(8, 1) should return 10
 * 8 = 1000, setting bit 1 gives 1010 = 10
 */

// Your code here:

// console.log("Exercise 7:");
// console.log("setBit(8, 1):", setBit(8, 1));    // 10
// console.log("setBit(0, 3):", setBit(0, 3));    // 8
// console.log("setBit(15, 4):", setBit(15, 4)); // 31

// ============================================
// EXERCISE 8: Clear Bit at Position
// ============================================
/**
 * Task: Create a function clearBit(n, pos) that sets the bit at position pos
 * to 0 and returns the new number
 *
 * Example: clearBit(15, 2) should return 11
 * 15 = 1111, clearing bit 2 gives 1011 = 11
 */

// Your code here:

// console.log("Exercise 8:");
// console.log("clearBit(15, 2):", clearBit(15, 2));   // 11
// console.log("clearBit(8, 3):", clearBit(8, 3));     // 0
// console.log("clearBit(255, 0):", clearBit(255, 0)); // 254

// ============================================
// EXERCISE 9: Count Set Bits
// ============================================
/**
 * Task: Create a function countSetBits(n) that counts the number of 1 bits
 *
 * Example: countSetBits(13) should return 3
 * 13 = 1101 has three 1s
 */

// Your code here:

// console.log("Exercise 9:");
// console.log("countSetBits(13):", countSetBits(13));   // 3
// console.log("countSetBits(255):", countSetBits(255)); // 8
// console.log("countSetBits(0):", countSetBits(0));     // 0

// ============================================
// EXERCISE 10: Check Power of 2
// ============================================
/**
 * Task: Create a function isPowerOfTwo(n) that returns true if n is a power of 2
 * using bitwise operators
 *
 * Hint: Powers of 2 have exactly one bit set
 * n & (n-1) clears the lowest set bit
 */

// Your code here:

// console.log("Exercise 10:");
// console.log("isPowerOfTwo(16):", isPowerOfTwo(16));  // true
// console.log("isPowerOfTwo(15):", isPowerOfTwo(15));  // false
// console.log("isPowerOfTwo(1):", isPowerOfTwo(1));    // true
// console.log("isPowerOfTwo(0):", isPowerOfTwo(0));    // false

// ============================================
// EXERCISE 11: RGB Color Conversion
// ============================================
/**
 * Task: Implement two functions:
 * 1. packRGB(r, g, b) - combines RGB values (0-255) into a single number
 * 2. unpackRGB(color) - extracts {r, g, b} from a packed number
 *
 * Format: 0xRRGGBB
 */

// Your code here:

// console.log("Exercise 11:");
// const packed = packRGB(255, 128, 64);
// console.log("Packed RGB:", packed.toString(16));  // ff8040
// console.log("Unpacked:", unpackRGB(packed));      // {r: 255, g: 128, b: 64}

// ============================================
// EXERCISE 12: XOR Encryption/Decryption
// ============================================
/**
 * Task: Implement simple XOR cipher
 * 1. encryptString(str, key) - encrypt a string with a numeric key
 * 2. decryptString(encrypted, key) - decrypt using the same key
 *
 * XOR each character's code with the key
 */

// Your code here:

// console.log("Exercise 12:");
// const original = "Secret!";
// const key = 123;
// const encrypted = encryptString(original, key);
// const decrypted = decryptString(encrypted, key);
// console.log("Original:", original);
// console.log("Encrypted:", encrypted);
// console.log("Decrypted:", decrypted);

// ============================================
// BONUS: Find Single Number
// ============================================
/**
 * Task: Given an array where every element appears twice except one,
 * find that single element using XOR
 *
 * Example: [2, 3, 5, 2, 3] should return 5
 *
 * Hint: a ^ a = 0, and a ^ 0 = a
 */

// Your code here:

// console.log("Bonus:");
// console.log("findSingle([2, 3, 5, 2, 3]):", findSingle([2, 3, 5, 2, 3]));  // 5
// console.log("findSingle([1, 1, 2]):", findSingle([1, 1, 2]));              // 2

// ============================================
// SOLUTIONS
// ============================================
/**
 * Exercise 1:
 * const binary42 = (42).toString(2);        // "101010"
 * const decimal = parseInt("110110", 2);     // 54
 * const binaryLiteral = 0b11001;             // 25
 *
 * Exercise 2:
 * const isOdd = (n) => (n & 1) === 1;
 *
 * Exercise 3:
 * const VIEW = 1, EDIT = 2, CREATE = 4, DELETE = 8;
 * const hasPermission = (perms, perm) => (perms & perm) !== 0;
 * const addPermission = (perms, perm) => perms | perm;
 * const removePermission = (perms, perm) => perms & ~perm;
 *
 * Exercise 4:
 * x = x ^ y;  // x = 15 ^ 27 = 20
 * y = x ^ y;  // y = 20 ^ 27 = 15
 * x = x ^ y;  // x = 20 ^ 15 = 27
 *
 * Exercise 5:
 * const multiplyBy2 = (n) => n << 1;
 * const multiplyBy16 = (n) => n << 4;
 * const divideBy2 = (n) => n >> 1;
 * const divideBy8 = (n) => n >> 3;
 *
 * Exercise 6:
 * const getBit = (n, pos) => (n >> pos) & 1;
 *
 * Exercise 7:
 * const setBit = (n, pos) => n | (1 << pos);
 *
 * Exercise 8:
 * const clearBit = (n, pos) => n & ~(1 << pos);
 *
 * Exercise 9:
 * const countSetBits = (n) => {
 *     let count = 0;
 *     while (n) {
 *         count += n & 1;
 *         n >>>= 1;
 *     }
 *     return count;
 * };
 *
 * Exercise 10:
 * const isPowerOfTwo = (n) => n > 0 && (n & (n - 1)) === 0;
 *
 * Exercise 11:
 * const packRGB = (r, g, b) => (r << 16) | (g << 8) | b;
 * const unpackRGB = (color) => ({
 *     r: (color >> 16) & 0xFF,
 *     g: (color >> 8) & 0xFF,
 *     b: color & 0xFF
 * });
 *
 * Exercise 12:
 * const encryptString = (str, key) =>
 *     [...str].map(c => String.fromCharCode(c.charCodeAt(0) ^ key)).join('');
 * const decryptString = (encrypted, key) => encryptString(encrypted, key);
 *
 * Bonus:
 * const findSingle = (arr) => arr.reduce((acc, n) => acc ^ n, 0);
 */
Exercises - JavaScript Tutorial | DeepML