Fudbal

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

Učinak fudbalskog tima tokom sezone opisan je sledećim poljima:

  • naziv tima (do 30 karaktera)

  • gol razlika (ceo broj)

  • broj bodova (neoznačen, ceo broj)

Svaki tim, pored imena i gol razlike, u ulaznoj datoteci postoje, redom, broj pobeda, nerešenih utakmica i poraza. Sa podacima iz ulazne datoteke uraditi sledeće:

  1. Učitati ih u niz struktura koje odgovaraju gornjem opisu. Iskoristiti broj pobeda, nerešenih utakmica i poraza za računanje trenutnog broja bodova po sledećem principu:

    • Pobeda nosi 3 boda

    • Nerešena utakmica nosi 1 bod

    • Poraz nosi 0 bodova

  2. U izlaznu datoteku ispisati sve timove koji se sa brojem bodova nalaze u intervalu između prosečnog broja bodova u ligi i vrednosti zadate kao argument komandne linije. Datoteku nazvati sa prefiksom "izmedju_proseka_i_", pa onda staviti broj bodova unet kao argument komandne linije i postfiks "_bodova.txt".

  3. Sortirati tabelu po broju bodova. U slučaju da dve ekipe imaju isti broj bodova, prednost ima ona ekipa koja ima veću gol razliku. Prve tri ekipe idu u "Ligu šampiona", sledeće dve u "Ligu Evrope", a poslednje tri su u "zoni ispadanja". Prilikom ispisa u izlaznu datoteku posebno podvući crtu ispod timova koji su plasirani za "Lige", odnosno iznad "zone ispadanja".

Primer ulazne datoteke statistika.txt:

Atalanta 7 8 1 4
Bologna -5 4 4 5
Cagliari -10 5 1 7
Chievoverona -1 5 3 5
Crotone -16 1 2 10
Empoli -11 2 4 7
Fiorentina 7 5 5 2
Genoa 0 4 4 4
Inter 2 5 3 5
Juventus 19 11 0 2
Lazio 12 7 4 2
Milan 4 8 2 3
Napoli 9 7 3 3
Palermo -16 1 3 9
Pescara -14 1 4 8
Roma 16 8 2 3
Sampdoria -3 5 3 5
Sassuolo -9 4 1 8
Torino 13 6 4 3
Udinese -4 4 3 6

Primer izlazne datoteke tabela.txt:

Juventus 19 33
Roma 16 26
Milan 4 26
-------------------
Lazio 12 25
Atalanta 7 25
-------------------
Napoli 9 24
Torino 13 22
Fiorentina 7 20
Inter 2 18
Chievoverona -1 18
Sampdoria -3 18
Genoa 0 16
Bologna -5 16
Cagliari -10 16
Udinese -4 15
Sassuolo -9 13
Empoli -11 10
-------------------
Pescara -14 7
Palermo -16 6
Crotone -16 5

Primer izlazne datoteke izmedju_proseka_i_25_bodova.txt:

Atalanta 7 25
Chievoverona -1 18
Fiorentina 7 20
Inter 2 18
Lazio 12 25
Napoli 9 24
Sampdoria -3 18
Torino 13 22

Primer poziva programa:

./fudbal statistika.txt tabela.txt 20

