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 <vector>
#include <list>
#include <cmath>
#include <fstream>
#include <algorithm>
#include <string>
#include <queue>
#include <set>
#include <map>
#include <complex>
#include <iterator>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <stack>
#include <climits>
#include <deque>
#include <bitset>
#include <cassert>
#include <ctime>
using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
const int dy[]={-1,0,1,0},dx[]={0,1,0,-1};
// adjust problem by problem
const double EPS=1e-8;
const double PI=acos(-1.0);
#ifdef __GNUC__
int popcount(int n){return __builtin_popcount(n);}
int popcount(ll n){return __builtin_popcountll(n);}
#endif
#ifndef __GNUC__
template<class T> int popcount(T n){int cnt=0;while(n){if(n%2)cnt++;n/=2;}return cnt;}
#endif
template<class T>int SIZE(T a){return a.size();}
template<class T>string IntToString(T num){string res;stringstream ss;ss<<num;return ss.str();}
template<class T>T StringToInt(string str){T res=0;for(int i=0;i<SIZE(str);i++)res=(res*10+str[i]-'0');return res;}
template<class T>T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template<class T>T lcm(T a,T b){return a/gcd(a,b)*b;}
template<class T> void PrintSeq(T &a,int sz){for(int i=0;i<sz;i++){cout<<a[i];if(sz==i+1)cout<<endl;else cout<<' ';}}
bool EQ(double a,double b){return abs(a-b)<EPS;}
void fastStream(){cin.tie(0);std::ios_base::sync_with_stdio(0);}
vector<string> split(string str,char del){
  vector<string> res;
  for(int i=0,s=0;i<SIZE(str);i++){
    if(str[i]==del){if(i-s!=0)res.push_back(str.substr(s,i-s));s=i+1;}
    else if(i==SIZE(str)-1){res.push_back(str.substr(s));}
  }
  return res;
}

int main(){

  int x,y,z;
  int tri=0;
  int t=0;
  int e=0;
  int d=0;
  while(cin>>x>>y>>z){
    vector<int> v;
    v.push_back(x);
    v.push_back(y);
    v.push_back(z);
    sort(v.begin(),v.end());
    if(v[0]+v[1]<=v[2])break;
    else{
      tri++;
      if(v[0]*v[0]+v[1]*v[1]==v[2]*v[2])t++;
      else if(v[0]*v[0]+v[1]*v[1]>v[2]*v[2])e++;
      else d++;
    }
  }
  cout<<tri<<" "<<t<<" "<<e<<" "<<d<<endl;
  
  return 0;
}

C++: #input_f = "3 4 5\n2 1 2\n6 3 4\n1 1 1\n1 2 3"
def t_check(a,b,c):
    if a + b > c:
        if b + c > a:
            if a + c > b: return True
    return False



def f_check(a_, b_, c_):
    tmp = []
    tmp.append(a_)
    tmp.append(b_)
    tmp.append(c_)
    sqrts = []
    for i in range(3):
        sqrts.append(tmp[i]**2)
    m = max(sqrts)
    s = sum(sqrts)

    if m == (s - m): return(0)
    if m > (s - m): return(2)
    if m < (s - m): return(1)
    
    
counter=[0,0,0]
    
    
while(1):
    input_f = input()


    t = input_f.split("\n")[i].split()
    fn, sn, tn = int(t[0]),int(t[1]),int(t[2])
    if t_check(fn,sn,tn):
        counter[f_check(fn,sn,tn)] += 1
    else: break
    

print(sum(counter),counter[0], counter[1], counter[2])

C++: #include<iostream>
using namespace std;
int main()
{
  int ans[4]={0,0,0,0};
  int a,b,c;
  for(;cin>>a>>b>>c;)
    {
      if(a+b<=c||c+b<=a||a+c<=b)
	break;
      ans[0]++;
      if(c<a)
	swap(a,c);
      if(c<b)
	swap(b,c);
      if(a*a+b*b==c*c)
	ans[1]++;
      else if(a*a+b*b>c*c)
	ans[2]++;
      else if(a*a+b*b<c*c)
	ans[3]++;
    }
  cout<<ans[0]<<" "<<ans[1]<<" "<<ans[2]<<" "<<ans[3]<<endl;
}

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

