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 a > c {
			return b, a, c
		} else {
			return b, c, 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":
					r_t++
				}
				t++
			}	else {
				break
			}
			
	}
	fmt.Println(t, r_t, s_t, o_t)
}

C++: 
#include "bits/stdc++.h"
//#include <iostream>
//#include <vector>
//#include <string>
using namespace std;
#define repi(i,a,b) for(int i=(a), i##_len=(b); i<i##_len; ++i)
#define rep(i,n) repi(i,0,n)
#define repi_(i,a,b) for(int i=(a), i##_len=(b); i<=i##_len; ++i)
#define rep_(i,n) repi_(i,0,n)
#define all(x) (x).begin(),(x).end()
#define vsort(v) sort((v).begin(), (v).end())
#define gsort(v) tsort(v); reverse((v).begin(), (v).end())
#define vrev(v) reverse((v).begin(), (v).end())
#define siz(v) ((int)(v).size())
#define ers(v, n) (v).erase((v).begin() + n)
#define cnt(v, n) count(all(v), n)
#define vmin(v) *min_element(v.begin(), v.end())
#define vmax(v) *max_element(v.begin(), v.end())
#define el "\n"
#define sp " "
#define co(x) cout<<(x)<<el
#define coc(c, a, b) if(c)co((a));else co((b))
#define cosp(x) cout<<(x)<<' '
#define YES(c) coc(c,"YES", "NO")
#define Yes(c) coc(c,"Yes", "No")
#define yes(c) coc(c,"yes", "no")
#define POSSIBLE(c) coc(c, "POSSIBLE", "IMPOSSIBLE")
#define Possible(c) coc(c, "Possible", "Impossible")
#define possible(c) coc(c, "possible", "impossible")
#define inf INT_MAX
#ifdef tqktmp_2
#define gc() getchar(); getchar()
#else
#define gc() 1
#endif
const unsigned int bf0 = (1 << 0);
const unsigned int bf1 = (1 << 1);
const unsigned int bf2 = (1 << 2);
const unsigned int bf3 = (1 << 3);
const unsigned int bf4 = (1 << 4);
const unsigned int bf5 = (1 << 5);
const unsigned int bf6 = (1 << 6);
const unsigned int bf7 = (1 << 7);

typedef long long lint;
typedef vector<int> ivec; typedef vector<string> svec;

const int
	dx8[8] = { 0,1,1,1,0,-1,-1,-1 },
	dy8[8] = { 1,1,0,-1,-1,-1,0,1 },
	dx4[4] = { 0,1,0,-1 },
	dy4[4] = { 1,0,-1,0 };

template<class T>inline bool maxi(T &a, const T &b) { if (a<b) { a = b; return 1; } return 0; }
template<class T>inline bool mini(T &a, const T &b) { if (b<a) { a = b; return 1; } return 0; }




int main() {
	cin.tie(0);
	ios::sync_with_stdio(0);

	ivec l(3);
	lint ctr[4] = {};
	while (cin >> l[0] >> l[1] >> l[2]) {
		vsort(l);
		if (l[0] + l[1] <= l[2]) {
			cout << ctr[0] << sp << ctr[1] << sp << ctr[2] << sp << ctr[3] << el;
			gc();
			return 0;
		}
		if (l[0] * l[0] + l[1] * l[1] == l[2] * l[2])++ctr[1];
		else if (l[0] * l[0] + l[1] * l[1] > l[2] * l[2])++ctr[2];
		else ++ctr[3];
		++ctr[0];
	}
	gc();
}

C++: #include<iostream>
using namespace std;
int main(){
	int i,x,y ,z,a,b,c,ch=0,ei=0,d=0;

	for(i=0;i<100;i++)
	{
		cin>>x>>y>>z;

		if(x>=y && y>=z) 
		{
			a=x;
			b=y;
			c=z;
		}
		else if(y>=x  && x>=z)
		{
			a=y;
			b=x;
			c=z;
		}
		else //(z>=x && x>=y)
		{
			a=z;
			b=y;
			c=x;
		}

		if(b+c<=a)
		{
			break;
		}  

		a = a*a;
		b = b*b;
		c = c*c;

		if (a-(b+c)<0)
		{
			ei+=1;
		}

		if (a-(b+c)>0)
		{
			d+=1;
		}

		if(a == b+c)
		{
			ch+=1;
		}

		
	}

	cout<<ch+d+ei<<" "<<ch<<" "<<ei<<" "<<d<<endl;



	return 0;
}

