Go: package main
// 三角形の形は辺の長さで決まる． 順番に３つの正整数が与えられたとき， 辺の長さがそれらの値と一致する三角形が存在するかどうかを調べ,
//  存在するなら鋭角三角形，直角三角形，鈍角三角形のいずれかを判定し， 次の入力へ進む． 三角形が存在しないとき， それまでに入力された，
// 三角形，直角三角形，鋭角三角形，鈍角三角形の 個数を空白で区切って出力し， それ以降の入力は無視して終了する
// 入力の中には必ず三角形が存在しないようなものがある と仮定してよい. 入力の行数は判らないが各行には３つの正整数が空白で区切って書かれている．
//  ただし，各整数は100 以下とする.

// return
// 三角形 直角三角形　鈍角三角形 鈍角三角形
import (
	"os"
	"fmt"
	"bufio"
)


var sc = bufio.NewScanner(os.Stdin)

func max(a, b, c int) (int, int, int) {
	if a > b {
		if b > c {
			return a, b, c
		} else {
			return a, c, b
		}
	} else {
		if b > c {
			return b, a, c
		} else {
			return c, b, a
		}
	}
}

func find_trianges(a, b, c int) string {
	a, b, c = max(a, b, c)
	r := b*b + c*c
	if a*a > r {
		return "obtuse_triangle"
	} else if a*a < r {
		return "sharped_triangle"
	} else {
		return "right_triangle"
	}
}

func main() {
	s := bufio.NewScanner(os.Stdin)
	var t, r_t, s_t, o_t int = 0, 0, 0, 0
	for s.Scan() {
		var a, b, c int
		fmt.Sscan(s.Text(), &a, &b, &c)
			a, b, c = max(a, b, c)
			if (a < b + c) {
				r := find_trianges(a, b, c)
				switch r {
				case "right_triangle":
					r_t++
				case "sharped_triangle":
					s_t++
				case "obtuse_triangle":
					o_t++
				}
				t++
			}	else {
				break
			}
			
	}
	fmt.Println(t, r_t, s_t, o_t)
}

C++: #include <iostream>
#include <cstdio>
#include <vector>
#include <list>
#include <cmath>
#include <fstream>
#include <algorithm>
#include <string>
#include <queue>
#include <set>
#include <map>
#include <complex>
#include <iterator>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <stack>
#include <climits>
#include <deque>
#include <bitset>
#include <cassert>
#include <ctime>
using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
const int dy[]={-1,0,1,0},dx[]={0,1,0,-1};
// adjust problem by problem
const double EPS=1e-8;
const double PI=acos(-1.0);
#ifdef __GNUC__
int popcount(int n){return __builtin_popcount(n);}
int popcount(ll n){return __builtin_popcountll(n);}
#endif
#ifndef __GNUC__
template<class T> int popcount(T n){int cnt=0;while(n){if(n%2)cnt++;n/=2;}return cnt;}
#endif
template<class T>int SIZE(T a){return a.size();}
template<class T>string IntToString(T num){string res;stringstream ss;ss<<num;return ss.str();}
template<class T>T StringToInt(string str){T res=0;for(int i=0;i<SIZE(str);i++)res=(res*10+str[i]-'0');return res;}
template<class T>T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template<class T>T lcm(T a,T b){return a/gcd(a,b)*b;}
template<class T> void PrintSeq(T &a,int sz){for(int i=0;i<sz;i++){cout<<a[i];if(sz==i+1)cout<<endl;else cout<<' ';}}
bool EQ(double a,double b){return abs(a-b)<EPS;}
void fastStream(){cin.tie(0);std::ios_base::sync_with_stdio(0);}
vector<string> split(string str,char del){
  vector<string> res;
  for(int i=0,s=0;i<SIZE(str);i++){
    if(str[i]==del){if(i-s!=0)res.push_back(str.substr(s,i-s));s=i+1;}
    else if(i==SIZE(str)-1){res.push_back(str.substr(s));}
  }
  return res;
}

int main(){

  int x,y,z;
  int tri=0;
  int t=0;
  int e=0;
  int d=0;
  while(cin>>x>>y>>z){
    vector<int> v;
    v.push_back(x);
    v.push_back(y);
    v.push_back(z);
    sort(v.begin(),v.end());
    if(v[0]+v[1]<=v[2])break;
    else{
      tri++;
      if(v[0]*v[0]+v[1]*v[1]==v[2]*v[2])t++;
      else if(v[0]*v[0]+v[1]*v[1]>v[2]*v[2])e++;
      else d++;
    }
  }
  cout<<tri<<" "<<t<<" "<<e<<" "<<d<<endl;
  
  return 0;
}

C++: #input_f = "3 4 5\n2 1 2\n6 3 4\n1 1 1\n1 2 3"
def t_check(a,b,c):
    if a + b > c:
        if b + c > a:
            if a + c > b: return True
    return False



def f_check(a_, b_, c_):
    tmp = []
    tmp.append(a_)
    tmp.append(b_)
    tmp.append(c_)
    sqrts = []
    for i in range(3):
        sqrts.append(tmp[i]**2)
    m = max(sqrts)
    s = sum(sqrts)

    if m == (s - m): return(0)
    if m > (s - m): return(2)
    if m < (s - m): return(1)
    
    
