Dynamic Programming - Minimum Coin caching - c

Earlier I posted a question about the coin vending machine problem (the minimum number of coins required). Turns out the issue was a typo in a for loop, so now the program works. The original question was this:
As the programmer of a vending machine controller your are required to compute the minimum number of coins that make up the required change to give back to customers. An efficient solution to this problem takes a dynamic programming approach, starting off computing the number of coins required for a 1 cent change, then for 2 cents, then for 3 cents, until reaching the required change and each time making use of the prior computed number of coins. Write a program containing the function ComputeChange(), that takes a list of valid coins and the required change. This program should repeatedly ask for the required change from the console and call ComputeChange() accordingly. It should also make use of “caching”, where any previously computed intermediate values are retained for subsequent look-up.
The issue is that the code makes use of recursion, so it takes quite a long time to evaluate large values. Making use of caching should improve the issue, but I have no idea how to go about it. The code can be found below.
#include <stdio.h>
#include <limits.h>
int computeChange(int[],int,int);
int min(int[],int);
int main(){
int cur[]={1,2,5,10,20,50,100,200};
int n = sizeof(cur)/sizeof(int);
int v;
printf("Enter a value in euro cents: ");
scanf("%d", &v);
printf("The minimum number of euro coins required is %d", computeChange(cur, v, n));
return 0;
}
int computeChange(int cur[], int v, int n){
if(v < 0)
return INT_MAX;
else if(v == 0)
return 0;
else{
int possible_mins[n], i;
for(i = 0; i < n; i++){
possible_mins[i]=computeChange(cur, v-cur[i], n);
}
return 1+min(possible_mins, n);
};
}
int min(int a[], int n){
int min = INT_MAX, i;
for(i = 0; i < n; i++){
if((a[i]>=0) && (a[i]< min))
min = a[i];
}
return min;
}

With your existing code:
#include <stdio.h>
#include <limits.h>
int computeChange(int[],int,int);
int min(int[],int);
void initChange ();
int change [MAX]; //used for memoization
int main(){
int cur[]={1,2,5,10,20,50,100,200};
int n = sizeof(cur)/sizeof(int);
int v;
initChange ();
printf("Enter a value in euro cents: ");
scanf("%d", &v);
printf("The minimum number of euro coins required is %d", computeChange(cur, v, n));
return 0;
}
void initChange () {
int i =0;
for (i = 0; i < MAX; i++) {
change[i] = INT_MAX;
}
}
int computeChange(int cur[], int v, int n){
if(v < 0)
return INT_MAX;
else if(v == 0)
return 0;
else{
if (change[v] == INT_MAX) {
int possible_mins[n], i;
for(i = 0; i < n; i++){
possible_mins[i]=computeChange(cur, v-cur[i], n);
}
change[v] = 1 + min(possible_mins, n); // memoization
}
return change[v];//you return the memoized value
};
}
int min(int a[], int n){
int min = INT_MAX, i;
for(i = 0; i < n; i++){
if((a[i]>=0) && (a[i]< min))
min = a[i];
}
return min;
}
I already posted a solution using loops in your previous question. I will post it again here:
So the below is the code snippet for your problem using memoization and dynamic programming. The complexity is O(Val*numTypesofCoins).
In the end, change[val] will give you the min number of coins for val.
int main (void) {
int change [MAX];
int cur[]={1,2,5,10,20,50,100,200};
int n = sizeof(a)/sizeof(int);
int val; //whatever user enters to get the num of coins required.
printf("Enter a value in euro cents: ");
scanf("%d", &val);
for (i=0; i <= val; i++) {
change[i] = INT_MAX;
}
for (i=0; i < n; i++) { // change for the currency coins should be 1.
change[cur[i]] = 1;
}
for (i=1; i <= val; i++) {
int min = INT_MAX;
int coins = 0;
if (change[i] != INT_MAX) { // Already got in 2nd loop
continue;
}
for (j=0; j < n; j++) {
if (cur[j] > i) { // coin value greater than i, so break.
break;
}
coins = 1 + change[i - cur[j]];
if (coins < min) {
min = coins;
}
}
change[i] = min;
}
}

