Coin Change :Dynamic Programming - c

The code I have written solves the basic coin change problem using dynamic programming and gives the minimum number of coins required to make the change. But I want to store the count of each coin playing part in the minimum number.
What I am trying to do is initializing an array count[] and just like hashing it increments the number of coin[j] whenever min is found, i.e count[coin[j]]++ .
But this is not working the way I wanted because it adds the coin every time it finds min corresponding to coin[j]. Hence the number is not the final count of coin in the final answer.
Here is the code:
void makeChange(int coin[], int n, int value)
{
int i, j;
int min_coin[MAX];
int min;
int count[MAX];
min_coin[0] = 0;
for (i=1; i <= value; i++)
{
min = 999;
for (j = 0; j<n; j++)
{
if (coin[j] <= i)
{
if (min > min_coin[i-coin[j]]+1)
{
min = min_coin[i-coin[j]]+1;
count[coin[j]]++;
}
}
}
min_coin[i] = min;
}
printf("minimum coins required %d \n", min_coin[value]);
}

You have to keep an extra, two-dinemsional array to store the coin count for each value and each coin denomination.
When you assign a new minimum in your inner loop, copy all coin counts from i - coin[j] to i and then increment min_count[i][j]. The number of coins needed is then in coin_count[value].

As you already noted, the bottom-up solution adds the coin every time, not only when i == value, but if you want to know the count of coins when i == value, it depends on the the counts of coins of sub-problems, so we need store previous computations with a 2-D array:
#include <stdio.h>
#define MAX 1000
#define COIN_ARRAY_SIZE 4
void makeChange(int coin[], int n, int value)
{
int i, j, k;
int min_coin[MAX];
int count[MAX + 1][COIN_ARRAY_SIZE] = {0}; // zeroing
int min;
//int count[MAX];
min_coin[0] = 0;
for (i=1; i <= value; i++)
{
min = 999;
for (j = 0; j<n; j++)
{
if (coin[j] <= i)
{
if (min > min_coin[i-coin[j]]+1)
{
min = min_coin[i-coin[j]]+1;
for(k = 0; k < n; ++k)
{
count[i][k] = count[i-coin[j]][k]; // copy coin counts when value=i-coin[j]
}
count[i][j]++; // use a coin[j], increase the count
}
}
}
min_coin[i] = min;
}
printf("minimum coins required %d \n", min_coin[value]);
for(int i = 0; i < COIN_ARRAY_SIZE; ++i)
printf("%d: %d\n", coin[i], count[value][i]);
}
Driver program to test above function:
int main()
{
int coin[COIN_ARRAY_SIZE] = {5,3,2,1};
makeChange(coin, 4, 8);
makeChange(coin, 4, 10);
};

Related

Sorting integers by sum of their digits

