#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define NO_T_DEBUG
#define FIN "trapez.in"
#define FOUT "trapez.out"
typedef struct point_s {
int x,y;
} point;
typedef struct pnt_s {
double panta;
point *p1,*p2;
} pnt;
point *point_alloc(int x, int y);
void point_free(point *p);
pnt *pnt_alloc(point *p1, point *p2);
void pnt_free(pnt *pn);
point **point_getplist(char *finfn, int *plist_s);
pnt **pnt_list(point **plist, int plist_s, int *pntlist_s);
int parallel_count(pnt **pntlist, int pntlist_s);
void write_results(char *foufn, int tval);
int util_cmbn(int n);
int util_cmp(const void *pnt2, const void *pnt1);
point *point_alloc(int x, int y) {
point *p;
p = calloc(1, sizeof(*p));
assert(p != NULL);
p->x = x;
p->y = y;
return p;
}
void point_free(point *p) {
if (p != NULL) {
free(p);
}
}
pnt *pnt_alloc(point *p1, point *p2) {
int tmpydif;
pnt *pn = NULL;
pn = calloc(1, sizeof(*pn));
assert(pn != NULL);
pn->p1 = p1;
pn->p2 = p2;
tmpydif = pn->p1->y - pn->p2->y;
if (tmpydif == 0) {
pn->panta = INT_MAX;
#ifndef NO_T_DEBUG
printf("(%d - %d) / (%d - %d) = %3.3f \n", pn->p1->x,
pn->p2->x,
pn->p1->y,
pn->p2->y,
pn->panta);
#endif
} else {
pn->panta = ((double)(pn->p1->x - pn->p2->x)) / tmpydif;
#ifndef NO_T_DEBUG
printf("(%d - %d) / (%d - %d) = %3.3f \n", pn->p1->x,
pn->p2->x,
pn->p1->y,
pn->p2->y,
pn->panta);
#endif
}
return pn;
}
void pnt_free(pnt *pn) {
if (pn != NULL) {
free(pn->p1);
free(pn->p2);
free(pn);
}
}
point **point_getplist(char *finfn, int *plist_s) {
FILE *f;
point **plist;
int i,x,y;
f = fopen(finfn,"r");
assert(f != NULL);
fscanf(f, "%d", plist_s);
assert(*plist_s > 0);
plist = calloc(*plist_s, sizeof(*plist));
assert(plist != NULL);
for (i = 0; i < *plist_s; i++) {
fscanf(f, "%d", &x);
fscanf(f, "%d", &y);
plist[i] = point_alloc(x, y);
assert(plist != NULL);
}
fclose(f);
return plist;
}
pnt **pnt_list(point **plist, int plist_s, int *pntlist_s) {
pnt **pntlist = NULL;
int i, j, k;
assert(plist != NULL);
*pntlist_s = util_cmbn(plist_s);
pntlist = calloc(*pntlist_s, sizeof(*pntlist));
assert(pntlist != NULL);
k = 0;
for (i = 0; i < plist_s ; i++) {
for (j = i + 1; j < plist_s ; j++) {
pntlist[k] = pnt_alloc(plist[i], plist[j]);
assert(pntlist[i] != NULL);
k++;
}
}
#ifndef NO_T_DEBUG
printf("Before sort: \n");
for (i = 0; i < *pntlist_s ; i++) {
printf("[%d] : %15.3f : (%d %d) (%d %d) \n", i,
pntlist[i]->panta,
pntlist[i]->p1->x,
pntlist[i]->p1->y,
pntlist[i]->p2->x,
pntlist[i]->p2->y);
}
printf("Success!\n");
#endif
return pntlist;
}
int parallel_count(pnt **pntlist, int pntlist_s) {
int i,j,c;
assert(pntlist != NULL);
c = 0;
#ifndef NO_T_DEBUG
printf("Test panta eq. : \n");
#endif
for (i = 0; i < pntlist_s ; i++) {
for (j = i+1; j < pntlist_s ; j++) {
#ifndef NO_T_DEBUG
printf("%15.3f == %15.3f -> %d \n", pntlist[i]->panta,
pntlist[j]->panta,
pntlist[i]->panta == pntlist[j]->panta);
#endif
if ( pntlist[i]->panta == pntlist[j]->panta) {
c++;
}
}
}
return c;
}
void write_results(char *foufn, int tval){
FILE *f = NULL;
f = fopen(foufn, "w");
assert(f!=NULL);
fprintf(f, "%d", tval);
fclose(f);
}
int util_cmbn(int n) {
assert( n > 0);
return n * (n - 1) / 2;
}
int main() {
int *plist_s, *pntlist_s;
point **plist;
pnt **pntlist;
plist_s = calloc(1, sizeof(*plist_s));
pntlist_s = calloc(1, sizeof(*pntlist_s));
plist = point_getplist(FIN, plist_s);
assert(plist != NULL);
pntlist = pnt_list(plist, *plist_s, pntlist_s);
assert(pntlist != NULL);
write_results(FOUT, parallel_count(pntlist, *pntlist_s));
return (0);
}