Go: package main

import (
	"fmt"
	"sort"
)

// TriangleKind kind of triangle
type TriangleKind int

const (
	// Nothing not triangle
	Nothing TriangleKind = iota
	// RightTriangle the right triangle
	RightTriangle
	// SharpTriangle the sharp triangle
	SharpTriangle
	// ObtuseTriangle the obtuse triangle
	ObtuseTriangle
) // const for Triangle kind

type result struct {
	rTriangle int
	sTriangle int
	oTriangle int
}

func (res *result) String() string {
	return fmt.Sprintf("%d %d %d %d", res.rTriangle+res.sTriangle+res.oTriangle, res.rTriangle, res.sTriangle, res.oTriangle)
}

func checkTriangleType(a int, b int, c int) TriangleKind {
	p := []int{a, b, c}
	sort.Sort(sort.IntSlice(p))
	if !(p[0]+p[1] > p[2] && p[1]+p[2] > p[0] && p[2]+p[0] > p[1]) {
		return Nothing
	}

	c = (p[0] * p[0]) + (p[1] * p[1]) - (p[2] * p[2])
	if c == 0 {
		return RightTriangle
	}
	if c > 0 {
		return SharpTriangle
	}
	return ObtuseTriangle
}

func main() {
	var res = new(result)
	var a, b, c int
	var hasNext = true
	for hasNext {
		fmt.Scanf("%d %d %d", &a, &b, &c)
		switch checkTriangleType(a, b, c) {
		case Nothing:
			hasNext = false
		case RightTriangle:
			res.rTriangle++
		case SharpTriangle:
			res.sTriangle++
		case ObtuseTriangle:
			res.oTriangle++
		}
	}
	fmt.Println(res.String())
}

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[2]++;
			}
			else {
				nums[1]++;
			}
			nums[0]++;
		}

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

C++: #include <iostream>
#include <algorithm>
using namespace std;
int main() {
	int k[5], sha = 0, ninety = 0, more = 0;
	bool triangle = true;
	while (triangle) {
		cin >> k[0] >> k[1] >> k[2];
		sort(k, k + 3);
		if (k[0] + k[1] <= k[2]) {
			cout << sha + ninety + more << " " << ninety << " " << sha << " " << more;
			triangle = false;
		}
		else {
			if (k[2] * k[2] == k[0] * k[0] + k[1] * k[1]) ninety++;
			else if (k[2] * k[2] < k[0] * k[0] + k[1] + k[1]) sha++;
			else more++;
		}
	}
	cout << endl;
}

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

using namespace std;

#define rep(i, n) for (int i = 0; i < int(n); ++i)

int main() {
  int r[3] = {};
  while (true) {
    int a[3];
    rep (i, 3) cin >> a[i];
    sort(a, a + 3);
    if (a[0] + a[1] <= a[2]) break;
    if (a[0] * a[0] + a[1] * a[1] == a[2] * a[2]) ++r[0];
    if (a[0] * a[0] + a[1] * a[1] >  a[2] * a[2]) ++r[1];
    if (a[0] * a[0] + a[1] * a[1] <  a[2] * a[2]) ++r[2];
  }
  cout << r[0] + r[1] + r[2];
  rep (i, 3) cout << " " << r[i];
  cout << endl;
  return 0;
}

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

#define Avec vec[0] >> vec[1] >> vec[2]
#define Lrule pow(vec[0], 2) + pow(vec[1], 2)
#define Rrule pow(vec[2], 2)

int main() {
	int tri = 0; int rig = 0;
	int acu = 0; int obt = 0;
	vector<int> vec(3);
	while (cin >> Avec) {
		sort(vec.begin(), vec.end());
		if (vec[0] + vec[1] > vec[2]) {
			tri++;
			if (Lrule == Rrule) rig++;
			else if (Lrule > Rrule) acu++;
			else if (Lrule < Rrule) obt++;
		}
		else break;
	}
	cout << tri << " " << rig << " " << acu << " " << obt << endl;
	return 0;
}

C++: #include<iostream>
#include<string>
#include<algorithm>
 
using namespace std;
 