I'm trying to write a program that will sort an array of 20 random numbers by the sums of their digits.
For example:
"5 > 11" because 5 > 1+1 (5 > 2).
I managed to sort the sums but is it possible to return to the original numbers or do it other way?
#include <stdio.h>
void sortujTab(int tab[], int size){
int sum,i;
for(int i=0;i<size;i++)
{
while(tab[i]>0){//sum as added digits of an integer
int p=tab[i]%10;
sum=sum+p;
tab[i]/=10;
}
tab[i]=sum;
sum=0;
}
for(int i=0;i<size;i++)//print of unsorted sums
{
printf("%d,",tab[i]);
}
printf("\n");
for(int i=0;i<size;i++)//sorting sums
for(int j=i+1;j<=size;j++)
{
if(tab[i]>tab[j]){
int temp=tab[j];
tab[j]=tab[i];
tab[i]=temp;
}
}
for(int i=0;i<20;i++)//print of sorted sums
{
printf("%d,",tab[i]);
}
}
int main()
{
int tab[20];
int size=sizeof(tab)/sizeof(*tab);
for(int i=0;i<=20;i++)
{
tab[i]=rand()%1000;// assamble the value
}
for(int i=0;i<20;i++)
{
printf("%d,",tab[i]);//print unsorted
}
printf("\n");
sortujTab(tab,size);
return 0;
}
There are two basic approach :
Create a function that return the sum for an integer, say sum(int a), then call it on comparison, so instead of tab[i] > tab [j] it becomes sum(tab[i]) > sum (tab[j])
Store the sum into a different array, compare with the new array, and on swapping, swap both the original and the new array
The first solution works well enough if the array is small and takes no extra memory, while the second solution didn't need to repeatedly calculate the sum. A caching approach is also possible with map but it's only worth it if there are enough identical numbers in the array.
Since your numbers are non-negative and less than 1000, you can encode the sum of the digits in the numbers itself. So, this formula will be true: encoded_number = original_number + 1000 * sum_of_the_digits. encoded_number/1000 will decode the sum of the digits, and encoded_number%1000 will decode the original number. Follow the modified code below. The numbers enclosed by parentheses in the output are original numbers. I've tried to modify minimally your code.
#include <stdio.h>
#include <stdlib.h>
void sortujTab(int tab[], int size)
{
for (int i = 0; i < size; i++) {
int sum = 0, n = tab[i];
while (n > 0) { //sum as added digits of an integer
int p = n % 10;
sum = sum + p;
n /= 10;
}
tab[i] += sum * 1000;
}
for (int i = 0; i < size; i++) { //print of unsorted sums
printf("%d%c", tab[i] / 1000, i < size - 1 ? ',' : '\n');
}
for (int i = 0; i < size; i++) { //sorting sums
for (int j = i + 1; j < size; j++) {
if (tab[i] / 1000 > tab[j] / 1000) {
int temp = tab[j];
tab[j] = tab[i];
tab[i] = temp;
}
}
}
for (int i = 0; i < size; i++) { //print of sorted sums
printf("%d(%d)%c", tab[i] / 1000, tab[i] % 1000, i < size - 1 ? ',' : '\n');
}
}
int main(void)
{
int tab[20];
int size = sizeof(tab) / sizeof(*tab);
for (int i = 0; i < size; i++) {
tab[i] = rand() % 1000; // assamble the value
}
for (int i = 0; i < size; i++) {
printf("%d%c", tab[i], i < size - 1 ? ',' : '\n'); //print unsorted
}
sortujTab(tab, size);
return 0;
}
If the range of numbers doesn't allow such an encoding, then you can declare a structure with two integer elements (one for the original number and one for the sum of its digits), allocate an array for size elements of this structure, and initialize and sort the array using the digit sums as the keys.
You can sort an array of indexes rather than the array with data.
#include <stdio.h>
//poor man's interpretation of sumofdigits() :-)
int sod(int n) {
switch (n) {
default: return 0;
case 5: return 5;
case 11: return 2;
case 1000: return 1;
case 9: return 9;
}
}
void sortbyindex(int *data, int *ndx, int size) {
//setup default indexes
for (int k = 0; k < size; k++) ndx[k] = k;
//sort the indexes
for (int lo = 0; lo < size; lo++) {
for (int hi = lo + 1; hi < size; hi++) {
if (sod(data[ndx[lo]]) > sod(data[ndx[hi]])) {
//swap indexes
int tmp = ndx[lo];
ndx[lo] = ndx[hi];
ndx[hi] = tmp;
}
}
}
}
int main(void) {
int data[4] = {5, 11, 1000, 9};
int ndx[sizeof data / sizeof *data];
sortbyindex(data, ndx, 4);
for (int k = 0; k < sizeof data / sizeof *data; k++) {
printf("%d\n", data[ndx[k]]);
}
return 0;
}

Problem with frequency analysis of user input array in C

I'm supposed to do a freqency analysis of a user input array. User may enter as many numbers between 0-1000 as s/he wants and a maximum of 100 numbers can be entered, user ends input by entering a negative number. A void function will calculate which number appears the most times and those 2 variables should be sent to the function as pointers.
My problem is that no matter what I do the analysis seems to calculate all the "empty" elements of the array and I can't figure out what I'm doing wrong. If i make the array smaller to lets say 10 elements it works fine. As I'm a complete novice when it comes to programming and I've changed the code about a million times so at this point I can't remeber what I've changed from my original code. When debugging I get stuck in the second for loop in the function..
#include <stdio.h>
#define MAX 100
#define INTERVAL 1000
void frequencyAnalysis(int array[],int *number, int *freq)
{
int element = 0, count = 0;
for (int i = 0; i < MAX; i++) {
int tempElement = array[i];
int tempCount = 0;
for (int j = 0; j < MAX; j++)
if (array[j] == tempElement)
tempCount++;
if (tempCount > count) {
element = tempElement;
count = tempCount;
}
}
*number = element;
*freq = count;
}
int main(void)
{
int array[MAX], i, j, number = 0, freq = 0;
printf("Hello.\n"
"Please enter a number between 0-1000. "
"Enter as many number as you want (maximum 100).\n"
"Exit by entering a negative number.\n\n");
printf("Enter a number:\n");
for (i = 0; i < MAX; i++) {
scanf("%d", &array[i]);
if (array[i] < 0)
break;
}
frequencyAnalysis(array, &number, &freq);
printf("The number:%d is the most frequent number and appears %d times.\n", number, freq);
return 0;
}
Addressing the first issue, pass in how many items the user actually entered so you're not running up to MAX (which would include all the unused cells). The key is nitems.
void frequencyAnalysis(int array[], int nitems, int *number, int *freq)
{
for (int i = 0; i < nitems; i++) {
...
for (int j = 0; j < nitems; j++)
{
// do stuff
}
}
}
int main(void)
{
int array[MAX],i, j, number = 0, freq = 0;
...
frequencyAnalysis(array, i, &number,&freq);
///
}

