// Arup Guha
// 9/23/2025
// Solution for CIS 3362 Homework #4 Question 4

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void printBits(unsigned long long x);
unsigned long long cyclicLeftShift(unsigned long long block, int b);
unsigned long long setBitsRnd();
int main() {

    srand(time(0));

    // Put test cases here.
    unsigned long long x = setBitsRnd();
    printBits(x);
    unsigned long long res = cyclicLeftShift(x, 6);
    printBits(res);
	printf("here\n");

    return 0;
}

// Pre-condition: b is an integer in between 1 and 63, inclusive.
// Post-condition: returns the result of applying a cyclic left shift of b bits to block.
unsigned long long cyclicLeftShift(unsigned long long block, int b) {

    // This has b bits on.
    unsigned long long mask = (1llu<<b)-1;

    // This isolates the b most significant bits.
    unsigned long long leftSide = block & (mask<<(64-b));

    // Now, move over all the bits to the left by b, and then fill in the b
    // least significant bits by right shifting the leftSide bits 64-b bits over,
    return (block << b) | (leftSide >> (64-b));
}

// Just so we can see the bits.
void printBits(unsigned long long x) {

    // Go from MSB to LSB.
    for (int i=63; i>=0; i--) {

        // Isolate bit with a bitwise and with a number with a single 1 bit.
        if (x&(1ll<<i)) printf("1");
        else printf("0");
    }
    printf("\n");
}

// Returns an unsigned long long with random bits.
unsigned long long setBitsRnd() {

    unsigned long long x = 0;

    // Go to each bit.
    for (int i=0; i<64; i++) {

        // Get a random number 0 or 1.
        int tmp = rand()%2;

        // If it's odd, turn this bit on.
        if (tmp)
            x |= (1ll<<i);
    }

    return x;
}
