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 <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <bitset>
#include <algorithm>
#include <numeric>
#include <functional>
using namespace std;

#define Rep(b, e, i) for(int i = b; i <= e; i++)
#define Repr(e, b, i) for(int i = e; i >= b; i--)
#define rep(n, i) Rep(0, n-1, i)
#define repr(n, i) Repr(n-1, 0, i)
#define all(v) (v).begin(), (v).end()
#define pb(x) push_back(x)
#define uniq(x) (x).erase(unique(all(x)),(x).end())

typedef long long ll;
typedef pair<ll, ll> llP;
typedef pair<int, int> intP;
typedef std::priority_queue<int> IntPrioQueue; //Z->A
typedef std::priority_queue<int, std::vector<int>, std::greater<int> > IntReversePrioQueue; //A->Z

const int MAX = 200000;
const double PI = 3.14159265358979323846;
const double EPS = 1e-12;
const int INF = 1<<29;
const int MOD = 1000000007;

int ls[3], cnt, don, cho, ei;

void solve(void){
    while (1) {
        scanf("%d %d %d\n", &ls[0], &ls[1], &ls[2]);
        sort(ls, ls+3);
        if (ls[0] + ls[1] <= ls[2]) {
            printf("%d %d %d %d\n", cnt, cho, ei, don);
            break;
        }
        cnt++;
        if (ls[0]*ls[0] + ls[1]*ls[1] == ls[2]*ls[2]) cho++;
        else if (ls[0]*ls[0] + ls[1]*ls[1] > ls[2]*ls[2]) ei++;
        else don++;
    }
}

int main(void){
  solve();
  return 0;
}

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

static const int TOTAL = 0;
static const int RIGHT = 1;
static const int ACUTE = 2;
static const int OBTUSE = 3;

bool isTriangle(int *ary) {	return ary[0] < ary[1] + ary[2]; }

void sort(int *ary, int n) {
	for (int i = n - 1; i > 0; i--) {
		for (int j = 0; j < i; j++) {
			if (ary[j] < ary[j + 1]) {
				swap(ary[j], ary[j + 1]);
			}
		}
	}
}

void judgeAndSet(int *ary,int *count) {
	int d = ary[1] * ary[1] + ary[2] * ary[2] - ary[0] * ary[0];
	if (d == 0) count[RIGHT]++;
	else if (d > 0) count[ACUTE]++;
	else count[OBTUSE]++;
	count[TOTAL]++;
}


int main() {
	int ary[3];
	int count[4] = { 0,0,0,0 };
	int num = 0;
	while (true) {
		cin >> ary[0] >> ary[1] >> ary[2];
		sort(ary, 3);
		if (!isTriangle(ary)) break;
		judgeAndSet(ary, count);
	}

	for (int i = 0; i < 4; i++) {
		if (i) cout << " ";
		cout << count[i];
	}
	cout << endl;
	
	return 0;
}

C++: #include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<math.h>
#include<string>
#include<string.h>
#include<stack>
#include<queue>
#include<vector>
#include<utility>
#include<set>
#include<map>
#include<stdlib.h>
#include<iomanip>

using namespace std;

#define ll long long
#define ld long double
#define EPS 0.0000000001
#define INF 1e9
#define MOD 1000000007
#define rep(i,n) for(i=0;i<n;i++)
#define loop(i,a,n) for(i=a;i<n;i++)
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)
#define first F
#define second S

typedef vector<int> vi;
typedef pair<int,int> pii;

int main(void) {
  vi l(3);
  vi n(4,0);
  while(scanf("%d %d %d",&l[0],&l[1],&l[2])!=EOF){
    sort(all(l));
    if(l[0]+l[1]>l[2])n[0]++;
    else break;
    int hypo=l[0]*l[0]+l[1]*l[1];
    if(hypo==l[2]*l[2])n[1]++;
    else if(hypo>l[2]*l[2])n[2]++;
    else if(hypo<l[2]*l[2])n[3]++;
  }
  printf("%d %d %d %d\n",n[0],n[1],n[2],n[3]);
}

C++: #include<algorithm>
#include<iostream>
using namespace std;
 
int out[4] = {0};
 
int main() {
int l[3];
while( cin >> l[0] >> l[1] >> l[2] ) {
sort(l, l+3);
if ( l[2] > l[0] + l[1] )
break;
 
out[0]++;
if ( l[2] * l[2] == l[0] * l[0] + l[1] * l[1] )
out[1]++;
if ( l[2] * l[2] < l[0] * l[0] + l[1] * l[1] )
out[2]++;
if ( l[2] * l[2] > l[0] * l[0] + l[1] * l[1] )
out[3]++;
}
 
cout << out[0] << " " << out[1] << " " << out[2] << " " << out[3] << endl;
return 0;
}

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

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

C++: #include <iostream>
#include <cstdio>
#include <algorithm>
#define S(x) x*x
using namespace std;
int a,b,c,d;
bool flag=true;
int main(void){
  int x[3];
  while(cin>>x[0]>>x[1]>>x[2]){
    sort(x,x+3);
    if(x[0]+x[1]<=x[2])flag=false;
    if(flag){
      a++;
      if(S(x[0])+S(x[1])==S(x[2]))b++;
      if(S(x[0])+S(x[1])>S(x[2]))c++;
      if(S(x[0])+S(x[1])<S(x[2]))d++;
    }
  }
  printf("%d %d %d %d\n",a,b,c,d);
  return 0;
}

C++: #include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int X[3];
int ans,ans1,ans2,ans3;
int C;
int main()
{
	while(true){
		for(int i=0;i<3;i++)scanf("%d",&X[i]);
		sort(X,X+3);
		if(X[0]+X[1]<=X[2])break;
		ans++;
		C=X[0]*X[0]+X[1]*X[1]-X[2]*X[2];
		if(C>0)ans1++;
		else if(C==0)ans2++;
		else ans3++;
	}
	printf("%d %d %d %d\n",ans,ans2,ans1,ans3);
	return 0;
}

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

int main() {
    int a, b, c;
    int tri=0, sharp=0, obtuse=0, right=0;
    while(cin>>a>>b>>c) {
        int temp = max({a, b, c});
        if(temp==b) {
            swap(a, b);
        } else if(temp==c) {
            swap(a, c);
        }
        if(a>=b+c) break;
        tri++;
        int d = b*b+c*c-a*a;
        if(d==0) right++;
        else if(d>0) sharp++;
        else obtuse++;
    }
    cout << tri << ' ' << right << ' ' << sharp << ' ' << obtuse << '\n';

    return 0;
}

C++: #include<cstdio>
int a,b,c;
int re[4]={-1};
void st(int* p,int* q){
int r;
if(*p<*q){
r=*p;*p=*q;*q=r;
}
return;
}
int main(void){
while(1){
re[0]++;
scanf("%d%d%d",&a,&b,&c);
st(&a,&b);st(&a,&c);st(&b,&c);
if(a>=b+c)break;
if(a*a>b*b+c*c)re[3]++;
else if(a*a<b*b+c*c)re[2]++;
else re[1]++;
}
for(a=0;a<4;a++){
printf("%d ",re[a]);
}
printf("\n");
return 0;
}