C function to print maximum and minimum numbers

'm currently writing a C program that prompts a user to enter five numbers and to display the maximum number. So here's what i came up with
int max_num(float num_arr[])
// this is a number array
{
int max = 0;
for (int k = 0; k <= 4; k++)
{
max = num_arr[0];
if (max > num_arr[k])
{
max = num_arr[k];
printf("The maximum number is is %d\n", max);
}
}
}
Any help is appreciated.
Your function will not work for numbers entered less than 0, also int type is wrong for the fuunction since it's not returning anything. Here is a better version of the same:
void max_num(float num_arr[], int size)
{
if(size>0) float max = num_arr[0];
for (int k = 0; k <= size; k++) {
if (max < num_arr[k]) {
max = num_arr[k];
}
}
printf("The maximum number is %f\n", max);
}
And if you need to return max:
float max_num(float num_arr[], int size)
{
if(size>0) float max = num_arr[0];
for (int k = 0; k <= size; k++) {
if (max < num_arr[k]) {
max = num_arr[k];
}
}
return max;
}
You are setting
max = num_arr[0];
in every loop iteration, so you are losing the max value every time and set it
to the first value in the array.
The correct version is:
for(int k = 0;k<5;k++)
{
if(num_arr[k] > max)
max = num_arr[k];
}
printf("The maximum number is is %d\n", max);
Having a <= in the condition is not incorrect, but it's not very readable either,
it's hard to miss the = sign. It's always better to just use <, in this case
k<5.
Also it's better practice to pass the size of the array to the functions, so you
don't have to hard code the maximal number of items to loop through (like you
did in your code). Like this:
#include <stdio.h>
float max_num(float *array, size_t len)
{
if(array == NULL)
{
fprintf(stderr, "invalid argument, array == NULL\n");
return 0;
}
if(len == 0)
{
fprintf(stderr, "Invalid array size, cannot be 0\n");
return 0;
}
float max = array[0];
for(size_t i = 0; i < len; ++i)
{
if(array[i] > max)
max = array[i];
}
return max;
}
int main(void)
{
float nums[] = { 1.1, -2.2, 8, 6, 99 , -12 };
float max = max_num(nums, sizeof nums / sizeof *nums);
printf("The maximal number in the array is: %f\n", max);
return 0;
}
Rather than if(max > num_arr[k]) it should be if(num_arr[k] > max)

Maximum value of every contiguous subarray