Related

changing the size of array as required: C

This program is to find all prime numbers and store them in an array. I don't want to take unnecessary memory by defining a fixed array before getting the exact number of prime numbers in a specific range. I also want to make this code to be able to run in C89 so, variable sized array is out of question here.
This is my code with 2 methods I found for this.
#include<stdio.h>
#include<stdlib.h>
struct prime{
int *arr;
int count;
};
int prmchk();
struct prime method1();
struct prime method2();
int main()
{
int min,max;
int i,j;
struct prime p[2];
printf("Enter limits of range..\n");
printf("min: ");
scanf("%d",&min);
printf("max: ");
scanf("%d",&max);
p[0] = method1(min,max);
p[1] = method2(min,max);
for(i = 0; i < 2; i++) //to test the results by printing them
{ //has nothing to do with the problem
printf("result of method %d: ",i+1);
for(j = 0; j < p[i].count; j++)
printf("%d ",p[i].arr[j]);
printf("\n");
}
}
struct prime method1(int min, int max) //function starts
{
struct prime pf;
int i;
int temparr[10000]; //No 2 consecutive no.s can be prime numbers simulteneously
int pcount = 0;
for(i = min; i <= max; i++)
{
if(prmchk(i) == 1)
temparr[pcount++] = i; //
}
pf.arr = (int*) malloc(pcount * sizeof(int));
for(i = 0; i < pcount; i++)
{
pf.arr[i] = temparr[i];
}
pf.count = pcount;
return pf;
}
struct prime method2(int min, int max)
{
struct prime pf;
pf.arr = (int*) malloc(0);
int i;
int pcount = 0;
for(i = min; i < max; i++)
{
if(prmchk(i) == 1)
{
pf.arr = (int*) realloc(pf.arr,++pcount*sizeof(int));
pf.arr[pcount-1] = i;
}
}
pf.count = pcount;
return pf;
}
int prmchk(int num)
{
int i;
if(num == 1)
return 0;
if(num == 2)
return 1;
for(i = 2; i < num; i++)
{
if(num%i == 0)
return 0;
}
return 1;
}
My questions are
Since I'm new to competitive programming I don't know which method will consume less memory and which one will consume less time. I want to know which method is better than the other.
If possible feel free to add a new method if you can think of any.
Can we use malloc(0) as used here
How the readability of this particular code could be improved more. I'm read some articles about it. But unable to get any proper understanding.

How can I pass values from one function to another?

I have created a program that takes in input "n" numbers that the user chooses and then prints the most repeated one, but I have a problem with passing the values between the functions so it gives me 0 as a result. How can I solve it?
void most_present_number(int array[]);
int read_numbers(int array[]);
int main() {
int array[400];
most_present_number(array);
return 0;
}
void most_present_number(int array[]){
read_numbers(array);
int i = 0;
int Max = 0;
int Current_number = vettore[0];
int Current_number_counter = 0;
int most_present_number = 0;
int most_present_number_counter = 0;
while (i < Max) {
if (array[i] == Current_number) {
Current_number_counter++;
i++;
} else {
if (Current_number_counter > most_present_number_counter){
most_present_number = Current_number;
most_present_number_counter = Current_number_counter;
}
Current_number = array[i];
Current_number_counter = 1;
i++;
}
}
printf("The most present number is %d which is repeated %d times\n", most_present_number,
most_present_number_counter);
}
int read_numbers(int array[]){
int Max = 0;
int i = 0;
printf("Insert the array lenght\n");
scanf("%d", &Max);
while (i < Max) {
printf("Insert the numbers\n");
scanf("%d", &array[i]);
i++;
}
return Max;
}
You have Max = 0 in most_present_number(), so the while loop stops immediately.
read_numbers() returns Max, so you can use this to initialize Max in most_present_number().
void most_present_number(int array[], int Max);
int read_numbers(int array[]);
int main() {
int array[400];
int size;
most_present_number(array);
return 0;
}
void most_present_number(int array[]){
int Max = read_numbers(array);
int i;
int Current_number = array[0];
int Current_number_counter = 0;
int most_present_number = 0;
int most_present_number_counter = 0;
for (i = 0; i < Max; i++) {
if (array[i] == Current_number) {
Current_number_counter++;
} else {
if (Current_number_counter > most_present_number_counter){
most_present_number = Current_number;
most_present_number_counter = Current_number_counter;
}
Current_number = array[i];
Current_number_counter = 1;
}
}
printf("The most present number is %d which is repeated %d times\n", most_present_number,
most_present_number_counter);
}
int read_numbers(int array[]){
int Max = 0;
int i = 0;
printf("Insert the array lenght\n");
scanf("%d", &Max);
while (i < Max) {
printf("Insert the numbers\n");
scanf("%d", &array[i]);
i++;
}
return Max;
}
Note also that your algorithm assumes that all the equal numbers will be together in the array. If they can be mixed up, you need a very different design. You need another array where you keep the counts of each number. Then at the end you find the entry in this array with the highest count.

