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


typedef struct 
{
   unsigned int  w;      /* weight           */
   unsigned int  c;      /* cost             */
} Item;


typedef struct 
{
   unsigned int  n;      /* number of items  */
   unsigned int  W;      /* weight bound     */
   double        eps;    /* epsilon          */
   Item *        items;  /* array of items   */
} Instance;


/**
 * The function frees an instance (or what is left of it)
**/
void free_instance(Instance * instance)
{
   if (instance != NULL) {
      if (instance->items != NULL) {
         free(instance->items);
      }
      free(instance);
   }
}


/**
 * The function reads a KNAPSACK file meeting the requirements stated under
 * http://www.or.uni-bonn.de/lectures/ss13/approximation_uebung_ss13.html
 * If an error occurs during malloc or fopen, NULL is returned.
**/
Instance * read_instance(const char * filename)
{
   FILE *        fp;
   unsigned int  i;
   Instance *    inst;

   if (!(fp = fopen(filename, "r")))
   {
      printf("Could not open %s.\n", filename);
      return NULL;
   }
   
   inst = (Instance *)malloc(sizeof(Instance));
   if (inst == NULL) {
      printf("Error occured during malloc!\n");
      fclose(fp);
      return NULL;
   }

   /* Read n W and eps from file. */
   if (fscanf(fp, "%u %u %lf", &inst->n, &inst->W, &inst->eps) != 3) {
      printf("Error occured during scanf!\n");
      free_instance(inst);
      fclose(fp);
      return NULL;
   }

   inst->items = (Item *)malloc(inst->n * sizeof(Item));
   if (inst->items == NULL) {
      printf("Error occured during malloc!\n");
      free_instance(inst);
      fclose(fp);
      return NULL;
   }

   for (i = 0; i < inst->n; ++i) {
      if (fscanf(fp, "%u %u", &(inst->items[i].c), &(inst->items[i].w)) != 2) {
         printf("Error occured during scanf!\n");
         free_instance(inst);
         fclose(fp);
         return NULL;
      }
   }
   
   fclose(fp);
   return inst;
}


/**
 * Prints a given KNAPSACK instance
**/
void print_instance(Instance * instance)
{
   unsigned int i;
   
   if (instance == NULL) {
      return;
   }
   if ((instance->n != 0) && (instance->items == NULL)) {
      printf("Wrong number of items stored\n");
      return;
   }

   printf("Instance:  n %u, W %u, eps %f\n",
          instance->n, instance->W, instance->eps);
   for (i = 0; i < instance->n; ++i)
   {
      printf("Item %u: %u %u\n",
             i, instance->items[i].c, instance->items[i].w);
   }
}


/**
 * main function: plug in your code here
**/
int main(int argc, const char ** argv)
{
   Instance * instance = NULL;
   if(argc < 2){
      printf("Specify a filename\n");
      return EXIT_FAILURE;
   }
   instance = read_instance(argv[1]);
   print_instance(instance);
   free_instance(instance);
   return EXIT_SUCCESS;
}
