diff --git a/coins.c b/coins.c index 3a9d903..4eb4a4d 100644 --- a/coins.c +++ b/coins.c @@ -7,15 +7,60 @@ #define MAX_N 1024 #define WORDS ((MAX_N / 64) + 1) #define ITERATIONS 10000000 -#define NUMBER 86 +#define NUMBER 999 +//Artem + +int main123(int n) { + int a = 0; + while (n != 0) { + if (n - 50 >= 0) { + n -= 50; + a++; + } + else { + if (n - 25 >= 0) { + n -= 25; + a++; + } + else { + if (n - 10 >= 0) { + n -= 10; + a++; + } + else { + if (n - 5 >= 0) { + n -= 5; + a++; + } + else { + if (n - 2 >= 0) { + n -= 2; + a++; + } + else { + if (n - 1 >= 0) { + n -= 1; + a++; + } + else { + break; + } + } + } + } + } + } + } + return a; +} // ========================================== // 1. TRADITIONAL DP (FOR-LOOP) APPROACH // ========================================== int min_coins_dp(int n, int* coins, int num_coins) { int dp[MAX_N + 1]; dp[0] = 0; - + for (int i = 1; i <= n; i++) { dp[i] = 1000000; // Represent "infinity" for (int c = 0; c < num_coins; c++) { @@ -39,7 +84,7 @@ void shift_left_and_or(uint64_t* dest, const uint64_t* src, int shift) { for (int i = WORDS - 1; i >= word_shift; i--) { int src_idx = i - word_shift; uint64_t val = src[src_idx] << bit_shift; - + if (bit_shift > 0 && src_idx > 0) { val |= (src[src_idx - 1] >> (64 - bit_shift)); } @@ -51,13 +96,13 @@ int min_coins_bitwise(int n, int* coins, int num_coins) { if (n == 0) return 0; if (n > MAX_N) return -1; - uint64_t state[WORDS] = {0}; - state[0] = 1ULL; + uint64_t state[WORDS] = { 0 }; + state[0] = 1ULL; uint64_t next_state[WORDS]; - + int steps = 0; int target_word = n / 64; - int target_bit = n % 64; + int target_bit = n % 64; uint64_t target_mask = 1ULL << target_bit; while (1) { @@ -85,13 +130,13 @@ int min_coins_bitwise_optimized(int n, int* coins, int num_coins) { // How many 64-bit blocks do we ACTUALLY need for this 'n'? int active_words = (n / 64) + 1; - + // Allocate two arrays to act as our "Current" and "Next" states - uint64_t bufferA[WORDS] = {0}; - uint64_t bufferB[WORDS] = {0}; - - bufferA[0] = 1ULL; - + uint64_t bufferA[WORDS] = { 0 }; + uint64_t bufferB[WORDS] = { 0 }; + + bufferA[0] = 1ULL; + // We will use pointers so we never have to use memcpy()! uint64_t* state = bufferA; uint64_t* next_state = bufferB; @@ -102,7 +147,7 @@ int min_coins_bitwise_optimized(int n, int* coins, int num_coins) { while (1) { steps++; - + // Manual clearing is faster than memset because we ONLY clear active_words for (int i = 0; i < active_words; i++) { next_state[i] = 0; @@ -118,7 +163,7 @@ int min_coins_bitwise_optimized(int n, int* coins, int num_coins) { for (int i = active_words - 1; i >= w_shift; i--) { int src_idx = i - w_shift; uint64_t val = state[src_idx] << b_shift; - + if (b_shift > 0 && src_idx > 0) { val |= (state[src_idx - 1] >> (64 - b_shift)); } @@ -142,10 +187,10 @@ int min_coins_bitwise_optimized(int n, int* coins, int num_coins) { // MAIN BENCHMARK // ========================================== int main() { - int ukraine_coins[] = {1, 2, 5, 10, 25, 50}; + int ukraine_coins[] = { 1, 2, 5, 10, 25, 50 }; int num_coins = 6; int n = NUMBER; // 868 cents (Answer: 17 coins + 10 + 5 + 2 + 1 = 21 coins) - + printf("Evaluating N = %d over %d iterations...\n\n", n, ITERATIONS); clock_t start, end; @@ -158,7 +203,7 @@ int main() { total_sum += min_coins_dp(n, ukraine_coins, num_coins); } end = clock(); - cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC; + cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC; printf("1. Traditional DP Time: %f seconds (Answer: %d)\n", cpu_time_used, total_sum / ITERATIONS); // --- Benchmark Bitwise --- @@ -168,17 +213,28 @@ int main() { total_sum += min_coins_bitwise(n, ukraine_coins, num_coins); } end = clock(); - cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC; + cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC; printf("2. Native Bitwise Time: %f seconds (Answer: %d)\n", cpu_time_used, total_sum / ITERATIONS); - // --- Benchmark Bitwise Optimized--- + // --- Benchmark Bitwise Optimized--- total_sum = 0; // Reset start = clock(); for (int i = 0; i < ITERATIONS; i++) { total_sum += min_coins_bitwise_optimized(n, ukraine_coins, num_coins); } end = clock(); - cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC; + cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC; printf("3. Optimized Bitwise Time: %f seconds (Answer: %d)\n", cpu_time_used, total_sum / ITERATIONS); + + //Artem + total_sum = 0; // Reset + start = clock(); + for (int i = 0; i < ITERATIONS; i++) { + total_sum += main123(n); + + } + end = clock(); + cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC; + printf("3. Artemtime: %f seconds (Answer: %d)\n", cpu_time_used, total_sum / ITERATIONS); return 0; } \ No newline at end of file