Dobro došli gosti

Autor zadatka: Rade Radišić <radisic.rade@uns.ac.rs>

Napisati program koji pronalazi najpogodniji za proslavu među zadatim restoranima. Podaci su zadati u ulaznoj datoteci u sledećem formatu:

  • naziv (jedna reč, do 20 karaktera)

  • cena_po_osobi (u dinarima, realan broj)

  • kapacitet (celobrojna vrednost)

  • broj_konobara (celobrojna vrednost)

Učitati restorane u statički niz, zatim na osnovu zadatog broja gostiju i kursa evra ispisati sve restorane sa cenom preračunatom u evre, osim onih čiji kapacitet premašuje zadati broj gostiju. U tom slučaju, umesto cene, ispisati nedovoljno kapaciteta. Broj gostiju i kurs evra zadaju se kao argumenti komandne linije. Kod restorana sa dovoljnim kapacitetom ispisati i odnos na koliko gostiju dolazi jedan konobar. U slučaju decimalnog rezultata, zaokružiti broj gostiju po konobaru na prvu sledeću celobrojnu vrednost nakon deljenja.

Osim ispisivanja svih restorana, potrebno je pronaći i ispisati na standardni izlaz restoran sa najmanjim koeficijentom za restorane koji ispunjavaju zahtev za kapacitetom. Koeficijent se računa na sledeći način:

\[koeficijent = cena\_po\_osobi \div \lceil \frac{broj\_gostiju}{broj\_konobara} \rceil\]

U slučaju uspešnog izvršavanja programa, izaći sa status kodom 0 (EXIT_SUCCESS). Ukoliko program ne može da se izvrši do kraja usled sledećih nedostataka, izaći iz programa sa sledećim status kodovima:

  • U slučaju nedovoljnog ili suvišnog broj argumenata komandne linije, izaći iz programa sa status kodom 1 (EXIT_FAILURE)

  • Ako program ne može da otvori ulazni fajl, izaći sa status kodom 2

  • Ako program ne može da otvori izlazni fajl, izaći sa status kodom 3

Primer poziva programa:

./a.out restorani.txt 120 117.5

Primer ulazne datoteke restorani.txt:

Kafanica   1199.99  50  5
MalaHala   2130.00 150 12
Restoran   1341.99 100  7
BastaMala  2099.99 162 15
KodMacka   2439.99  72  8
VelikaHala 1999.99 214 14

Primer izlazne datoteke cene_za_120_ljudi.txt:

Kafanica nedovoljno kapaciteta
MalaHala 2175.32e 1/10
Restoran nedovoljno kapaciteta
BastaMala 2144.67e 1/8
KodMacka nedovoljno kapaciteta
VelikaHala 2042.54e 1/9

Ispis programa na standardnom izlazu:

Najpogodniji restoran za slavlje: MalaHala 2175.32e 1/10