Why does same program act different in ideone and codeblocks?

This code is designed to find the sum of digits of 100!. I get the correct ouput in ideone but the wrong one in codeblocks. Please help.
#include <stdio.h>
#include <stdlib.h>
#define size_of_number 160
#define question 100
//Function Prototypes
void initialise(int[]);
int sum_of_digits(int[]);
void factorial(int[],int);
int main()
{
int number[size_of_number];
int sum;
initialise(number);
factorial(number, question);
//Getting the sum of the digits of the number
sum = sum_of_digits(number);
printf("The sum of the digits of %d! is %d.\n",question, sum);
return 0;
}
//Initially, the number is 0 so all it's digits are set to zero.
void initialise(int number[])
{
int i;
for(i = 0; i < size_of_number; i++)
{
number[i] = 0;
}
}
//Finding the factorial by multiplying the digits
void factorial(int number[], int num)
{
int i, first_digit;
int carry, replace, product;
first_digit = 0;
number[first_digit] = 1;
while(num != 1)
{
carry = 0;
for(i = 0; i <= first_digit; i++)
{
product = num*number[i] + carry;
replace = product%10;
carry = product/10;
number[i] = replace;
if( (i == first_digit) && (carry > 0) )
{
first_digit++;
}
}
num--;
}
}
//Finding the sum of all digits
int sum_of_digits(int number[])
{
int i, sum;
for(i = 0; i < size_of_number; i++)
{
sum = sum + number[i];
}
return sum;
}
I had problems with some other programs too. Why s Codeblocks not giving the correct output which is 648 ?
You don't initialize sum in the function sum_of_digits. Normal local variables don't automatically get a starting value in C, so your program has what the C standard calls undefined behaviour. Anything can happen, but what typically does happen is that the variable starts with whatever data happened to be in the place in memory where the variable happened to be located.

Complex numbers using struct

