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<algorithm>
#include<cmath>

using namespace std;

int main(){

	int tri[3];
	int s = 0, e = 0, t = 0, d = 0;

	while (cin >> tri[0] >> tri[1] >> tri[2]){
		sort(tri, tri + 3);
		if (tri[2] >= tri[0] + tri[1]) break;
		s++;
		if (pow(tri[2], 2) == pow(tri[0], 2) + pow(tri[1], 2)) t++;
		if (pow(tri[2], 2) > pow(tri[0], 2) + pow(tri[1], 2)) d++;
		if (pow(tri[2], 2) < pow(tri[0], 2) + pow(tri[1], 2)) e++;
	}

	cout << s << " " << t << " " << e << " " << d << endl;
	return 0;
}

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

int main() {
  int a, b, c;
  int ansn = 0, ans1 = 0, ans2 = 0, ans3 = 0;
  while (cin >> a >> b >> c) {
    if (a + b > c && b + c > a && c + a > b) {
      ansn++;

      if (a < b) {
        int swap = a;
        a = b;
        b = swap;
      }
      if (a < c) {
        int swap = a;
        a = c;
        c = swap;
      }

      int A = b * b + c * c - a * a;

      if (A > 0) ans1++;
      else if (A == 0) ans2++;
      else ans3++;
    } else break;
  }

  cout << ansn << " " << ans1 << " " << ans2 << " " << ans3 << endl;

  return 0;
}

C++: #include "bits/stdc++.h"

using namespace std;

#define rep(i,a,b) for(int i=(a), i##_len=(b);i<i##_len;i++)
#define rrep(i,a,b) for(int i=(b)-1;i>=(a);i--)
#define all(c) begin(c),end(c)

//#define int long long
#define SZ(x) ((int)(x).size())
#define pb push_back
#define mp make_pair

typedef long long ll;
//typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;
typedef pair<double, double> pdd;
typedef vector<vector<int>> mat;
typedef unsigned int uint;

template<class T> bool chmax(T &a, const T &b) { if (a < b) { a = b; return true; } return false; }
template<class T> bool chmin(T &a, const T &b) { if (b < a) { a = b; return true; } return false; }

const int INF = sizeof(int) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const int MOD = (int)1e9 + 7;
const double EPS = 1e-9;

ll a[3];

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

	while (true)
	{
		ll t[3];
		rep(i, 0, 3)
		{
			cin >> t[i];
		}
		sort(t, t + 3);
		if (t[0] + t[1] <= t[2])
		{
			printf("%lld %lld %lld %lld\n", accumulate(a, a + 3, 0LL), a[0], a[1], a[2]);
			break;
		}
		else
		{
			ll tv = t[0] * t[0] + t[1] * t[1] - t[2] * t[2];
			if (tv==0LL)
			{
				a[0]++;
			}
			else if (tv > 0LL)
			{
				a[1]++;
			}
			else
			{
				a[2]++;
			}
		}
	}

	return 0;
}