Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// ProductEntry
typedef struct {
char month[4];
char product[50];
int sales;
} ProductEntry;
// Y: number of rows (products)
// X: number of cols (months)
#define Y 11
#define X 12
// Index->name mappings
const char PRODSTR[Y][50] = {"Note A", "Note B", "Note C", "Ballpoint pen A", "Ballpoint pen B", "Ballpoint pen C",
"Pencil", "Marker", "Pencil case", "Erase A", "Erase B"};
const char MONTHSTR[X][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
// Create an initialized ProductEntry data[][] by using an int numbers[][] as input
void ProductEntry_create(int y, int x, ProductEntry data[y][x], int numbers[y][x]);
// arrprint...(...) : array printing functions
void arrprintheader(void);
void arrprintall(int y, int x, ProductEntry a[y][x]);
void arrprintmonth3(int y, int x, ProductEntry a[y][x], int month_index);
void arrprintproduct3(int y, int x, ProductEntry a[y][x], int product_index);
// arrcopy(y, x, a, b): copy elements of a into b
// arrtrans(y, x, a, aT): transpose a into aT
void arrcopy(int y, int x, ProductEntry a[y][x], ProductEntry b[y][x]);
void arrtrans(int y, int x, ProductEntry a[y][x], ProductEntry aT[x][y]);
// arrsort, arrsortrows, arrsortcolumns: array sorting
void arrsort(int n, ProductEntry a[n]);
void arrsortrows(int y, int x, ProductEntry a[y][x]);
void arrsortcolumns(int y, int x, ProductEntry a[y][x]);
int main(int argc, char *argv[])
{
int rawnumbers[Y] [X] = {
{34, 56, 27, 100, 74, 56, 12, 5, 87, 29, 63, 16},
{9, 11, 14, 55, 30, 4, 47, 150, 136, 26, 18, 12},
{46, 3, 22, 8, 78, 14, 52, 27, 35, 80, 123, 90},
{58, 38, 79, 120, 85, 52, 39, 23, 31, 10, 10, 46},
{8, 5, 3, 8, 2, 21, 7, 3, 8, 13, 8, 7},
{26, 32, 28, 26, 24, 20, 19, 22, 23, 28, 30, 29},
{12, 19, 54, 51, 41, 36, 20, 28, 3, 5, 7, 32},
{22, 14, 53, 21, 25, 23, 22, 180, 31, 6, 213, 58},
{10, 14, 43, 12, 13, 17, 14, 12, 11, 9, 54, 15},
{21, 20, 28, 17, 19, 14, 13, 12, 17, 18, 14, 11},
{24, 21, 13, 24, 20, 16, 13, 17, 24, 38, 23, 28} };
// Initialize rawdata table
ProductEntry rawdata[Y][X];
ProductEntry_create(Y, X, rawdata, rawnumbers);
printf("\nTop sales by month:\n");
ProductEntry bymonth[Y][X];
arrcopy(Y, X, rawdata, bymonth);
arrsortcolumns(Y, X, bymonth);
arrprintheader();
for(int monthid=0; monthid <= X-1; monthid++)
arrprintmonth3(Y, X, bymonth, monthid);
printf("\nTop sales sorted by product:\n");
ProductEntry byproduct[Y][X];
arrcopy(Y, X, rawdata, byproduct);
arrsortrows(Y, X, byproduct);
arrprintheader();
for (int prodid=0; prodid <= Y-1; prodid++)
arrprintproduct3(Y, X, byproduct, prodid);
return 0;
}
void ProductEntry_create(int y, int x, ProductEntry data[y][x], int numbers[y][x]) {
for (int i=0; i < y; i++)
for (int j=0; j < x; j++) {
strcpy(data[i][j].month, MONTHSTR[j]);
strcpy(data[i][j].product, PRODSTR[i]);
data[i][j].sales = numbers[i][j];
}
}
void arrprintheader(void) {
printf("%-5s %-20s %-5s\n", "---", "-------------", "-----");
printf("%-5s %-20s %-5s\n", "Mon", "Product name", "Sales");
printf("%-5s %-20s %-5s\n", "---", "-------------", "-----");
}
void arrprintall(int y, int x, ProductEntry a[y][x]) {
arrprintheader();
for (int i=0; i < y; i++) {
for (int j=0; j < x; j++) {
printf("%-5s %-20s %-5d\n", a[i][j].month, a[i][j].product, a[i][j].sales);
}
}
}
void arrprintmonth3(int y, int x, ProductEntry a[y][x], int mo) {
for (int i=0; i < 3; i++) {
printf("%-5s %-20s %-5d\n", a[i][mo].month, a[i][mo].product, a[i][mo].sales);
}
}
void arrprintproduct3(int y, int x, ProductEntry a[y][x], int pr) {
for (int i=0; i < 3; i++) {
printf("%-5s %-20s %-5d\n", a[pr][i].month, a[pr][i].product, a[pr][i].sales);
}
}
void arrcopy(int y, int x, ProductEntry a[y][x], ProductEntry b[y][x]) {
for (int i=0; i < y; i++)
for (int j=0; j < x; j++)
b[i][j] = a[i][j];
}
void arrtrans(int y, int x, ProductEntry a[y][x], ProductEntry aT[x][y]) {
for (int i=0; i < y; i++)
for (int j=0; j < x; j++)
aT[j][i] = a[i][j];
}
static inline int ProductEntry_sort_desc(const void*a, const void *b) {
const ProductEntry *x = a;
const ProductEntry *y = b;
return y->sales - x->sales;
}
void arrsort(int n, ProductEntry a[n]) {
qsort(a, n, sizeof(a[0]), ProductEntry_sort_desc);
}
void arrsortrows(int y, int x, ProductEntry a[y][x]) {
for (int i=0; i < y; i++)
arrsort(x, a[i]);
}
void arrsortcolumns(int y, int x, ProductEntry a[y][x]) {
ProductEntry aT[x][y];
arrtrans(y, x, a, aT);
arrsortrows(x, y, aT);
arrtrans(x, y, aT, a);
}