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>
typedef long long ll;
using namespace std;
ll MOD = 1000000007;

#define vec                vector<int>
#define vecll              vector<ll>
#define vecst              vector<string>
#define vecb               vector<bool>
#define vec2(var, n, m)    vector<vector<int>> var(n, vector<int>(m, 0))
#define vecll2(var, n, m)  vector<vector<ll>> var(n, vector<ll>(m, 0))

#define rep(i,n)         for(ll i=(ll)0; i<(ll)n; i++)
#define REP(i,m,n)       for(ll i=(ll)m; i<(ll)n; i++)
#define arr(var, n)      vec var(n); rep(i,n){cin >> var[i];}
#define arrll(var, n)    vecll var(n); rep(i,n){cin >> var[i];}
#define arrst(var, n)    vecst var(n); rep(i,n){cin >> var[i];}
#define all(var)         (var).begin(), (var).end()
#define sortall(var)     sort(all(var))
#define uniqueall(v)     v.erase(unique(v.begin(), v.end()), v.end());
#define f_sum(var)       accumulate(all(var), 0)
#define f_sumll(var)     accumulate(all(var), 0LL)
#define chmin(v1, v2)    v1 = min(v1, v2)
#define chmax(v1, v2)    v1 = max(v1, v2)
#define mp(v1, v2)       make_pair(v1, v2)
#define pb(var)          push_back(var)
#define prt(var)         cout << (var) << "\n"
#define prtd(n, var)     cout << fixed << setprecision(n) << var << "\n"
#define prtfill(n, var)  cout << setw(n) << setfill('0') << var;
#define prt2(v1, v2)     cout << v1 << " " << v2 << "\n"
#define prt3(v1, v2, v3) cout << v1 << " " << v2 << " " << v3 << "\n"
#define prtall(v)        rep(i,v.size()){cout<<v[i]<<(i!=v.size()-1?" ":"\n");}
void prtok(bool ok){prt(ok ? "Yes" : "No");}
//----------------------------------------------------------------
int main(void) {
  ll ans_num=0, ans_0=0, ans_p=0, ans_m=0;
  while(1){
    vec a(3, 0);
    cin >> a[0] >> a[1] >> a[2];
    sortall(a);

    if(a[2]<(a[0]+a[1])){
      ans_num++;
      ll judge=(a[0]*a[0] + a[1]*a[1] - a[2]*a[2]);
      if(judge>0) ans_p++;
      if(judge<0) ans_m++;
      if(judge==0) ans_0++;
    } else {
      cout << ans_num << " " << ans_0 << " " << ans_p << " " << ans_m << "\n";
      return 0;
    }
  }
}

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

int main() {
  vector<int> cnt(3,0);
  while(true) {
    vector<int> v(3);
    cin >> v[0] >> v[1] >> v[2];
    sort(v.begin(),v.end());
    if(v[2] >= v[0]+v[1])
       break;
    if(v[2]*v[2] > v[0]*v[0] + v[1]*v[1])
      cnt[2]++;
    if(v[2]*v[2] == v[0]*v[0] + v[1]*v[1])
      cnt[1]++;
    else
      cnt[0]++;
  }
  cout << cnt[0] + cnt[1] + cnt[2] << " " << cnt[1] << " " << cnt[0] << " " << cnt[2] << endl;
}

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

using pii = pair<int, int>;
using vi = vector<int>;
using ll = long long;

int main() {
    int x = 0, y = 0, z = 0;
    int a, b, c;
    while(cin >> a >> b >> c) {
        int a1 = min({a, b, c}), a3 = max({a, b, c}), a2 = a + b + c - a1 - a3;
        if(a1 + a2 <= a3) {
            break;
        }
        if(a1 * a1 + a2 * a2 == a3 * a3) {
            x += 1;
        } else if(a1 * a1 + a2 * a2 > a3 * a3) {
            y += 1;
        } else {
            z += 1;
        }
    }
    cout << x + y + z << ' ' << x << ' ' << y << ' ' << z << endl;
}

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