C++: #include<iostream>
#include<algorithm>
#define rep(num,num2) for(int num=0;num<num2;num++)
using namespace std;
int main()
{
    int t=0,r=0,n=0,p=0;
    while(true)
    {
        int a[3];
        rep(i,3)cin>>a[i];
        sort(a,a+3);
        if(a[1]+a[0]<=a[2])break;
        if(a[2]*a[2]==a[1]*a[1]+a[0]*a[0]){
            t++;r++;
        }
        if(a[2]*a[2]>a[1]*a[1]+a[0]*a[0]){
            t++;p++;
        }
        if(a[2]*a[2]<a[1]*a[1]+a[0]*a[0]){
            t++;n++;
        }
    }
    cout<<t<<" "<<r<<" "<<n<<" "<<p<<endl;
}

C++: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
template<class T>
using Table = vector<vector<T>>;
const ld eps=1e-9;

//// < "D:\D_Download\Visual Studio 2015\Projects\programing_contest_c++\Debug\a.txt" > "D:\D_Download\Visual Studio 2015\Projects\programing_contest_c++\Debug\b.answer"
int main() {
	vector<int>nums(4);
	while (1) {
		vector<int>vs(3);
		cin >> vs[0] >> vs[1] >> vs[2];
		sort(vs.begin(), vs.end());
		if (vs[0] + vs[1] <= vs[2]) {
			break;
		}
		else {
			int l = vs[0] * vs[0] + vs[1] * vs[1];
			int r = vs[2] * vs[2];
			if (l < r) {
				nums[3]++;
			}
			else if (l == r) {
				nums[1]++;
			}
			else {
				nums[2]++;
			}
			nums[0]++;
		}

	}
	cout << nums[0] << " " << nums[1] << " " << nums[2] << " " << nums[3] << endl;
	return 0;
}

C++: #include <iostream>
#include <complex>
#include <sstream>
#include <string>
#include <algorithm>
#include <deque>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <vector>
#include <set>
#include <limits>
#include <cstdio>
#include <cctype>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <ctime>
using namespace std;
#define REP(i, j) for(int i = 0; i < (int)(j); ++i)
#define FOR(i, j, k) for(int i = (int)(j); i < (int)(k); ++i)
#define SORT(v) sort((v).begin(), (v).end())
#define REVERSE(v) reverse((v).begin(), (v).end())
const double EPS = 1e-8;
#define EQ(a,b) (abs((a)-(b)) < EPS)
typedef complex<double> P;


int solve(vector<int> &v, vector<int> &cnt){
    SORT(v);
    if(v[0] + v[1] <= v[2]) return -1;
    if(v[0] * v[0] + v[1] * v[1] > v[2] * v[2]) return 1;
    if(v[0] * v[0] + v[1] * v[1] < v[2] * v[2]) return 2;
    return 0;
}

int main() {
  vector<int> v(3), cnt(3, 0);
  for(int i = 0; cin >>v[0] >>v[1] >>v[2]; ++i){
    int r = solve(v, cnt);
    if(r == -1){
      cout <<i;
      REP(i, 3) cout <<" " <<cnt[i];
      cout <<endl;
      break;
    }
    ++cnt[r];
  }
  return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define all(v) v.begin(), v.end()

void print_vec(vector<int> vec)
{
  cout << "[";
  for (int i = 0; i < vec.size(); i++)
  {
    cout << vec.at(i);
    if (i < vec.size() - 1)
    {
      cout << ", ";
    }
  }
  cout << "]...size: " << vec.size() << endl;
}

int main()
{
  map<string, int> hash;
  hash["right"] = 0;
  hash["acute"] = 0;
  hash["obtuse"] = 0;

  bool judge = true;
  while (judge)
  {
    int a, b, c;
    cin >> a >> b >> c;

    if (a + b <= c || b + c <= a || c + a <= b)
    {
      judge = false;
    }
    else
    {
      vector<int> vec(3);
      vec.at(0) = a * a;
      vec.at(1) = b * b;
      vec.at(2) = c * c;
      sort(all(vec));
      int x = vec.at(0);
      int y = vec.at(1);
      int z = vec.at(2);
      if (z == x + y)
      {
        hash.at("right") += 1;
      }
      else if (z < x + y)
      {
        hash.at("acute") += 1;
      }
      else
      {
        hash.at("obtuse") += 1;
      }
    }
  }

  printf("%d %d %d %d\n", hash["right"] + hash["acute"] + hash["obtuse"], hash["right"], hash["acute"], hash["obtuse"]);
}