Primer rešenja

  1#include <stdio.h>
  2#include <math.h>
  3#include <string.h>
  4#include <stdlib.h>
  5
  6#define MAX_NAZIV 21
  7
  8#define MAX_RESTORANA 20
  9
 10#define MAX_IME_DATOTEKE 23
 11
 12typedef struct restoran_st {
 13    char naziv[MAX_NAZIV];
 14    double cena_po_osobi;
 15    int kapacitet;
 16    int broj_konobara;
 17} RESTORAN;
 18
 19FILE *safe_fopen(char *, char *, int);
 20void ucitaj_restorane(FILE *, RESTORAN *, int *);
 21double ukupna_cena_u_evrima(double, int, double);
 22int broj_gostiju_po_konobaru(int, int);
 23void ispisi_restorane(FILE *, RESTORAN *, int, int, double);
 24RESTORAN pronadji_optimalni_restoran(RESTORAN *, int, int);
 25
 26int main(int argc, char **argv) {
 27    RESTORAN restorani[MAX_RESTORANA];
 28    int n;
 29
 30    if(argc != 4) {
 31        printf("Primer poziva programa: %s restorani.txt 120 117.5\n", argv[0]);
 32        exit(1);
 33    }
 34
 35    FILE *pulazna = safe_fopen(argv[1], "r", 2);
 36    ucitaj_restorane(pulazna, restorani, &n);
 37    fclose(pulazna);
 38
 39    int broj_gostiju = atoi(argv[2]);
 40    double kurs_evra = atof(argv[3]);
 41    
 42    char ime_datoteke[MAX_IME_DATOTEKE] = "cene_za_";
 43    strcat(ime_datoteke, argv[2]);
 44    strcat(ime_datoteke, "_ljudi.txt");
 45    FILE *pizlazna = safe_fopen(ime_datoteke, "w", 3);
 46    ispisi_restorane(pizlazna, restorani, n, broj_gostiju, kurs_evra);
 47    RESTORAN optimalni_restoran = pronadji_optimalni_restoran(restorani, n, broj_gostiju);
 48    printf("Najpogodniji restoran za slavlje: %s %.2lfe 1/%d\n",
 49           optimalni_restoran.naziv,
 50           ukupna_cena_u_evrima(optimalni_restoran.cena_po_osobi, broj_gostiju, kurs_evra),
 51           (int)ceil((double)broj_gostiju / optimalni_restoran.broj_konobara));
 52    fclose(pizlazna);
 53
 54    return 0;
 55}
 56
 57FILE *safe_fopen(char *ime, char *rezim, int kod_greske) {
 58    FILE *fp = fopen(ime, rezim);
 59
 60    if(fp == NULL) {
 61        printf("Greska prilikom otvaranja %s datoteke!\n", ime);
 62        exit(kod_greske);
 63    }
 64
 65    return fp;
 66}
 67
 68void ucitaj_restorane(FILE *pulazna, RESTORAN *restorani, int *pn) {
 69    int i = 0;
 70
 71    while(fscanf(pulazna, "%s %lf %d %d",
 72                 restorani[i].naziv,
 73                 &restorani[i].cena_po_osobi,
 74                 &restorani[i].kapacitet,
 75                 &restorani[i].broj_konobara) != EOF) {
 76        i++;
 77    }
 78
 79    *pn = i;
 80}
 81
 82double ukupna_cena_u_evrima(double cena_po_osobi, int broj_ljudi, double kurs) {
 83    return cena_po_osobi * broj_ljudi / kurs;
 84}
 85
 86int broj_gostiju_po_konobaru(int broj_gostiju, int broj_konobara) {
 87    return (int)ceil((double)broj_gostiju / broj_konobara);
 88}
 89
 90void ispisi_restorane(FILE *pizlazna, RESTORAN *restorani, int n, int broj_gostiju, double kurs) {
 91    int i;
 92
 93    for(i = 0;i < n;i++) {
 94        if(restorani[i].kapacitet >= broj_gostiju) {
 95            fprintf(pizlazna, "%s %.2lfe 1/%d\n",
 96                    restorani[i].naziv,
 97                    ukupna_cena_u_evrima(restorani[i].cena_po_osobi, broj_gostiju, kurs),
 98                    broj_gostiju_po_konobaru(broj_gostiju, restorani[i].broj_konobara));
 99        } else {
100            fprintf(pizlazna, "%s nedovoljno kapaciteta\n", restorani[i].naziv);
101        }
102    }
103}
104
105RESTORAN pronadji_optimalni_restoran(RESTORAN *restorani, int n, int broj_gostiju) {
106    int i;
107    RESTORAN optimalni_restoran;
108    double min_koeficijent, koeficijent_restorana;
109
110    for(i = 0;i < n;i++) {
111        if(broj_gostiju <= restorani[i].kapacitet) {
112            optimalni_restoran = restorani[i];
113            min_koeficijent = restorani[i].cena_po_osobi / broj_gostiju_po_konobaru(broj_gostiju, restorani[i].broj_konobara);
114            break;
115        }
116    }
117
118    for(i = 0;i < n;i++) {
119        if(broj_gostiju <= restorani[i].kapacitet) {
120            koeficijent_restorana = restorani[i].cena_po_osobi / broj_gostiju_po_konobaru(broj_gostiju, restorani[i].broj_konobara);
121            if(koeficijent_restorana < min_koeficijent) {
122                optimalni_restoran = restorani[i];
123                min_koeficijent = koeficijent_restorana;
124            }
125        }
126    }
127
128    return optimalni_restoran;
129}
130