counter=[0,0,0]
    
    
while(1):
    input_f = input()


    t = input_f.split("\n")[i].split()
    fn, sn, tn = int(t[0]),int(t[1]),int(t[2])
    if t_check(fn,sn,tn):
        counter[f_check(fn,sn,tn)] += 1
    else: break
    

print(sum(counter),counter[0], counter[1], counter[2])

C++: #include<iostream>
using namespace std;
int main()
{
  int ans[4]={0,0,0,0};
  int a,b,c;
  for(;cin>>a>>b>>c;)
    {
      if(a+b<=c||c+b<=a||a+c<=b)
	break;
      ans[0]++;
      if(c<a)
	swap(a,c);
      if(c<b)
	swap(b,c);
      if(a*a+b*b==c*c)
	ans[1]++;
      else if(a*a+b*b>c*c)
	ans[2]++;
      else if(a*a+b*b<c*c)
	ans[3]++;
    }
  cout<<ans[0]<<" "<<ans[1]<<" "<<ans[2]<<" "<<ans[3]<<endl;
}

C++: #include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;

int main() {
  vector<int> edge;
  int rgt_num, act_num, obt_num;

  rgt_num= 0;
  act_num= 0;
  obt_num= 0;
  while(1) {
    for(int i = 0; i < 3; i++) {
      int E;
      cin >> E;
      edge.push_back(E);
    }

    sort(edge.begin(), edge.end(), greater<int>());

    int a = edge[0];
    int b = edge[1];
    int c = edge[2];

    if(a >= b + c)
      break;
    else if(pow(a, 2) == pow(b, 2) + pow(c, 2))
      rgt_num++;
    else if(pow(a, 2) < pow(b, 2) + pow(c, 2))
      act_num++;
    else
      obt_num++;
    edge.clear();
  }
  cout << rgt_num + act_num + obt_num << ' ' <<  rgt_num
       << ' ' << act_num << ' ' << obt_num << endl;
}

C++: #include <iostream>
#include <algorithm>
#include <string>

using namespace std;

int main(){
  int a[3];
  int x,y;
  int san=0,tyoku=0,ei=0,don=0;

  while(1){
    cin>>a[0]>>a[1]>>a[2];
    sort(a,a+3);
    x=a[0]*a[0]+a[1]*a[1];
    y=a[2]*a[2];

    if(a[0]+a[1] <= a[2])
      break;
    else if (x == y)
      tyoku++;
    else if(x > y)
      ei++;
    else if (x < y)
      don++;
  }

  san=tyoku+ei+don;
  cout<<san<<" "<<tyoku<<" "<<ei<<" "<<don<<endl;

  return 0;
}

C++: #include <iostream>
using namespace std;

typedef unsigned int U4;
#define TRUE 1
#define FALSE 0

#define ACUTE_TRIANGLE 0
#define RIGHT_TRIANGLE 1
#define OBTUSE_TRIANGLE 2

U4 TrinagleNum = 0;
U4 AcuteTriangleNum = 0;
U4 RightTriangleNum = 0;
U4 ObtuseTriangleNum = 0;

U4 U4_TriangleCheck(U4,U4,U4);
U4 U4_TypeCheck(U4,U4,U4);
void V_LengthSort(U4*,U4*,U4*);
int main(void){

U4 a;
U4 b;
U4 c;

  while(1){
    cin >> a >> b >> c;
    if(U4_TriangleCheck(a,b,c) == TRUE){
      TrinagleNum++;
      if(U4_TypeCheck(a,b,c) == ACUTE_TRIANGLE){
        AcuteTriangleNum++;
      }else if(U4_TypeCheck(a,b,c) == OBTUSE_TRIANGLE){
        ObtuseTriangleNum++;
      }else{
        RightTriangleNum++;
      }
    }else{
      break;
    }
  }

  cout << TrinagleNum << " " << RightTriangleNum << " " << AcuteTriangleNum << " " << ObtuseTriangleNum << endl;
}

U4 U4_TriangleCheck(U4 a,U4 b,U4 c){
  if((a + b > c) && (b + c > a) && (c + a > b)){
    return TRUE;
  }else{
    return FALSE;
  }
}

U4 U4_TypeCheck(U4 a,U4 b,U4 c){
  U4 LongLength;
  U4 MiddleLength;
  U4 ShortLength;
  U4 LongLengthSquare;
  U4 MiddleLengthSquare;
  U4 ShortLengthSquare;

  LongLength   = a;
  MiddleLength = b;
  ShortLength  = c;

  V_LengthSort(&LongLength,&MiddleLength,&ShortLength);

  LongLengthSquare   = LongLength * LongLength;
  MiddleLengthSquare = MiddleLength * MiddleLength;
  ShortLengthSquare  = ShortLength * ShortLength;

  if(MiddleLengthSquare + ShortLengthSquare > LongLengthSquare){
    return ACUTE_TRIANGLE;
  }else if(MiddleLengthSquare + ShortLengthSquare < LongLengthSquare){
    return OBTUSE_TRIANGLE;
  }else{
    return RIGHT_TRIANGLE;
  }
}

void V_LengthSort(U4* Long,U4 *Middle,U4 *Short){
  U4 buff;

  if((*Long >= *Middle) && (*Long >= *Short)){
    // Do Nothing
  }else if(*Middle >= *Short){
    buff = *Long;
    *Long = *Middle;
    *Middle = buff;
  }else{
    buff = *Long;
    *Long = *Short;
    *Short = buff;
  }
}