Given an unsorted array A[0...n-1] of integers and an integer k; the desired algorithm in C should calculate the maximum value of every contiguous subarray of size k. For instance, if A = [8,5,10,7,9,4,15,12,90,13] and k=4, then findKMax(A,4,10) returns 10 10 10 15 15 90 90.
My goal is to implement the algorithm as a C programm that reads the elements of A, reads k and then prints the result of the function findKMax(A,4,10). An input/output example is illustrated bellow (input is typeset in bold):
Elements of A: 8 5 10 7 9 4 15 12 90 13 end
Type k: 4
Results: 10 10 10 15 15 90 90
What I've tried so far? Please keep in mind that I am an absolute beginner in C. Here is my code:
#include <stdio.h>
void findKMax(int A[], int k, int n) {
int j;
int max;
for (int i = 0; i <= n-k; i++) {
max = A[i];
for (j = 1; j < k; j++) {
if (A[i+j] > max)
max = A[i+j];
}
}
}
int main() {
int n = sizeof(A);
int k = 4;
printf("Elements of A: ");
scanf("%d", &A[i]);
printf("Type k: %d", k);
printf("Results: %d", &max);
return 0;
}
Update March 17th:
I've modified the source code, i.e. I've tried to implement the hints of Michael Burr and Priyansh Goel. Here is my result:
#include <stdio.h>
// Returning the largest value in subarray of size k.
void findKMax(int A[], int k, int n) {
int j;
int largestValueOfSubarray;
for (int i = 0; i <= n-k; i++) {
largestValueOfSubarray = A[i];
for (j = 1; j < k; j++) {
if (A[i+j] > largestValueOfSubarray)
largestValueOfSubarray = A[i+j];
}
printf("Type k: %d", k);
}
return largestValueOfSubarray;
}
int main() {
int n = 10;
int A[n];
// Reading values into array A.
for (int i = 0; i < n; i++) {
printf("Enter the %d-th element of the array A: \n", i);
scanf("%d", &A[i]);
}
// Printing of all values of array A.
for (int i = 0; i < n; i++) {
printf("\nA[%d] = %d", i, A[i]);
}
printf("\n\n");
// Returning the largest value in array A.
int largestValue = A[0];
for (int i = 0; i < n; i++) {
if (A[i] > largestValue) {
largestValue = A[i];
}
}
printf("The largest value in the array A is %d. \n", largestValue);
return 0;
}
I guess there is not so much to code. Can anybody give me a hint how to do the rest. I need an advice how to "combine" the pieces of code into a running program.
Since you are a beginner, lets begin with the simplest algorithm.
for every i, you need to find sum of k continous numbers starting from that i. And then find the max of it.
Before that you need to see how to take input to an array.
int n;
scanf("%d",&n);
int a[n];
for(int i = 0; i < n; i++) {
scanf("%d",&a[i]);
}
Also, you will need to call the function findKMax(a,n,k);
In your findKMax function, you have to implement the algorithm that I mentioned.
I will not provide the code so that you may try on your own. If you face any issue, do tell me.
HINT : You need to use nested loops.
You find max value in window many times, but output only the last max value.
The simplest correction - add output in the end of main cycle:
for (int i = 0; i <= n-k; i++) {
max = A[i];
for (j = 1; j < k; j++) {
if (A[i+j] > max)
max = A[i+j];
}
printf("Type k: %d", k);
}
The next step - collect all local max values in a single string "10 10 10 15 15 90 90" or additional array of length n-k+1: [10,10,10,15,15,90,90] and print it after the main cycle (I don't know the best approach for this in C)

Fill a defined 2D Array with random numbers in C / Average / Max Value

I've created this 2D 21x21 array that has all it's values set to -1. I wrote it to print the address and value and somehow it only starts at [6][19] why?
What i want to do is to replace some of the -1 values with random numbers from 0 to 100 in the same array. I know i need to seed it with srand but i'm having problems connecting the functions since i'm a total beginner in C.
EDIT 1:
Now i can print the whole array and fill it with random numbers. For the -1 values i just assigned directly which for this case its fine.
What i'm trying now is finding the average of all the values and the maximum number, so what i have is:
#include<stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int a[21][21], i , j;
for (i = 0; i < 21; i++)
{
for ( j = 0; j < 21; j++)
{
a[i][j] = GetRand(0, 100);
a[7][15] = -1;
a[10][6] = -1;
a[13][5] = -1;
a[15][17] = -1;
a[17][17] = -1;
a[19][6] = -1;
printf("%3d" , a[i][j]);
}
printf("\n");
}
return 0;
}
// random seed
int GetRand(int min, int max);
int get() {
int i, r;
for (i = 0; i < 21; i++)
{
r = GetRand(0, 100);
printf("Your number is %d \n", r);
}
return(0);
}
int GetRand(int min, int max)
{
static int Init = 0;
int rc;
if (Init == 0)
{
srand(time(NULL));
Init = 1;
}
rc = (rand() % (max - min +1) +min);
return (rc);
}
// average
int avg()
float sum=0.0;
for(i = 0; i <= 21; i = i + 1) {
for(j = 0; j <= 21; j = j + 1){
sum = sum + a[21][21];
}
printf("The the average number is %.2f\n", sum/21);
}
//find maximum of all values
int *pv = &a[0][0];
max = min = 0;
for (i = 1; i < i*j; ++i){
if (pv[i] > pv[max])
max =i;
if (pv[i] < pv[min])
min = i;
}
printf("The max value is %d in row %d, col %d\n", pv[max], max/j, max%j);
return 0;
}
For the average function the compiler tells me that expected a declaration before i, which is "float sum=0.0;" but i haven't been able to fix that yet.
For the finding the max function i'm not sure yet what i'm doing there, i just have a vague idea of how it's done...am i going in the right direction?
Thanks!
It's very simple: Just assign the result of your GetRand function to the matrix entry.

Resources