Primer rešenja

  1#include <stdio.h>
  2#include <string.h>
  3#include <stdlib.h>
  4
  5#define MAX_SIZE 30
  6
  7#define MAX_NAZIV 31
  8
  9#define MAX_IME_DATOTEKE 36
 10
 11#define LIGA_SAMPIONA 3
 12#define LIGA_EVROPE 5
 13#define VELICINA_ZONE_ISPADANJA 3
 14
 15typedef struct fudbal_st {
 16    char naziv_tima[MAX_NAZIV];
 17    int gol_razlika;
 18    unsigned broj_bodova;
 19} FUDBAL;
 20
 21FILE *safe_fopen(char *naziv, char *rezim, int kod_greske);
 22void ucitaj_statistiku(FILE *pulazna, FUDBAL *ekipe, int *pn);
 23void ispisi_interval(FILE *pizlazna, FUDBAL *ekipe, int n, unsigned broj_bodova);
 24void ispisi_tabelu(FILE *pizlazna, FUDBAL *ekipe, int n);
 25unsigned suma_bodova(FUDBAL *ekipe, int n);
 26double prosek_bodova(FUDBAL *ekipe, int n);
 27void sortiraj_ekipe(FUDBAL *ekipe, int n);
 28unsigned izracunaj_bodove(unsigned broj_pobeda, unsigned broj_neresenih);
 29
 30int main(int argc, char **argv) {
 31    FUDBAL ekipe[MAX_SIZE];
 32    int n;
 33
 34    FILE *pulazna, *pizlazna_interval, *pizlazna_tabela;
 35
 36    if(argc != 4) {
 37        printf("Primer poziva programa: %s statistika.txt tabela.txt 25\n", argv[0]);
 38        exit(EXIT_FAILURE);
 39    }
 40
 41    // a
 42
 43    pulazna = safe_fopen(argv[1], "r", 2);
 44    ucitaj_statistiku(pulazna, ekipe, &n);
 45    fclose(pulazna);
 46
 47    // b
 48    
 49    char ime_datoteke[MAX_IME_DATOTEKE] = "izmedju_proseka_i_";
 50    strcat(ime_datoteke, argv[3]);
 51    strcat(ime_datoteke, "_bodova.txt");
 52    unsigned broj_bodova = atoi(argv[3]);
 53    pizlazna_interval = safe_fopen(ime_datoteke, "w", 3);
 54    ispisi_interval(pizlazna_interval, ekipe, n, broj_bodova);
 55    fclose(pizlazna_interval);
 56
 57    // c
 58
 59    sortiraj_ekipe(ekipe, n);
 60    pizlazna_tabela = safe_fopen(argv[2], "w", 4);
 61    ispisi_tabelu(pizlazna_tabela, ekipe, n);
 62    fclose(pizlazna_tabela);
 63
 64    return EXIT_SUCCESS;
 65}
 66
 67FILE *safe_fopen(char *naziv, char *rezim, int kod_greske) {
 68    FILE *fp = fopen(naziv, rezim);
 69
 70    if(fp == NULL) {
 71        printf("Datoteku %s nije moguce otvoriti!\n", naziv);
 72        exit(kod_greske);
 73    }
 74
 75    return fp;
 76}
 77
 78void ucitaj_statistiku(FILE *pulazna, FUDBAL *ekipe, int *pn) {
 79    int i = 0;
 80    unsigned broj_pobeda, broj_neresenih, broj_poraza;
 81
 82    while(fscanf(pulazna, "%s %d %u %u %u", 
 83                 ekipe[i].naziv_tima, 
 84                 &ekipe[i].gol_razlika,
 85                 &broj_pobeda,
 86                 &broj_neresenih,
 87                 &broj_poraza) != EOF) {
 88        // broj_poraza se ne koristi u daljim proracunima (ne dobijaju se bodovi), 
 89        // ali moramo ucitati iz datoteke kako bismo presli na ucitavanje novog reda
 90        ekipe[i].broj_bodova = izracunaj_bodove(broj_pobeda, broj_neresenih);
 91        i++;
 92    }
 93
 94    *pn = i;
 95}
 96
 97void ispisi_interval(FILE *pizlazna, FUDBAL *ekipe, int n, unsigned broj_bodova) {
 98    int i;
 99
100    double prosek = prosek_bodova(ekipe, n);
101
102    for(i = 0;i < n;i++) {
103        if(ekipe[i].broj_bodova >= prosek && ekipe[i].broj_bodova <= broj_bodova) {
104            fprintf(pizlazna, "%s %d %u\n", ekipe[i].naziv_tima, ekipe[i].gol_razlika, ekipe[i].broj_bodova);
105        }
106    }
107}
108
109void ispisi_tabelu(FILE *pizlazna, FUDBAL *ekipe, int n) {
110    int i;
111
112    for(i = 0;i < n;i++) {
113        if(i == LIGA_SAMPIONA || i == LIGA_EVROPE || i == n - VELICINA_ZONE_ISPADANJA) {
114            fprintf(pizlazna, "-------------------\n");
115        }
116        fprintf(pizlazna, "%s %d %u\n", ekipe[i].naziv_tima, ekipe[i].gol_razlika, ekipe[i].broj_bodova);
117    }
118}
119
120unsigned izracunaj_bodove(unsigned broj_pobeda, unsigned broj_neresenih) {
121    return 3 * broj_pobeda + broj_neresenih;
122}
123
124unsigned suma_bodova(FUDBAL *ekipe, int n) {
125    int i;    
126    unsigned suma = 0;
127
128    for(i = 0;i < n;i++) {
129        suma += ekipe[i].broj_bodova;
130    }
131
132    return suma;
133}
134
135double prosek_bodova(FUDBAL *ekipe, int n) {
136    return (double) suma_bodova(ekipe, n) / n;
137}
138
139void sortiraj_ekipe(FUDBAL *ekipe, int n) {
140    int i, j, max_idx;
141    FUDBAL tmp_ekipa;
142
143    for(i = 0;i < n - 1;i++) {
144        max_idx = i;
145        for(j = i + 1;j < n;j++) {
146            if(ekipe[max_idx].broj_bodova < ekipe[j].broj_bodova ||
147               (ekipe[max_idx].broj_bodova == ekipe[j].broj_bodova && 
148                ekipe[max_idx].gol_razlika < ekipe[j].gol_razlika)) {
149                max_idx = j;
150            }
151        }
152
153        if(i != max_idx) {
154            tmp_ekipa = ekipe[i];
155            ekipe[i] = ekipe[max_idx];
156            ekipe[max_idx] = tmp_ekipa;
157        }
158    }
159}
160