int main() {
  vector<int> edge;
  int rgt_num, act_num, obt_num;

  rgt_num= 0;
  act_num= 0;
  obt_num= 0;
  while(1) {
    for(int i = 0; i < 3; i++) {
      int E;
      cin >> E;
      edge.push_back(E);
    }

    sort(edge.begin(), edge.end(), greater<int>());

    int a = edge[0];
    int b = edge[1];
    int c = edge[2];

    if(a >= b + c)
      break;
    else if(pow(a, 2) == pow(b, 2) + pow(c, 2))
      rgt_num++;
    else if(pow(a, 2) < pow(b, 2) + pow(c, 2))
      act_num++;
    else
      obt_num++;
    edge.clear();
  }
  cout << rgt_num + act_num + obt_num << ' ' <<  rgt_num
       << ' ' << act_num << ' ' << obt_num << endl;
}

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

using namespace std;

int main(){
  int a[3];
  int x,y;
  int san=0,tyoku=0,ei=0,don=0;

  while(1){
    cin>>a[0]>>a[1]>>a[2];
    sort(a,a+3);
    x=a[0]*a[0]+a[1]*a[1];
    y=a[2]*a[2];

    if(a[0]+a[1] <= a[2])
      break;
    else if (x == y)
      tyoku++;
    else if(x > y)
      ei++;
    else if (x < y)
      don++;
  }

  san=tyoku+ei+don;
  cout<<san<<" "<<tyoku<<" "<<ei<<" "<<don<<endl;

  return 0;
}

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

typedef unsigned int U4;
#define TRUE 1
#define FALSE 0

#define ACUTE_TRIANGLE 0
#define RIGHT_TRIANGLE 1
#define OBTUSE_TRIANGLE 2

U4 TrinagleNum = 0;
U4 AcuteTriangleNum = 0;
U4 RightTriangleNum = 0;
U4 ObtuseTriangleNum = 0;

U4 U4_TriangleCheck(U4,U4,U4);
U4 U4_TypeCheck(U4,U4,U4);
void V_LengthSort(U4*,U4*,U4*);
int main(void){

U4 a;
U4 b;
U4 c;

  while(1){
    cin >> a >> b >> c;
    if(U4_TriangleCheck(a,b,c) == TRUE){
      TrinagleNum++;
      if(U4_TypeCheck(a,b,c) == ACUTE_TRIANGLE){
        AcuteTriangleNum++;
      }else if(U4_TypeCheck(a,b,c) == OBTUSE_TRIANGLE){
        ObtuseTriangleNum++;
      }else{
        RightTriangleNum++;
      }
    }else{
      break;
    }
  }

  cout << TrinagleNum << " " << RightTriangleNum << " " << AcuteTriangleNum << " " << ObtuseTriangleNum << endl;
}

U4 U4_TriangleCheck(U4 a,U4 b,U4 c){
  if((a + b > c) && (b + c > a) && (c + a > b)){
    return TRUE;
  }else{
    return FALSE;
  }
}

U4 U4_TypeCheck(U4 a,U4 b,U4 c){
  U4 LongLength;
  U4 MiddleLength;
  U4 ShortLength;
  U4 LongLengthSquare;
  U4 MiddleLengthSquare;
  U4 ShortLengthSquare;

  LongLength   = a;
  MiddleLength = b;
  ShortLength  = c;

  V_LengthSort(&LongLength,&MiddleLength,&ShortLength);

  LongLengthSquare   = LongLength * LongLength;
  MiddleLengthSquare = MiddleLength * MiddleLength;
  ShortLengthSquare  = ShortLength * ShortLength;

  if(MiddleLengthSquare + ShortLengthSquare > LongLengthSquare){
    return ACUTE_TRIANGLE;
  }else if(MiddleLengthSquare + ShortLengthSquare < LongLengthSquare){
    return OBTUSE_TRIANGLE;
  }else{
    return RIGHT_TRIANGLE;
  }
}

void V_LengthSort(U4* Long,U4 *Middle,U4 *Short){
  U4 buff;

  if((*Long >= *Middle) && (*Long >= *Short)){
    // Do Nothing
  }else if(*Middle >= *Short){
    buff = *Long;
    *Long = *Middle;
    *Middle = buff;
  }else{
    buff = *Long;
    *Long = *Short;
    *Short = buff;
  }
}