int main(){
	vector<int> a(3), ans(4, 0);
	while( cin >> a[0] >> a[1] >> a[2] ){
		sort(a.begin(), a.end());
		double cosX = (double) (a[0] * a[0] + a[1] * a[1] - a[2] * a[2]) / 2.0 * a[0] * a[1];
		 
		if( a[0] + a[1] <= a[2] ){ // 三角形でない
			cout << ans[0] << " " << ans[1] << " " << ans[2] << " " << ans[3] << endl;
			return 0;
		}else if( a[0] * a[0] + a[1] * a[1] == a[2] * a[2] ){ // 直角三角形
			ans[1]++;
		}else if( cosX <= 0 ){ // 鈍角三角形
			ans[3]++;
		}else{ // 鋭角三角形
			ans[2]++;
		}
		ans[0]++;
	}
}

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

typedef long long int ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<pair<int, int> > vii;
#define rrep(i, m, n) for(int (i)=(m); (i)<(n);  (i)++)
#define erep(i, m, n) for(int (i)=(m); (i)<=(n); (i)++)
#define  rep(i, n)    for(int (i)=0; (i)<(n);  (i)++)
#define rrev(i, m, n) for(int (i)=(n)-1; (i)>=(m); (i)--)
#define erev(i, m, n) for(int (i)=(n); (i)>=(m); (i)--)
#define  rev(i, n)    for(int (i)=(n)-1; (i)>=0; (i)--)
#define vrep(i, c)    for(__typeof((c).begin())i=(c).begin(); i!=(c).end(); i++)
#define  ALL(v)       (v).begin(), (v).end()
#define mp            make_pair
#define pb            push_back
template<class T, class S> inline bool minup(T& m, S x){ return m>(T)x ? (m=(T)x, true) : false; }
template<class T, class S> inline bool maxup(T& m, S x){ return m<(T)x ? (m=(T)x, true) : false; }

const int    INF = 1000000000;
const ll     MOD = 1000000007LL;
const double EPS = 1E-12;

template<typename T> ostream& operator <<(ostream& r, const vector<T> t){vrep(v,t)r<<*v<<(v+1==t.end()?"":" ");return r;}
template<typename T> ostream& operator <<(ostream& r, const pair<vector<T>, int> p){int n=p.second;minup(n,p.first.size());rep(i,n-1)r<<p.first[i]<<' ';r<<p.first[n-1];return r;}
template<typename T> ostream& operator <<(ostream& r, const pair<T*, int> p){int n=p.second-1;rep(i,n)r<<p.first[i]<<' ';return r<<p.first[n];}
template<typename T, size_t S> ostream& operator <<(ostream& r, const T (&a)[S]){rep(i,S-1)r<<a[i]<<' ';return r<<a[S-1];}


int l[3];
int res[4];

int main()
{
  while(cin >> l[0] >> l[1] >> l[2]){
    sort(l, l+3);
    if(l[0] + l[1] <= l[2]){
      cout << res << endl;
      break;
    }
    int s = l[0] * l[0] + l[1] * l[1];
    int t = l[2] * l[2];
    res[0] += 1;
    if(s == t) res[1] += 1;
    if(s  > t) res[2] += 1;
    if(s  < t) res[3] += 1;
  }

  return 0;
}

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

using namespace std;

// Checks the sides satisfies the triangle inequality.
inline bool Ok(int a, int b, int c) {
  return a < b + c && b < a + c && c < a + b;
}

int main() {
  size_t i = 0;
  size_t obtuse = 0;
  size_t acute = 0;
  size_t right = 0;

  int a, b, c;
  for (;;) {
    cin >> a >> b >> c;
    if (!Ok(a, b, c)) {
      printf("%lu %lu %lu %lu\n", i, right, acute, obtuse);
      break;
    }
    const auto m = max({a, b, c});
    int lhs = 0;
    int rhs = 0;
    if (m == a) {
      lhs = a * a;
      rhs = b * b + c * c;
    } else if (m == b) {
      lhs = b * b;
      rhs = a * a + c * c;
    } else { // m == c
      lhs = c * c;
      rhs = a * a + b * b;
    }
    if (lhs == rhs) {
      ++right;
    } else if (lhs < rhs) {
      ++acute;
    } else {
      ++obtuse;
    }

    ++i;
  }

  return 0;
}