Оновити coins.c
This commit is contained in:
98
coins.c
98
coins.c
@@ -7,15 +7,60 @@
|
|||||||
#define MAX_N 1024
|
#define MAX_N 1024
|
||||||
#define WORDS ((MAX_N / 64) + 1)
|
#define WORDS ((MAX_N / 64) + 1)
|
||||||
#define ITERATIONS 10000000
|
#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
|
// 1. TRADITIONAL DP (FOR-LOOP) APPROACH
|
||||||
// ==========================================
|
// ==========================================
|
||||||
int min_coins_dp(int n, int* coins, int num_coins) {
|
int min_coins_dp(int n, int* coins, int num_coins) {
|
||||||
int dp[MAX_N + 1];
|
int dp[MAX_N + 1];
|
||||||
dp[0] = 0;
|
dp[0] = 0;
|
||||||
|
|
||||||
for (int i = 1; i <= n; i++) {
|
for (int i = 1; i <= n; i++) {
|
||||||
dp[i] = 1000000; // Represent "infinity"
|
dp[i] = 1000000; // Represent "infinity"
|
||||||
for (int c = 0; c < num_coins; c++) {
|
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--) {
|
for (int i = WORDS - 1; i >= word_shift; i--) {
|
||||||
int src_idx = i - word_shift;
|
int src_idx = i - word_shift;
|
||||||
uint64_t val = src[src_idx] << bit_shift;
|
uint64_t val = src[src_idx] << bit_shift;
|
||||||
|
|
||||||
if (bit_shift > 0 && src_idx > 0) {
|
if (bit_shift > 0 && src_idx > 0) {
|
||||||
val |= (src[src_idx - 1] >> (64 - bit_shift));
|
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 == 0) return 0;
|
||||||
if (n > MAX_N) return -1;
|
if (n > MAX_N) return -1;
|
||||||
|
|
||||||
uint64_t state[WORDS] = {0};
|
uint64_t state[WORDS] = { 0 };
|
||||||
state[0] = 1ULL;
|
state[0] = 1ULL;
|
||||||
uint64_t next_state[WORDS];
|
uint64_t next_state[WORDS];
|
||||||
|
|
||||||
int steps = 0;
|
int steps = 0;
|
||||||
int target_word = n / 64;
|
int target_word = n / 64;
|
||||||
int target_bit = n % 64;
|
int target_bit = n % 64;
|
||||||
uint64_t target_mask = 1ULL << target_bit;
|
uint64_t target_mask = 1ULL << target_bit;
|
||||||
|
|
||||||
while (1) {
|
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'?
|
// How many 64-bit blocks do we ACTUALLY need for this 'n'?
|
||||||
int active_words = (n / 64) + 1;
|
int active_words = (n / 64) + 1;
|
||||||
|
|
||||||
// Allocate two arrays to act as our "Current" and "Next" states
|
// Allocate two arrays to act as our "Current" and "Next" states
|
||||||
uint64_t bufferA[WORDS] = {0};
|
uint64_t bufferA[WORDS] = { 0 };
|
||||||
uint64_t bufferB[WORDS] = {0};
|
uint64_t bufferB[WORDS] = { 0 };
|
||||||
|
|
||||||
bufferA[0] = 1ULL;
|
bufferA[0] = 1ULL;
|
||||||
|
|
||||||
// We will use pointers so we never have to use memcpy()!
|
// We will use pointers so we never have to use memcpy()!
|
||||||
uint64_t* state = bufferA;
|
uint64_t* state = bufferA;
|
||||||
uint64_t* next_state = bufferB;
|
uint64_t* next_state = bufferB;
|
||||||
@@ -102,7 +147,7 @@ int min_coins_bitwise_optimized(int n, int* coins, int num_coins) {
|
|||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
steps++;
|
steps++;
|
||||||
|
|
||||||
// Manual clearing is faster than memset because we ONLY clear active_words
|
// Manual clearing is faster than memset because we ONLY clear active_words
|
||||||
for (int i = 0; i < active_words; i++) {
|
for (int i = 0; i < active_words; i++) {
|
||||||
next_state[i] = 0;
|
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--) {
|
for (int i = active_words - 1; i >= w_shift; i--) {
|
||||||
int src_idx = i - w_shift;
|
int src_idx = i - w_shift;
|
||||||
uint64_t val = state[src_idx] << b_shift;
|
uint64_t val = state[src_idx] << b_shift;
|
||||||
|
|
||||||
if (b_shift > 0 && src_idx > 0) {
|
if (b_shift > 0 && src_idx > 0) {
|
||||||
val |= (state[src_idx - 1] >> (64 - b_shift));
|
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
|
// MAIN BENCHMARK
|
||||||
// ==========================================
|
// ==========================================
|
||||||
int main() {
|
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 num_coins = 6;
|
||||||
int n = NUMBER; // 868 cents (Answer: 17 coins + 10 + 5 + 2 + 1 = 21 coins)
|
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);
|
printf("Evaluating N = %d over %d iterations...\n\n", n, ITERATIONS);
|
||||||
|
|
||||||
clock_t start, end;
|
clock_t start, end;
|
||||||
@@ -158,7 +203,7 @@ int main() {
|
|||||||
total_sum += min_coins_dp(n, ukraine_coins, num_coins);
|
total_sum += min_coins_dp(n, ukraine_coins, num_coins);
|
||||||
}
|
}
|
||||||
end = clock();
|
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);
|
printf("1. Traditional DP Time: %f seconds (Answer: %d)\n", cpu_time_used, total_sum / ITERATIONS);
|
||||||
|
|
||||||
// --- Benchmark Bitwise ---
|
// --- Benchmark Bitwise ---
|
||||||
@@ -168,17 +213,28 @@ int main() {
|
|||||||
total_sum += min_coins_bitwise(n, ukraine_coins, num_coins);
|
total_sum += min_coins_bitwise(n, ukraine_coins, num_coins);
|
||||||
}
|
}
|
||||||
end = clock();
|
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);
|
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
|
total_sum = 0; // Reset
|
||||||
start = clock();
|
start = clock();
|
||||||
for (int i = 0; i < ITERATIONS; i++) {
|
for (int i = 0; i < ITERATIONS; i++) {
|
||||||
total_sum += min_coins_bitwise_optimized(n, ukraine_coins, num_coins);
|
total_sum += min_coins_bitwise_optimized(n, ukraine_coins, num_coins);
|
||||||
}
|
}
|
||||||
end = clock();
|
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);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user