-1

As an assignment for my course on Design and Analysis of Algorithms, I was asked to determine the minimum number of coins required for giving a change, using a greedy approach. I came up with this intuitive approach:

#include<stdio.h>
#include<stdlib.h>

int main(){
  int hundreds=0,tens=0,ones=0,sum=0;

  printf("Enter a sum of money in range 1 to 999\n");
  scanf("%d",&sum);
  while(sum!=0) {
    if (sum<10&&sum>=1){
      ones=sum/1;
      sum-=ones;
    }
    else if(sum>=10&&sum<100){
      tens=sum/10;
      sum-=tens*10;
    }
    else if(sum>=100&&sum<=999){
      hundreds=sum/100;
      sum-=hundreds*100;
    }
    else{
      printf("Error");
      exit(0);
    }
  }

  printf("%d $100, %d $10, %d $1",hundreds,tens,ones);
  return 0;
}

Is this approach greedy? How do I prove that the program is correct and uses the greedy approach?

bruno
  • 32,421
  • 7
  • 25
  • 37
Divyanshu Varma
  • 122
  • 3
  • 17
  • 3
    Who told you to use a greedy approach? Did you ask them what they mean by 'a greedy approach'? – JeffUK Mar 06 '19 at 17:25
  • This can be solved without a loop; in each iteration, exactly 1 of the cases will be true, and will never be true in any future iteration. – Scott Hunter Mar 06 '19 at 17:28
  • While the compiler doesn't care about spaces, empty lines, indentation or comments, those things are very important to humans attempting to read and understand your code. – Some programmer dude Mar 06 '19 at 17:29
  • By 'a greedy approach' I mean a greedy algorithm. So is this program using a greedy algorithm? How do I prove it? – Divyanshu Varma Mar 06 '19 at 17:37
  • @DivyanshuVarma there is no limit on the greedy because it is possible to add any useless computation, but it is easily possible to do more greedy, look my answer – bruno Mar 06 '19 at 17:44
  • Since the question is about the minimum number of coins. Are we discussing English pounds or American coins or something else? – user3629249 Mar 07 '19 at 16:53
  • OT: regarding: `scanf("%d",&sum);` Always check the returned value (not the parameter values) to assure the operation was successful – user3629249 Mar 07 '19 at 16:57

3 Answers3

4

This is indeed greedy approach but you need to reverse the order of if-then-else. In general, greedy means to consume at the current moment the biggest quantity that you can consume.

You need to check first for the biggest coin. There is no need for while-loop.

if(sum>=100) {
  hundreds=sum/100;
  sum-=hundreds*100;
}
if(sum>=10){
  tens=sum/10;
  sum-=tens*10;
} 
ones = sum; 
alinsoar
  • 15,386
  • 4
  • 57
  • 74
1

Your code is not enough greedy because it can be worst :

#include<stdio.h>
#include<stdlib.h>

int main(){
  int hundreds=0,tens=0,ones=0,sum=0;

  printf("Enter a sum of money in range 1 to 999\n");
  if ((scanf("%d",&sum) == 1) && (sum >= 1) && (sum <= 999)) {
    while(sum!=0) {
      if (sum<10&&sum>=1){
        ones += 1;
        sum -= 1;
      }
      else if(sum>=10&&sum<100){
        tens += 1;
        sum -= 10;
      }
      else if(sum>=100&&sum<=999){
        hundreds += 1;
        sum -= 100;
      }
      else{ /* impossible case in fact */
        printf("Error");
        exit(0);
      }
    }

    printf("%d $100, %d $10, %d $1\n",hundreds,tens,ones);
  }
  return 0;
}

Compilation and execution:

pi@raspberrypi:/tmp $ gcc -pedantic -Wextra g.c
pi@raspberrypi:/tmp $ ./a.out
Enter a sum of money in range 1 to 999
997
9 $100, 9 $10, 7 $1

How do I prove that the program is correct

A (greedy) way to prove the code is correct is to use the brutal force to check all from result from 1 to 999 :

#include<stdio.h>
#include<stdlib.h>

int main(){
  int n;

  for (n = 1; n <= 999; ++n) {
    /* the algo */
    int hundreds=0,tens=0,ones=0, sum = n;

    while(sum!=0) {
      if (sum<10&&sum>=1){
        ones += 1;
        sum -= 1;
      }
      else if(sum>=10&&sum<100){
        tens += 1;
        sum -= 10;
      }
      else if(sum>=100&&sum<=999){
        hundreds += 1;
        sum -= 100;
      }
      else{ /* impossible case in fact */
        printf("Error");
        exit(0);
      }
    }

    /* check */
    if ((hundreds*100 + tens*10 + ones) != n) {
      printf("error for %d : %d $100, %d $10, %d $1\n",n, hundreds,tens,ones);
      exit(0);
    }
  }
  puts("all ok");
  return 0;
}

Compilation and execution :

pi@raspberrypi:/tmp $ gcc -pedantic -Wextra g.c
pi@raspberrypi:/tmp $ ./a.out
all ok
bruno
  • 32,421
  • 7
  • 25
  • 37
0

The following proposed code:

  1. cleanly compiles
  2. does not include header files those contents are not used
  3. follows the axiom: only one statement per line and (at most) one variable declaration per statement.
  4. performs the desired functionality
  5. performs appropriate error checking
  6. performs a 'greedy' algorithm of consuming as much of the 'money' as quickly as possible, using the least number of 'bills'

and now, the proposed code:

#include <stdio.h>


int main( void )
{
    int sum;

    do
    {
        printf("Enter a sum of money in range 1 to 999\n");
        if( scanf("%d",&sum) != 1)
        {
            fprintf( stderr, "scanf failed\n");
            return -1;
        }       
    } while( sum<0 || sum>999 );

    int hundreds = sum/100;
    sum          = sum % 100;
    int tens     = sum/10;
    sum          = sum % 10;
    int ones     = sum;

    printf("%d $100, %d $10, %d $1\n",hundreds,tens,ones);
}

The proposed code ignores the (American) bills $50, $20, $5, and $2

user3629249
  • 16,402
  • 1
  • 16
  • 17