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:
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
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".
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