I want to write a program that reads an array of complex numbers until 0+0j is entered and calculates the absolute value of these numbers and gives the maximum value.
i create a struct which includes im and re.
i take numbers from user and check it whether it is equal to 0+0j
i send the inputs array to absc function
in absc function i created a new array which is equal to sqrt(re^2+im^2) and i send this new array to another function find_max
in find_max i find the max value of absolute array.
Then i print the max value.
However, i fail and i don't understand where should correct.
#include<stdio.h>
#include<math.h>
#define SIZE 5
struct stComplex
{
int re, im;
};
typedef struct stComplex Complex;
float absc(float[]);
float find_max(float[]);
int main()
{
Complex inputs[SIZE]; //Array for inputs
int i;
float max;
for(i = 0; i < SIZE; i++
printf("Enter real part of complex number: ");
scanf("%d", &inputs[i].re);
printf("Enter imaginary part of complex number: ");
scanf("%d", &inputs[i].im);
if(inputs[i].re != 0 and inputs[i].im != 0)
{
continue;
}
else
{
return 1;
}
}
max = absc(Complex inputs[SIZE]); //Sending the real and imaginary parts to calculate absolute value
printf("The biggest absolute value is %f", max);
return 0;
}
float absc(Complex x[SIZE])
{
int i;
float absolute[SIZE], max;
for(i = 0; i < SIZE; i++)
{
absolute[i] = sqrt(pow(inputs[i].re, 2) + pow(inputs[i].im, 2));
}
max = find_max(absolute[SIZE]);
return max;
}
float find_max( float array[SIZE] )
{
int i, max;
max = array[0];
for( i = 1; i < SIZE; i++ )
{
if( max < array[ i ] )
max = array[ i ];
}
return max;
}
#include<stdio.h>
#include<math.h>
#define SIZE 5
struct stComplex
{
int re, im;
};
typedef struct stComplex Complex;
float absc(Complex inputs[]);
float find_max(float[]);
int main()
{
Complex inputs[SIZE]; //Array for inputs
int i;
float max;
for(i = 0; i < SIZE; i++)
{
printf("Enter real part of complex number: ");
scanf("%d", &inputs[i].re);
printf("Enter imaginary part of complex number: ");
scanf("%d", &inputs[i].im);
if(inputs[i].re != 0 && inputs[i].im != 0)
{
continue;
}
else
{
return 1;
}
}
max = absc(inputs); //Sending the real and imaginary parts to calculate absolute value
printf("The biggest absolute value is %f", max);
return 0;
}
float absc(Complex inputs[SIZE])
{
int i;
float absolute[SIZE], max;
for(i = 0; i < SIZE; i++)
{
absolute[i] = sqrt(pow(inputs[i].re, 2) + pow(inputs[i].im, 2));
}
max = find_max(absolute);
return max;
}
float find_max( float array[SIZE] )
{
int i, max;
max = array[0];
for( i = 1; i < SIZE; i++ )
{
if( max < array[ i ] )
max = array[ i ];
}
return max;
}

Add n Integers to an non fixed Array

I've been looking for a solution quite a while now, but did not manage to find anything.
I need a program which takes the users input (a random amount of integers) until EOF, sums them up and gives me back the average.
I tried it using an array but I am not sure whats my mistake here.
I managed to get it working with a fixed size array. But I need a flexible one.. Is this even possible?
Here is what I got so far:
#include <stdio.h>
int main()
{
int count = 3;
int numbers[count];
long sum;
float average;
int i;
for (i = 0; i < count; i++) {
while (scanf("%d", &numbers[i]) != EOF) {
sum += numbers[i];
}
}
average = (float)sum/count;
printf("Average of your numbers is: %.2f\n",average);
return 0;
}
If you're just trying to find the average then you don't need to actually store these numbers.
int count = 0;
int sum = 0;
int num = 0;
double avg = 0.0;
for(; scanf("%d", &num) != EOF; sum += num, count++)
;
avg = sum / count;
After checking with OP, he does not mind if the inputs are not stored in array. In that case, you may want to consider this:
int num=0;
int sum=0
int count=0;
do
{
printf("Enter number:");
scanf("%d", num);
sum += num;
count++;
printf("Proceed(y/n)?");
scanf("%c", proceed);
}while(proceed == 'y');
This code may be a little troublesome that you need to enter 'y' to continue inputing, but this may solve your current problem of inputting n inputs.
You will need to realloc the size of the array if you have filled the existing array. This should work:
#include <stdio.h>
#include <stdlib.h>
int main() {
int input;
int size = 0;
int* arr = NULL;
int* temp = NULL;
long sum = 0;
float average = 0;
do {
scanf("%d", &input);
size++;
temp = (int*) realloc(arr, sizeof(int)*size);
if(temp != NULL) {
arr = temp;
arr[size-1] = input;
}
sum += input;
} while(input != 0);
average = sum / size;
printf("sum: %lu\n", sum);
printf("average: %f\n", average);
return 0;
}
It does not have to be an array if all you're doing is adding up numbers
int number = 0;
int count = 0;
while(scanf("%d", &number)!=EOF)
{
sum += number;
count++;
}
Also this will never work because count is supposed to be a constant
int count = 3;
int numbers[count];

Resources