#include 
#include 

#define TRUE 1
#define FALSE 0

//--------------------------------------------------------------------------------------
// Section 1: Digit Manipulation (Lab 2)
//--------------------------------------------------------------------------------------

int sumDigits(int num) {
    int sum = 0;
    int temp = (num < 0) ? -num : num;
    if (temp == 0) return 0;
    while (temp > 0) {
        sum += temp % 10;
        temp /= 10;
    }
    return sum;
}

int reverseNumber(int num) {
    int reversed = 0;
    int temp = num;
    while (temp != 0) {
        if (reversed > __INT_MAX__ / 10 || reversed < (-__INT_MAX__ - 1) / 10) return 0;
        reversed = reversed * 10 + (temp % 10);
        temp /= 10;
    }
    return reversed;
}

int countDigits(int num) {
    int count = 0;
    int temp = (num < 0) ? -num : num;
    if (temp == 0) return 1;
    while (temp > 0) {
        count++;
        temp /= 10;
    }
    return count;
}


//--------------------------------------------------------------------------------------
// Section 2: Divisors, Factors, GCD, and LCM (Lab 2, 3)
//--------------------------------------------------------------------------------------

int sumProperDivisors(int num) {
    if (num <= 1) return 0;
    int sum = 1;
    for (int i = 2; i * i <= num; i++) {
        if (num % i == 0) {
            sum += i;
            if (i * i != num) sum += num / i;
        }
    }
    return sum;
}

int findGCD(int a, int b) {
   int temp;
   while (b != 0) {
       temp = b;
       b = a % b;
       a = temp;
   }
   return a;
}

int findLCM(int a, int b) {
    if (a == 0 || b == 0) return 0;
    return (int)(((long long)a * b) / findGCD(a, b));
}


//--------------------------------------------------------------------------------------
// Section 3: Number Property Checkers (Lab 2, 4)
//--------------------------------------------------------------------------------------

int isPrime(int num) {
    if (num <= 1) return FALSE;
    for (int i = 2; i * i <= num; i++) {
        if (num % i == 0) return FALSE;
    }
    return TRUE;
}

int isPalindrome(int num) {
    if (num < 0) return FALSE;
    return (num == reverseNumber(num));
}

int isPerfectNumber(int num) {
    if (num <= 1) return FALSE;
    return (num == sumProperDivisors(num));
}


//--------------------------------------------------------------------------------------
// Section 4: Combinatorics & Powers (Lab 1, 3, 4)
//--------------------------------------------------------------------------------------

long long factorial(int n) {
    if (n < 0) return 0;
    long long fact = 1;
    for (int i = 1; i <= n; i++) {
        fact *= i;
    }
    return fact;
}

long long calculate_nPr(int n, int r) {
    if (r < 0 || r > n) return 0;
    long long result = 1;
    for (int i = n; i > n - r; i--) {
        result *= i;
    }
    return result;
}

long long calculate_nCr(int n, int r) {
    if (r < 0 || r > n) return 0;
    if (r > n / 2) r = n - r;
    long long result = 1;
    for (int i = 1; i <= r; i++) {
        result = result * (n - i + 1) / i;
    }
    return result;
}

double customPower(double base, int exp) {
    double result = 1.0;
    int is_negative_exp = exp < 0;
    if(is_negative_exp) exp = -exp;

    for (int i = 0; i < exp; i++) {
        result *= base;
    }
    return is_negative_exp ? 1.0 / result : result;
}


//--------------------------------------------------------------------------------------
// Section 5: Number System Conversions & Rounding (Lab 3, 4)
//--------------------------------------------------------------------------------------

long long binaryToDecimal(long long binaryNum) {
    long long decimalNum = 0;
    int i = 0;
    while (binaryNum != 0) {
        decimalNum += (binaryNum % 10) * pow(2, i);
        binaryNum /= 10;
        i++;
    }
    return decimalNum;
}

long long decimalToBinary(int decimalNum) {
    long long binaryNum = 0;
    long long i = 1;
    while (decimalNum != 0) {
        binaryNum += (decimalNum % 2) * i;
        decimalNum /= 2;
        i *= 10;
    }
    return binaryNum;
}

double customRound(double num, int d) {
    double multiplier = pow(10, d);
    return round(num * multiplier) / multiplier;
}

// =====================================================================================
//                              MAIN CONTROL PROGRAM
// =====================================================================================
int main() {

    int n1, n2;
    long long bin_in;
    double d1;

    printf("Enter number: "); 
    scanf("%d", &n1); 
    printf("Result: %d\n", sumDigits(n1)); 
            
    printf("Enter two numbers: "); 
    scanf("%d %d", &n1, &n2); 
    printf("Result: %d\n", findGCD(n1, n2)); 
            
    printf("Enter number: "); 
    scanf("%d", &n1); 
    printf(isPrime(n1) ? "Result: TRUE\n" : "Result: FALSE\n"); 

    printf("Enter base and exponent: "); scanf("%lf %d", &d1, &n1); printf("Result: %lf\n", customPower(d1, n1)); 
    printf("Enter binary number: "); scanf("%lld", &bin_in); printf("Result: %lld\n", binaryToDecimal(bin_in)); 
    printf("Enter decimal number: "); scanf("%d", &n1); printf("Result: %lld\n", decimalToBinary(n1)); 
    printf("Enter number and decimal places: "); scanf("%lf %d", &d1, &n1); printf("Result: %.*f\n", n1, customRound(d1, n1)); 

    return 0;
}