Recently, I was learning about greedy algorithms. One example that was given was an algorithm for exchanging a given money amount using the smallest number of coins. After the lecture, I wrote a C program implementing this:
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
static int compareDenominations(const void *a, const void *b) {
return (*((int*) b) - *((int*) a));
}
int main(int argc, char *argv[]) {
long amount;
int count;
long *denominations;
if (argc > 2) {
errno = 0;
amount = strtol(argv[1], NULL, 10);
if (errno || amount <= 0) {
puts("The coin amount is either negative, zero, or too big.");
return EXIT_FAILURE;
}
count = argc - 2;
if (count == 0) {
puts("Please input at least one coin denomination.");
return EXIT_FAILURE;
}
denominations = malloc(sizeof(*denominations) * count);
if (denominations == NULL) {
puts("Insufficient memory.");
return EXIT_FAILURE;
}
int i;
for (i = 0; i < count; i++) {
errno = 0;
denominations[i] = strtol(argv[i + 2], NULL, 10);
if (errno || denominations[i] <= 0) {
puts("A denomination amount is either negative, zero, or too big.");
return EXIT_FAILURE;
} else {
int j;
for (j = 0; j < i; j++) {
if (denominations[j] == denominations[i]) {
fprintf(stderr, "%ld is a duplicate coin denomination.\n", denominations[j]);
return EXIT_FAILURE;
}
}
}
}
} else {
puts("Please enter a coin amount followed by a non-zero number of unique denominations, all separated by spaces.");
return EXIT_FAILURE;
}
heapsort(denominations, count, sizeof(*denominations), compareDenominations);
printf("Amount: %ld | Denominations: [ ", amount);
int i;
for (i = 0; i < count; i++) {
printf("%ld ", denominations[i]);
}
puts("]");
int denominationCount = 0;
for (i = 0; i < count; i++) {
denominationCount = 0;
while (amount >= denominations[i]) {
amount -= denominations[i];
denominationCount++;
}
denominations[i] = denominationCount;
}
if (amount) {
puts("The coin amount could not be represented using the given denominations.");
return EXIT_FAILURE;
}
printf("Counts: [ ");
for (i = 0; i < count; i++) {
printf("%ld ", denominations[i]);
}
puts("]");
return EXIT_SUCCESS;
}
Because my program can accept arbitrary inputs, this greedy algorithm may not always output the most optimal solution, but I am still interested in the quality of my implementation.