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.*;

//グラハムスキャン
//幾何
//凸包
class Main {

	Scanner sc = new Scanner(System.in);
	public void run() {
		while(sc.hasNext()){
			int n=sc.nextInt();
			if(n==0)break;
			P[] ps=new P[n];
			for(int i=0;i<n;i++){
				String[] str=sc.next().split(",");
				ps[i]=new P(Double.parseDouble(str[0]),Double.parseDouble(str[1]));
			}
			Arrays.sort(ps);

			int k=0;
			P[] qs =new P[2*n];
			//下側
			for(int i=0;i<n;i++){
				while(k>1 && P.cross(qs[k-1].s(qs[k-2]),ps[i].s(qs[k-1]))<=0)k--;//凸包になるまで戻す
				qs[k++]=ps[i];
			}
			//上側
			for(int i=n-2,t=k;i>=0;i--){
				while(k>t && P.cross(qs[k-1].s(qs[k-2]),ps[i].s(qs[k-1]))<=0)k--;
				qs[k++]=ps[i];
			}
			qs=Arrays.copyOf(qs,k-1);

			ln(ps.length-qs.length);
		}
	}
	public static void main(String[] args) {
		new Main().run();
	}
	public static void pr(Object o) {
		System.out.print(o);
	}
	public static void ln(Object o) {
		System.out.println(o);
	}
	public static void ln() {
		System.out.println();
	}
}

class P implements Comparable<P>{
	double x;
	double y;
	P(double _x,double _y){
		x=_x;
		y=_y;
	}
	@Override
	public int compareTo(P o) {
		if(this.x!=o.x){
			return (int)(this.x-o.x);
		}
		return (int)(this.y-o.y);
	}

	public static double dot(P a,P b){
			return a.x*b.x+a.y*b.y;
	}
	public static  double cross(P a,P b){
		return a.x*b.y-a.y*b.x;
	}
	public static boolean isParallel(P a1,P a2,P b1,P b2){
		return Math.abs(cross(a2.s(a1),b2.s(b1)))<Double.MIN_NORMAL;
	}
	public static boolean isVertical(P a1,P a2,P b1,P b2){
		return Math.abs(dot(a2.s(a1),b2.s(b1)))<Double.MIN_NORMAL;
	}

	public P a(P a){
		return new P(x+a.x,y+a.y);
	}
	public P s(P a){
		return new P(x-a.x,y-a.y);
	}

	public double norm(){
		return Math.sqrt(x*x+y*y);
	}

	public static int ccw(P a,P b,P c){
		if(P.cross(b.s(a),c.s(a))>Double.MIN_NORMAL){
			return 1;
		}
		if(P.cross(b.s(a),c.s(a))<-Double.MIN_NORMAL){
			return -1;
		}
		if(P.dot(b,c)<-Double.MIN_NORMAL)return 2;
		if(b.norm()<c.norm()-Double.MIN_NORMAL)return -2;
		return 0;
	}
	public String toString(){
		return "("+x+","+y+")";
	}
}