int main()
{
	int tris = 0;
	int right_tris = 0;
	int acute_tris = 0;
	int obtuse_tris = 0;
	for( int i = 0; i < 100; i ++)
	{
		int a, b, c;
		if( !(cin >> a) )
		{
			break;
		}

		cin >> b >> c;


		if( (a + b > c) && (b + c > a) && (c + a > b) )
		{
			tris ++;

			bool is_acute = false;
			int d = b * b + c * c;
			int aa = a * a;

			if( d == aa )
			{
				right_tris ++;
				continue;
			}
			else if ( d > aa )
			{
				is_acute = true;
			}
			else
			{
				obtuse_tris ++;
				continue;
			}
			d = c * c + a * a;
			aa = b * b;

			if( d == aa )
			{
				right_tris ++;
				continue;
			}
			else if ( d > aa )
			{
				is_acute = true;
			}
			else
			{
				obtuse_tris ++;
				continue;
			}
			d = a * a + b * b;
			aa = c * c;

			if( d == aa )
			{
				right_tris ++;
				continue;
			}
			else if ( d > aa )
			{
				is_acute = true;
			}
			else
			{
				obtuse_tris ++;
				continue;
			}
			if( is_acute )
			{
				acute_tris++;
			}
		}
		else
		{
			break;
		}
	}

	cout << tris << " " << right_tris << " " << acute_tris << " " << obtuse_tris << endl;
	return 0;
}

C++: #include <bits/stdc++.h>
#define r(i,n) for(i=0;i<n;i++)
using namespace std;
int main(){
  int a[3],b[3]={0},s=0;
  while(cin>>a[0]>>a[1]>>a[2]){
    sort(a,a+3);
    if(a[0]+a[1]<=a[2])break;
    s++;
    if(a[2]*a[2]==a[0]*a[0]+a[1]*a[1])b[0]++;
    if(a[2]*a[2]<a[0]*a[0]+a[1]*a[1])b[1]++;
    if(a[2]*a[2]>a[0]*a[0]+a[1]*a[1])b[2]++;
  }
  cout<<s<<' '<<b[0]<<' '<<b[1]<<' '<<b[2]<<endl;
}

C++: #include <bits/stdc++.h>
using namespace std ;

#define pb(n) push_back(n)
#define fi first
#define se second
#define all(r) (r).begin(),(r).end()
#define gsort(st,en) sort((st),(en),greater<int>())
#define vmax(ary) *max_element(all(ary))
#define vmin(ary) *min_element(all(ary))
#define debug(x) cout<<#x<<": "<<x<<endl
#define fcout(n) cout<<fixed<<setprecision((n))
#define scout(n) cout<<setw(n)
#define vary(type,name,size,init) vector< type> name(size,init)
#define vvl(v,w,h,init) vector<vector<ll>> v(w,vector<ll>(h,init));

#define rep(i,n) for(int i = 0; i < (int)(n);++i)
#define REP(i,a,b) for(int i = (a);i < (int)(b);++i)
#define repi(it,array) for(auto it = array.begin(),end = array.end(); it != end;++it)
#define repa(n,array) for(auto &n :(array))

using ll = long long;
using vi = vector<int>;
using vl = vector<ll>;
using dict = map<string,int>;
using pii = pair<int,int> ;
using pll = pair<ll,ll> ;

const int mod = 1000000007;
constexpr int imax = ((1<<30)-1)*2+1 ;
constexpr int inf = 100000000;
constexpr double PI = acos(-1.0) ;
double eps = 1e-10 ;
const int dy[] = {-1,0,1,0,1,-1,1,-1};
const int dx[] = {0,-1,0,1,1,-1,-1,1};

inline bool value(int x,int y,int w,int h){
  return (x >= 0 && x < w && y >= 0 && y < h);
}

template<typename T>
void Unique(vector<T> &v){
  sort(all(v));
  v.erase(unique(all(v)),v.end());
}

template<typename T>
T ston(string& str, T n){
  istringstream sin(str) ;
  T num ;
  sin >> num ;
  return num ;
}

void Ans(bool f){
  if(f) cout << "YES"<<endl;
  else cout << "NO"<<endl;
}

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  vary(ll,v,3,0);
  ll a = 0,b = 0,c = 0,d = 0;
  while(1){
    cin >> v[0] >> v[1] >> v[2];
    sort(all(v));
    if(! (v[2] < v[0] + v[1])){
      cout << a << " " << b << " " << c << " " << d << endl;
      break;
    }
    else if(v[0] * v[0] + v[1] * v[1] == v[2] * v[2]) ++b;
    else if(v[0]*v[0] + v[1]*v[1] > v[2] * v[2]) ++ c;
    else if(v[0]*v[0] + v[1]*v[1] < v[2] * v[2]) ++ d;
    ++a;
  }
  return 0;
}

C++: #include<iostream>
#include<algorithm>
using namespace std;
int num,s,t;
int main(){

    int x[3];
    while(cin>>x[0]>>x[1]>>x[2]){
        sort(x,x+3);
        int a = x[0],b = x[1],c = x[2];
        if(a+b<=c)break;
        if(a*a+b*b==c*c)s++;
        else if(a*a+b*b>c*c)t++;
        num++;
    }
    cout<<num<<" "<<s<<" "<<t<<" "<<num-s-t<<endl;

    return 0;
}