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 <iomanip>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cmath>
#include <cassert>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
#define chmax(a,b) (a<(b)?(a=b,1):0)
#define chmin(a,b) (a>(b)?(a=b,1):0)
#define valid(y,x,h,w) (0<=y&&y<h&&0<=x&&x<w)
const int INF = 1<<29;
const double EPS = 1e-8;
const double PI = acos(-1);
typedef pair<int,int> pii;
typedef long long ll;

template<class T>
struct Triangle {
  T a,b,c;
  Triangle(T a, T b, T c) : a(a),b(b),c(c) {}
  double area() {
    double s = (a+b+c)*0.5;
    return sqrt(s*(s-a)*(s-b)*(s-c));
  }
  bool isTriangle() {
    return abs(a-b) < c && c < a+b;
  }
  // G getG() {
  //   G t(3);
  //   t[0] = P(0,0);
  //   t[1] = P(a,0);
  //   double x = (a*a+b*b-c*c)/(2*a);
  //   t[2] = P(x,sqrt(b*b-x*x));
  //   return t;    
  // }
  int typeByAngle() {
    if (a*a>b*b+c*c ||
        b*b>c*c+a*a ||
        c*c>a*a+b*b) return -1; // Oblique
    if (a*a==b*b+c*c ||
        b*b==c*c+a*a ||
        c*c==a*a+b*b) return 1; // Right
    return 0;                   // Acute
  }  
};

int main() {
  int a,b,c;
  int A=0,B=0,C=0,D=0;
  while(cin >> a >> b >> c) {
    Triangle<ll> tri(a,b,c);
    if (!tri.isTriangle()) break;
    A++;
    int type = tri.typeByAngle();
    if (type == 0) C++;
    else if (type > 0) B++;
    else D++;
  }
  printf("%d %d %d %d\n",A,B,C,D);
}

C++: #include <iostream>

using namespace std;

int main() {
  int count_total = 0; // 合計
  int count_1 = 0; // 直角三角形
  int count_2 = 0; // 鋭角
  int count_3 = 0; // 鈍角
  while(1) {
    int long_side = 0;
    int short_side1 = 0;
    int short_side2 = 0;
    int a, b, c = 0;
    cin >> a >> b >> c;
    if (!(abs(b-c) < a && a < b + c)) {
      cout << count_total << " " << count_1 << " " << count_2 << " " << count_3 << endl;
      return 0;
    }
    count_total++;
    int max_side = a;
    if (b > a && b > c) {
      // bが一番長い
      long_side = b;
      short_side1 = a;
      short_side2 = c;
    }
    if (c > a && c > b) {
      // cが一番長い
      long_side = c;
      short_side1 = a;
      short_side2 = b;
    } else {
      // aが一番長い
      long_side = a;
      short_side1 = b;
      short_side2 = c;
    }
    int d1 = long_side * long_side;
    int d2 = short_side1 * short_side1 + short_side2 * short_side2;
    // 鈍角
    if (d1 > d2) {
      count_3++;
    } else if (d1 == d2) {
      // 直角
      count_1++;
    } else {
      // 鋭角
      count_2++;
    }
  }

}

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 continue;
    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<bits/stdc++.h>
using namespace std;

int Solve(int a,int b,int c){

  if(c*c < a*a+b*b )return 1;
  if(c*c == a*a+b*b)return 0;
  else return 2;

}

int main(){

  int sum[]={0,0,0};
  vector< int > a(3);

  while(cin>>a[0]>>a[1]>>a[2]){
    sort(a.begin(),a.end());

    if(a[0]+a[1] > a[2]){
      sum[ Solve(a[0],a[1],a[2]) ] ++;
    }
    else{
      break;
    }

  }

  cout << sum[0]+sum[1]+sum[2] << ' ' << sum[0] << ' ' << sum[1] << ' ' << sum[2] << endl;

  return 0;
}

C++: /**
 * File    : JOI_2005_triangle_types.cpp
 * Author  : Kazune Takahashi
 * Created : 2018-3-8 21:20:52
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int cnt[3] = {0, 0, 0};

int main()
{
  int a[3];
  while (cin >> a[0] >> a[1] >> a[2])
  {
    sort(a, a + 3);
    if (a[0] + a[1] <= a[2])
    {
      cout << cnt[0] + cnt[1] + cnt[2] << " "
           << cnt[1] << " " << cnt[0] << " " << cnt[2] << endl;
      return 0;
    }
    int s = a[0] * a[0] + a[1] * a[1];
    int t = a[2] * a[2];
    if (s < t)
    {
      cnt[2]++;
    }
    else if (s == t)
    {
      cnt[1]++;
    }
    else
    {
      cnt[0]++;
    }
  }
}

C++: #include <stdio.h>
#define rep(i, n) for(int i = 0; i < n; ++i)
#define abs(a) a > 0 ? a : -a
 
int main(void) {
  int a, b, c, ta = 0, tb = 0, tc = 0;
  while(scanf("%d%d%d", &a, &b, &c) != EOF) {
    int t;
    if(a < b) t = a, a = b, b = t;
    if(a < c) t = a, a = c, c = t;
    if(b < c) t = c, c = b, b = t;
    if(a >= b + c) break;
    double d;
    double at = (double)a, bt = (double)b, ct = (double)c;
    d = (bt * bt + ct * ct - at * at) / (2 * bt * ct);
    if(d < 0) {
      ta++;
    } else if(d > 0) {
      tb++;
    } else {
      tc++;
    }
  }
  printf("%d %d %d %d\n", ta + tb + tc, tc, tb, ta);
  return 0;
}