Problem:
輪ゴム

n 本の釘を平板上の座標 P1 (x1, y1), P2 (x2, y2), P3 (x3, y3),..., Pn (xn, yn) に１本ずつ打ち、輪ゴムの輪の中に全ての釘が入るように 1 本の輪ゴムで囲みます。このとき、輪ゴムが交差してはいけません。

釘の座標を読み込んで、上記のように釘を輪ゴムで囲んだときに輪ゴムに接していない釘の本数を出力するプログラムを作成してください。輪ゴムは充分に伸び縮みするものとします。同じ座標に 2 本以上の釘を打つことはないものとします。また、輪ゴムがかかった釘と釘の間は直線で結ばれるものとし、その直線上に 3 本以上の釘が並ぶことはないものとします。例えば、図 1 に示すような入力はありえません。図 2 に示すように輪ゴムがかかっていない釘が 1 直線上に並ぶことはありえます。

図１

図２

ただし、それぞれの座標値は -1000.0 以上1000.0 以下の実数です。また、n は 3 以上 100 以下の整数です。

Input

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

n
x1, y1
x2, y2
... 　　　　
...
xn, yn

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

Output

データセットごとに、ゴムと接していない釘の本数を出力してください。

例えば、図 3 に示す４つの釘を表す入力があった場合、図 4 のように囲まれるので、輪ゴムに接していない釘の本数は 1 本です。

図３

図４

Sample Input

4
1.0,0.0
0.0,1.0
2.0,1.0
1.0,2.0
9
-509.94,892.63
567.62,639.99
-859.32,-64.84
-445.99,383.69
667.54,430.49
551.12,828.21
-940.2,-877.2
-361.62,-970
-125.42,-178.48
0

Output for the Sample Input

0
3

Hint

以下は２つめのサンプル入力に対する図です。

Solution in JAVA (judge verdict: Wrong Answer)


import java.util.*;
import java.io.*;

import static java.util.Arrays.*;
import static java.util.Collections.*;
import static java.lang.Math.*;

public class Main {

	int INF = 1 << 28;
	//long INF = 1L << 62;
	double EPS = 1e-10;

	void run() {
		Scanner sc = new Scanner(System.in);
		for(;;) {
			int n = sc.nextInt();
			if(n == 0) break;
			
			P[] ps = new P[n];
			for(int i=0;i<n;i++) {
				String[] sp = sc.next().split(",");
				ps[i] = new P(Double.parseDouble(sp[0]), Double.parseDouble(sp[1]));
			}
			
			P[] poly = poly(ps);
			System.out.println( n - poly.length );
		}
	}
	
	P[] poly(P[] ps) {
		int n = ps.length, k=0;
		if(n <= 1) return ps;
		sort(ps, new Comp(ps[0]));
		P[] qs = new P[n*2];
		
		for(int i=0;i<n;qs[k++] = ps[i++]) {
			while(k > 1 && qs[k-1].sub(qs[k-2]).det(ps[i].sub(qs[k-1])) < EPS) k--;
		}
		for(int i=n-2,t=k;i>=0;qs[k++] = ps[i--]) {
			while(k > t && qs[k-1].sub(qs[k-2]).det(ps[i].sub(qs[k-1])) < EPS) k--;
		}
		P[] res = new P[k-1];
		System.arraycopy(qs, 0, res, 0, k-1);
		return res;
	}
	
	boolean contains(P[] ps, P p) {
		int n = ps.length;
		int res = -1;
		for(int j=0;j<n;j++) {
			P a = ps[j].sub(p);
			P b = ps[(j+1)%n].sub(p);
			if(a.y > b.y) {
				P t = new P(a.x, a.y); a = b; b = t; 
			}
			if(a.y < EPS &&  b.y > EPS && a.det(b) > EPS) {
				res = -res;
			}
			if(abs(a.det(b)) < EPS && a.dot(b) < EPS) {
				return true;
			}
		}
		return res == -1? false: true;
	}
	class Comp implements Comparator<P> {
		P p;
		Comp(P p) {
			this.p = new P(p.x, p.y);
		}

		public int compare(P o1, P o2) {
			// TODO 自動生成されたメソッド・スタブ
			return (p.det(p.sub(o1)) > p.det(p.sub(o2))? 1: -1);
		}
		
	}
	class P {
		double EPS = 1e-8;
		double x, y;
		P(double x, double y) {
			this.x = x;
			this.y = y;
		}

		double add(double a, double b) {	//誤差を考慮
			if( Math.abs(a+b) < EPS * ( Math.abs(a) + Math.abs(b) ) ) return 0;
			return a + b;
		}

		P add(P p) {	//和
			return new P(x+p.x, y+p.y);
		}

		P sub(P p) {	//差
			return new P(x-p.x, y-p.y);
		}
		
		P mlt(double k) {
			return new P(x*k, y*k);
		}

		double dot(P p) {	//内積
				return add(x*p.x, y*p.y);
		}

		double det(P p) {	//外積
			return add(x*p.y, -y*p.x);
		}

		//距離系
		double abs() {
			double ret = sqrt( add(x*x, y*y) );
			if ( Math.abs(ret) < EPS ) return 0;
			return ret;
		}

		double abs(P p) {
			double dx = add( x, -p.x );
			double dy = add( y, -p.y );
			double ret = sqrt( add(dx*dx, dy*dy) );
			if( Math.abs(ret) < EPS ) return 0;
			return ret;
		}

		//点と線分の距離
		double disSP(P p1, P p2, P q) {
			if( p2.sub(p1).dot(q.sub(p1)) < EPS ) return q.sub(p1).abs();
			if( p1.sub(p2).dot(q.sub(p2)) < EPS ) return q.sub(p2).abs();
			return disLP(p1, p2, q);
		}

		//点と直線の距離
		double disLP(P p1, P p2, P q) {
			return Math.abs(p2.sub(p1).det(q.sub(p1))) / p2.sub(p1).abs();
		}

		//線分交差判定
		boolean cross(P p1, P p2, P q1, P q2) {
			return ccw(p1, p2, q1) * ccw(p1, p2, q2) <= 0 &&
				ccw(q1, q2, p1) * ccw(q1, q2, p2) <= 0;
		}

		//時計回りなのか．反時計回りなのか，直線状なのか，とにかく位置関係をみる
		int ccw (P a, P b, P c) {
			P s = b.sub(a);
			P t = c.sub(a);
			if( s.det(t) > EPS ) return 1;
			if( s.det(t) < -EPS ) return -1;
			if( s.dot(t) < -EPS ) return 2;
			if( s.dot(s) + EPS < t.dot(t) ) return -2;
			return 0;
		}
	}

	void debug(Object... os) {
		System.err.println(Arrays.deepToString(os));
	}

	public static void main(String[] args) {
		new Main().run();
	}
}