// Arup Guha
// 10/4/2025
// Code to grade CIS 3362 Homework #4 Question 4

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void printBits(unsigned long long x);
unsigned long long cyclicLeftShiftSol(unsigned long long block, int b);
unsigned long long cyclicLeftShift(unsigned long long block, int b);
unsigned long long setBitsRnd();

int main() {

    srand(time(0));

    // Just trying one random bit string on all shifts.
    unsigned long long x = 13164965309027571551llu;
	int correct = 0;
	for (int i=1; i<=63; i++) {
		unsigned long long res = cyclicLeftShiftSol(x, i);
		unsigned long long student = cyclicLeftShift(x, i);
		if (res == student) correct++;
	}

	// Print out student's score.
	printf("Execution pts = %d\n", correct/7);

    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 cyclicLeftShiftSol(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));
}

/*** Copy paste student function for this. ***/
unsigned long long cyclicLeftShift(unsigned long long block, int b) {
	return 0;
}

// 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;
}
