Problem:
宇宙船 UAZ アドバンス号

恒星歴 2005.11.5。あなたは宇宙船 UAZ アドバンス号の艦長として敵の宇宙船と交戦しようとしています。 幸い敵の宇宙船はまだこちらに気付かずに静止しています。また、すでに敵の宇宙座標は判明しており強力な直線のビームを放つ「フェザー砲」は発射準備を完了しています。あとは、発射命令を出すばかりです。

ところが、宇宙空間には、敵の設置したエネルギーバリアが存在しています。バリアは三角形をしており「フェザー砲」のビームをはね返してしまいます。また、ビームがバリアに当たれば敵に気付かれて逃げられてしまいます。事前に命中すると判定できなければ、発射命令は出せません。

そこで、UAZ アドバンス号、敵、バリアの位置の宇宙座標(3次元座標 x, y, z) を入力して、ビームがバリアをさけて敵に命中する場合は "HIT"、バリアに当たってしまう場合"MISS"と出力するプログラムを作成してください。

ただし、バリアはアドバンス号から 3 角形に見えるものだけが対象であり、線分につぶれて見えるものはないものとします。また、バリアは 3 角形の頂点を含む境界でも有効であり、ビームをはね返すものとします。また、敵がバリア内にいる場合は"MISS"と出力して下さい。

Input

入力データの形式は以下のとおりです：

1 行目は、UAZ アドバンス号の座標 (x, y, z) (整数、半角空白区切り)

2 行目は、敵の座標 (x, y, z) (整数、半角空白区切り)

3 行目は、バリアの頂点 1 の座標 (x, y, z) (整数、半角空白区切り)

4 行目は、バリアの頂点 2 の座標 (x, y, z ) (整数、半角空白区切り)

5 行目は、バリアの頂点 3 の座標 (x, y, z ) (整数、半角空白区切り)

Output

HIT または MISS と１行に出力してください。

Constraints

-100 ≤ x, y, z ≤ 100

UAZ アドバンス号と敵が同じ位置にいることはない。

Sample Input 1

-10 0 0
10 0 0
0 10 0
0 10 10
0 0 10

Output for the Sample Input 1

HIT

Sample Input 2

-10 6 6
10 6 6
0 10 0
0 10 10
0 0 10

Output for the Sample Input 2

MISS

Solution in C# (judge verdict: Accepted)

using System;
using System.Collections;
using System.Collections.Generic;
 
class TEST{
	static void Main(){
		Sol mySol =new Sol();
		mySol.Solve();
	}
}

class Sol{

	public void Solve(){
		
		LinearAlg LA=new LinearAlg();
		
		double[][] A=new double[4][];
		for(int i=0;i<4;i++){
			A[i]=new double[4];
		} 
		
		double[] V=new double[4];
		
		//
		//	X=sP+tQ*uR;
		//	s+t+u=1;
		//	X=rS
		//
		
		A[0][0]=1.0;			A[0][1]=1.0;			A[0][2]=1.0;			A[0][3]=0.0;			V[0]=1.0;
		A[1][0]=Barrier[0][0]-UAZ[0];	A[1][1]=Barrier[1][0]-UAZ[0];	A[1][2]=Barrier[2][0]-UAZ[0];	A[1][3]=-(Enemy[0]-UAZ[0]);	V[1]=0.0;
		A[2][0]=Barrier[0][1]-UAZ[1];	A[2][1]=Barrier[1][1]-UAZ[1];	A[2][2]=Barrier[2][1]-UAZ[1];	A[2][3]=-(Enemy[1]-UAZ[1]);	V[2]=0.0;
		A[3][0]=Barrier[0][2]-UAZ[2];	A[3][1]=Barrier[1][2]-UAZ[2];	A[3][2]=Barrier[2][2]-UAZ[2];	A[3][3]=-(Enemy[2]-UAZ[2]);	V[3]=0.0;
/*
for(int ii=0;ii<4;ii++){
	for(int jj=0;jj<4;jj++){Console.Write("{0}\t",A[ii][jj]);}
	Console.WriteLine("{0}",V[ii]);
}
Console.WriteLine("");
*/
		double[] sol=LA.GaussElimination(A,V);
		
		
		bool chk=true;
		if(sol==null){
			chk=true;
		} else if(sol[0]>=0.0-EPS && sol[0]<=1.0+EPS &&sol[1]>=0.0-EPS && sol[1]<=1.0+EPS &&sol[2]>=0.0-EPS && sol[2]<=1.0+EPS && sol[3]<=1.0+EPS && sol[3]>=0.0-EPS){
			chk=false;
		}
		
		Console.WriteLine(chk?"HIT":"MISS");
	}
	
	
	
	
	double[][] Barrier;
	double[] Enemy;
	double[] UAZ;
	double EPS;
	
	public Sol(){
		UAZ=rda();
		Enemy=rda();
		Barrier=new double[3][];
		for(int i=0;i<3;i++)Barrier[i]=rda();
		EPS=1e-9;
	}




	static String rs(){return Console.ReadLine();}
	static int ri(){return int.Parse(Console.ReadLine());}
	static long rl(){return long.Parse(Console.ReadLine());}
	static double rd(){return double.Parse(Console.ReadLine());}
	static String[] rsa(){return Console.ReadLine().Split(' ');}
	static int[] ria(){return Array.ConvertAll(Console.ReadLine().Split(' '),e=>int.Parse(e));}
	static long[] rla(){return Array.ConvertAll(Console.ReadLine().Split(' '),e=>long.Parse(e));}
	static double[] rda(){return Array.ConvertAll(Console.ReadLine().Split(' '),e=>double.Parse(e));}
}


class LinearAlg{
	
	public double[] GaussElimination(double[][] A,double[] V){
		//  solving  Ax = V in double
		if(A.Length!=A[0].Length)return null;
		if(A.Length!=V.Length)return null;
		int N=A.Length;
		
		double[][] L=new double[N][];
		for(int i=0;i<N;i++){
			L[i]=new double[N+1];
			for(int j=0;j<N;j++)L[i][j]=A[i][j];
			L[i][N]=V[i];
		}

		for(int i=0;i<N;i++){
			int pibot=i;
			double buf=Math.Abs(L[i][i]);
			for(int j=i+1;j<N;j++){
				if(Math.Abs(L[j][i])>buf){
					pibot=j;
					buf=Math.Abs(L[j][i]);
				}
			}
			
			if(L[pibot][i]==0)return null;
			swap(ref L[i],ref L[pibot]);

			double d=L[i][i];
			for(int j=0;j<=N;j++){L[i][j]/=d;}
			
			for(int j=i+1;j<N;j++){
				d=L[j][i];
				for(int k=0;k<=N;k++){
					L[j][k]-=L[i][k]*d;
				}
			}

		}
				
		for(int i=N-1;i>=0;i--){
			for(int j=i-1;j>=0;j--){
				double d=L[j][i];
				for(int k=0;k<=N;k++){
					L[j][k]-=L[i][k]*d;
				}
			}
		}


		double[] Ret=new double[N];
		for(int i=0;i<N;i++)Ret[i]=L[i][N];
		return Ret;
		
	}
	
	void swap(ref double[] A,ref double[] B){
		double[] C;
		C=A;A=B;B=C;
	}
}