Problem:
シールの重なり

1 辺の長さが 10 の正方形の折り紙に半径 1 の円形のシールを n 枚貼ります。シールは重ねて貼ることができます。シールを貼る位置の座標を読み込んで、折り紙上でもっとも多くシールが重なっている場所(シールが１枚だけでも"重なっている"とする)でのシールの枚数を出力するプログラムを作成してください。

折り紙の左下を原点とした x, y 座標を与えます。この x, y を円の中心としてシールを貼ることとします。円の中心が折り紙の外に出ることはありません。また、同一座標に複数のシールが貼られることはありません。

Input

複数のデータセットが与えられます。各データセットは以下のような形式で与えられます。

n
x1,y1
x2,y2
:
xn,yn

１行目にシールの枚数 n (0 ≤ 100) が与えられます。続く n 行に、各シールの中心座標が与えられます。
xi, yi は i 枚目のシールの中心の x 座標と y 座標を表します。各値は小数点以下最大 6 桁までの数字を含む実数で与えられます。

n が 0 のとき、入力の最後とします。データセットの数は 50 を超えません。

Output

各データセットに対し、折り紙上で最も多くシールが重なっている場所でのシールの枚数（整数）を出力して下さい。

Sample Input

15
3.14979,8.51743
2.39506,3.84915
2.68432,5.39095
5.61904,9.16332
7.85653,4.75593
2.84021,5.41511
1.79500,8.59211
7.55389,8.17604
4.70665,4.66125
1.63470,4.42538
7.34959,4.61981
5.09003,8.11122
5.24373,1.30066
0.13517,1.83659
7.57313,1.58150
0

Output for the Sample Input

4

Hint

入力例のようにシールを貼った図です。円はシール、数字は入力例の行数を表しています。
点(2.3,4.6)では、入力例の 2 行目、3 行目、6 行目、10 行目の 4 枚のシールが重なっています。

6 と 9 のおのおのの中心の距離は 2.01293 なので、シールは重なっていません。1 と 12 のおのおのの中心の距離は 1.98231 なので、シールは重なっています。

２つの円が接しているとき（おのおのの中心の距離が 2 のとき）は、重なっているものとします。

Solution in C (judge verdict: Wrong Answer)


#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define MAX_INPUT 100
#define RADIUS 1e-10
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))

typedef struct {
    double x;
    double y;
} Point;

typedef struct {
    Point start;
    Point end;
} Vector;

Vector cross_point(Point p1, Point p2) {
    double distance = sqrt(pow(p2.x - p1.x, 2.0) + pow(p2.y - p1.y, 2.0));
    double theta = atan2(p2.x - p1.x, p2.y - p1.y);
    double alpha = acos(pow(distance, 2.0) / (2 * distance));
    Vector vec = {};
    vec.start.x = p1.x + cos(theta + alpha);
    vec.start.y = p1.y + sin(theta + alpha);
    vec.end.x = p1.x + cos(theta - alpha);
    vec.end.y = p1.y + sin(theta - alpha);
    return vec;
}

Point sub_point(Point p1, Point p2) {
    Point point = {};
    point.x = p1.x - p2.x;
    point.y = p1.y - p2.y;
    return point;
}

double cross(Point p1, Point p2) {
    return p1.x * p2.y - p1.y * p2.x;
}

/* bool is_cross(Vector v1, Vector v2) { */
/*     return (cross(sub_point(v1.end, v1.start), sub_point(v2.start, v1.start)) * */
/*             cross(sub_point(v1.end, v1.start), sub_point(v2.end, v1.start)) < RADIUS) && */
/*         (cross(sub_point(v2.end, v2.start), sub_point(v1.start, v2.start)) * */
/*          cross(sub_point(v2.end, v2.start), sub_point(v1.end, v2.start)) < RADIUS); */
/* } */

#define is_cross(v1, v2) \
    ((cross(sub_point(v1.end, v1.start), sub_point(v2.start, v1.start)) * \
      cross(sub_point(v1.end, v1.start), sub_point(v2.end, v1.start)) < RADIUS) && \
     (cross(sub_point(v2.end, v2.start), sub_point(v1.start, v2.start)) * \
      cross(sub_point(v2.end, v2.start), sub_point(v1.end, v2.start)) < RADIUS))

/* int count_overlaps(Point* points, int n) { */
/*     int i; */
/*     int j; */
/*     int x; */
/*     int y; */
/*     Vector vectors[MAX_INPUT][MAX_INPUT] = {}; */
/*     for (i = 0; i < n; i++) { */
/*         for (j = 0; j < n; j++) { */
/*             vectors[i][j] = cross_point(points[i], points[j]); */
/*         } */
/*     } */
/*     int max_counts = 1; */
/*     int counts; */
/*     for (i = 0; i < n; i++) { */
/*         for (j = 0; j < n; j++) { */
/*             for (x = 0; x < n; x++) { */
/*                 counts = 1; */
/*                 for (y = 0; y < n; y++) { */
/*                     if (is_cross(vectors[i][j], vectors[x][y])) { */
/*                         counts++; */
/*                     } */
/*                 } */
/*                 if (counts > max_counts) { */
/*                     max_counts = counts; */
/*                 } */
/*             } */
/*         } */
/*     } */
/*     return max_counts; */
/* } */

double calc_distance(Point p1, Point p2) {
    Point p = sub_point(p1, p2);
    return sqrt(pow(p.x, 2.0) + pow(p.y, 2.0)) - 1.0;
}

bool is_in_area(Point p1, Point p2) {
    if (calc_distance(p2, p1) <= RADIUS) {
        return true;
    } else {
        return false;
    }
}

int count_overlaps(Point* points, int n) {
    int i;
    int j;
    int x;
    Point cross_points[MAX_INPUT*MAX_INPUT*2] = {};
    int cross_len = 0;
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            if (i != j) {
                Vector res = cross_point(points[i], points[j]);
                double dist = calc_distance(res.end, res.start);
                if (dist == 2.0) {
                    cross_points[cross_len] = res.start;
                    cross_len++;
                } else if (dist < 2.0) {
                    cross_points[cross_len] = res.start;
                    cross_len++;
                    cross_points[cross_len] = res.end;
                    cross_len++;   
                }
            }
        }
    }
    int max_counts = 1;
    int counts;
    for (i = 0; i < cross_len; i++) {
        counts = 0;
        for (x = 0; x < n; x++) {
            if (is_in_area(cross_points[i], points[x])) {
                counts++;
            }
        }
        if (counts > max_counts) {
            max_counts = counts;
        }
    }
    return max_counts;
}

int main() {
    while (true) {
        int n;
        scanf("%d", &n);
        if (n == 0) {
            return 0;
        }
        Point points[MAX_INPUT] = {};
        int i;
        for (i = 0; i < n; i++) {
            scanf("%lf,%lf", &points[i].x, &points[i].y);
        }
        int count = count_overlaps(points, n);
        printf("%d\n", count);
    }
    return 0;
}