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;

typedef complex<double> P;
P pIN() { double x,y; cin >> x >> y; return P(x,y); }
namespace std {
  bool operator < (const P& a, const P& b) {
    // if (abs(a-b)<EPS) return 0;
    return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
  }
}
double cross(const P& a, const P& b) {
  return imag(conj(a)*b);
}
double dot(const P& a, const P& b) {
  return real(conj(a)*b);
}
struct L : public vector<P> {
  L(const P &a, const P &b) {
    push_back(a); push_back(b);
  }
  L() { resize(2); }
};
ostream &operator<<(ostream &os, const L &a) {
  os << a[0] << " -> " << a[1];
  return os;
}
typedef vector<P> G;

bool isTriangle(const G &t) {
  if (t.size() != 3) return 0;
  if (abs(cross(t[1]-t[0], t[2]-t[0])) < EPS) return 0; // line or dot
  return 1;
}
int typeByLength(const G &t) {
  double a = norm(t[0]-t[1]);
  double b = norm(t[1]-t[2]);
  double c = norm(t[2]-t[0]);
  if (abs(a-b) < EPS && abs(b-c) < EPS) return 0; // Equilateral
  if (abs(a-b) < EPS || abs(b-c) < EPS || abs(c-a) < EPS) return 1; // Isosceles
  return 2;                     // Scalene
}
int typeByAngle(const G &t) {
  REP(i,3) {
    double tmp = dot(t[(i+1)%3]-t[i], t[(i+2)%3]-t[i]);
    if (abs(tmp) < EPS) return i+1; // Right
    if (tmp < 0) return -i-1;        // Oblique
  }
  return 0;                     // Acute
}
G triangleFromLength(double a, double b, double c) {
  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 main() {
  int a,b,c;
  int A=0,B=0,C=0,D=0;
  while(cin >> a >> b >> c) {
    if (a==0||b==0||c==0) break;
    G t = triangleFromLength(a,b,c);
    if (!isTriangle(t)) break;
    A++;
    int type = typeByAngle(t);
    if (type == 0) C++;
    else if (type > 0) B++;
    else D++;
  }
  printf("%d %d %d %d\n",A,B,C,D);
}

C++: #include <bits/stdc++.h>
//---------------------------
using namespace std;
//---------------------------
#define REP(i,n) for(int i = 0; i < (n); i++)
#define P(x) cout << (x) << "\n"

#define MOD 1000000007 // 1e9+7
#define PI 3.1415926525
#define ll long long int // 10^18
#define INF 1000000001 // 1e9+1

int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
//---------------------------
int a[3],b[4];

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

  // ifstream in("input.txt");
  // cin.rdbuf(in.rdbuf());

  while(true){
    cin>>a[0]>>a[1]>>a[2];
    sort(a,a+3);
    if(a[2]==a[0]+a[1])break;
    b[0]++;
    int rec=a[2]*a[2]-a[1]*a[1]-a[0]*a[0];
    if(rec==0)b[1]++;
    if(rec>0)b[3]++;
    if(rec<0)b[2]++;
  }
  REP(i,4){
    cout<<b[i]<<" \n"[i==3];
  }
  return 0;
}

C++: #include<cstdio>
int main(void){
    
    int a=0,b=0,c=0;
    int change=0;
    int right=0,obtuse=0,acute=0;
    int value=0,check=0,count=0;
    int flag=true;
    while(flag){
        count++;
        scanf("%d%d%d",&a,&b,&c);
        if(c<a){
            change=a;
            a=c;
            c=a;
        }
        if(c<b){
            change=b;
            b=c;
            c=b;
        }
        check=a+b-c;
        value=a*a+(b*b-c*c);
        if(check<=0){
            break;
        }
        if(value==0){
            right++;
        }
        else if(value<0){
            obtuse++;
        }
        else{
            acute++;
        }
    }
    printf("%d %d %d %d\n",count,right,acute,obtuse);
    return 0;
}

C++: #include<stdio.h>
#include<string>
#include<stdlib.h>
#include<math.h>
#include<iostream>
#include<vector>
#include<algorithm>
#include<numeric>
#include<string.h>
#include<map>
#include<queue>

using namespace std;

typedef pair<int,int> pii;

#define rep(i,j) for(int i=0;i<(j);i++)
#define reps(i,j,k) for(int i=j;i<=k;i++)
#define in(i,j,k) ((i)>=(j)&&(i)<=(k))


int main(){
	int x[3],e,d,t,cnt;
	e=d=t=cnt=0;
	for(;;cnt++){
		rep(i,3)scanf("%d",x+i);
		sort(x,x+3);
		if(x[2]>=x[0]+x[1])break;
		rep(i,3)x[i]*=x[i];
		if(x[2]==x[0]+x[1])t++;
		else if(x[2]<x[0]+x[1])e++;
		else d++;
	}
	printf("%d %d %d %d\n",cnt,t,e,d);
	return 0;
}

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

using namespace std;

int main(){
    int e[3];
    int cnt1=0,cnt2=0,cnt3=0,cnt4=0;
    while(cin>>e[0]>>e[1]>>e[2]){
        sort(e,e+3);
        int a=e[0],b=e[1],m=e[2];
        if(m<a+b){
            ++cnt1;
            if(m*m<a*a+b*b) ++cnt3;
            else if(m*m==a*a+b*b) ++cnt2;
            else ++cnt4;
        }
    }
    cout<<cnt1<<" "<<cnt2<<" "<<cnt3<<" "<<cnt4<<endl;
    return 0;
}

C++: #include <iostream>

using namespace std;

int main() {
  int count_total = 0; // 合計
  int count_1 = 0; // 直角三角形
  int count_2 = 0; // 鋭角
  int count_3 = 0; // 鈍角
  for (int l = 0; l < 100; l++) {
    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++;
    }
  }

}