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 <cmath>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    int x,y,z;
    int san,don,cho,ei;
    for(int i=0;;i++){
        cin >> x >> y >> z;
        int a = max(max(x,y),z),b,c;
        if(a == x) b=y,c=z;
        else if(a == y) b=z,c=x;
        else if(a == z) b=x,c=y;

        if(a >= b+c) break;

        else if(a*a > b*b + c*c){
            san++;
            don++;
        }
        else if(a*a == b*b + c*c){
            san++;
            cho++;
        }
        else if(a*a < b*b + c*c){
            san++;
            ei++;
        }
    }

    cout << san << ' ' << cho << ' ' << ei << ' ' << don << endl;
}

C++: #define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
#define INF         1e9
#define EPS         1e-9
#define REP(i,n)    for(lint i=0,i##_len=(n);i<i##_len;++i)
#define REP1(i,n)   for(lint i=1,i##_len=(n);i<=i##_len;++i)
#define REPR(i,n)   for(lint i=(n)-1;i>=0;--i)
#define REPR1(i,n)  for(lint i=(n);i>0;--i)
#define REPC(i,obj) for(auto i:obj)
#define R_UP(a,b)   (((a)+(b)-1)/(b))
#define ALL(obj)    (obj).begin(),(obj).end()
#define SETP        cout << fixed << setprecision(8)
using namespace std;
using lint = long long;
template<typename T = lint>inline T in() { T x; cin >> x; return x; }

signed main()
{
	int tr1 = 0, tr2 = 0, tr3 = 0, tr4 = 0;
	for (;;)
	{
		int a = in(), b = in(), c = in();
		if (a >= b + c || b >= c + a || c >= a + b)
		{
			cout << tr1 << ' ' << tr2 << ' ' << tr3 << ' ' << tr4 << endl;
			return 0;
		}
		else
		{
			tr1++;
			if (a * a == b * b + c * c || b * b == c * c + a * a || c * c == a * a + b * b)tr2++;
			else if (a * a < b * b + c * c && b * b < c * c + a * a && c * c < a * a + b * b)tr3++;
			else tr4++;
		}
	}
}

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=change;
        }
        if(c<b){
            change=b;
            b=c;
            c=change;
        }
        check=a+b-c;
        value=a*a+b*b-c*c;
        if(check<=0){
            break;
        }
        
        if(value==0){
            right++;
        }
        if(value<0){
            acute++;
        }
        if(value>0){
            obtuse++;
        }
    }
    printf("%d %d %d %d\n",count,right,acute,obtuse);
    return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;

int main()
{
  int a,b,c;
  int L = 0;
  int L1 = 0;
  int L2 = 0;
  int L3 = 0;

  while(1){
    cin>>a>>b>>c;
    int d = max(a,b);
    int e = max(d,c);
    int f = min(a,b);
    int g = min(d,c);

    if(f + g <= e){
      break;
    }

    int delta = (f * f) + (g * g) - (e * e);
    if(delta == 0){
      ++L1;
    }
    else if(delta > 0){
      ++L2;
    }
    else{
      ++L3;
    }
  }
  L = L1 + L2 + L3;
  cout<<L<<" "<<L1<<" "<<L2<<" "<<L3<<endl;
  return 0;
}

C++: #include <iostream>

using namespace std;

int main() {
    int num_right=0, num_acute=0, num_obtuse=0;
    while(true){
        int x, y, z;
        cin >> x >> y >> z;
        if(x<y) swap(x, y);
        if(x<z) swap(x, z);
        if(x>=y+z) break;
        if(x*x==y*y+z*z) ++num_right;
        else if(x*x<y*y+z*z) ++num_acute;
        else ++num_obtuse;
    }
    cout << num_acute+num_right+num_obtuse << " "
         << num_right << " "
         << num_acute << " "
         << num_obtuse << "\n";
    return 0;
}

C++: package main
// 三角形の形は辺の長さで決まる． 順番に３つの正整数が与えられたとき， 辺の長さがそれらの値と一致する三角形が存在するかどうかを調べ,
//  存在するなら鋭角三角形，直角三角形，鈍角三角形のいずれかを判定し， 次の入力へ進む． 三角形が存在しないとき， それまでに入力された，
// 三角形，直角三角形，鋭角三角形，鈍角三角形の 個数を空白で区切って出力し， それ以降の入力は無視して終了する
// 入力の中には必ず三角形が存在しないようなものがある と仮定してよい. 入力の行数は判らないが各行には３つの正整数が空白で区切って書かれている．
//  ただし，各整数は100 以下とする.

// return
// 三角形 直角三角形　鈍角三角形 鈍角三角形
import (
	"os"
	"fmt"
	"bufio"
)


var sc = bufio.NewScanner(os.Stdin)

func max(a, b, c int) (int, int, int) {
	if a > b {
		if b > c {
			return a, b, c
		} else {
			return a, c, b
		}
	} else {
		if a > c {
			return b, a, c
		} else {
			return b, c, a
		}
	}
}

func find_trianges(a, b, c int) string {
	a, b, c = max(a, b, c)
	r := b*b + c*c
	if a*a > r {
		return "obtuse_triangle"
	} else if a*a < r {
		return "sharped_triangle"
	} else {
		return "right_triangle"
	}
}

func main() {
	s := bufio.NewScanner(os.Stdin)
	var t, r_t, s_t, o_t int = 0, 0, 0, 0
	for s.Scan() {
		var a, b, c int
		fmt.Sscan(s.Text(), &a, &b, &c)
			a, b, c = max(a, b, c)
			if (a < b + c) {
				r := find_trianges(a, b, c)
				switch r {
				case "right_triangle":
					r_t++
				case "sharped_triangle":
					s_t++
				case "obtuse_triangle":
					o_t++
				}
				t++
			}	else {
				break
			}
			
	}
	fmt.Println(t, r_t, s_t, o_t)
}

C++: #include<iostream>

using namespace std;

int main(){
    int a[100];
    int b[100];
    int c[100];
    int n=0;
    int m=0;
    int k=0;
    int l=0;

    for(int i=0;i<100;i++){
        cin >> a[i] >> b [i] >> c[i];

        if(a[i]+b[i]<=c[i] || a[i]+c[i]<b[i] || b[i]+c[i]<a[i]){
            break;
        }else if(a[i]*a[i]+b[i]*b[i]==c[i]*c[i] || a[i]*a[i]+c[i]*c[i]==b[i]*b[i] || b[i]*b[i]+c[i]*c[i]==a[i]*a[i]){
            n++;
            m++;
        }else if(a[i]*a[i]+b[i]*b[i]<c[i]*c[i] || a[i]*a[i]+c[i]*c[i]<b[i]*b[i] || b[i]*b[i]+c[i]*c[i]<a[i]*a[i]){
            n++;
            k++;
        }else{
            n++;
            l++;
        }
    }
    cout << n << " " << m << " " << l << " " << k << endl;
}

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

int main(){

    bool holds = true;
    vector<int> mem(4,0);//0が三角形の数　１が直角　２が鋭角　３が鈍角
    vector<int> tri(3);

    while(holds){
        vector<int> node(3);
        int a,b,c;
        cin>>node[0]>>node[1]>>node[2];

        for(int i=0;i<3;i++){
            if(node[i] >= node[(i+1)%3] + node[(i+2)%3]){
                holds = false;
            }
            else {
               sort(node.begin(),node.end());
               a = node[2];
               b = node[1];
               c = node[0];
            }
        }

        if(holds){
            mem[0]++;
            if(a*a > b*b + c*c) mem[3]++;
            else if (a*a < b*b + c*c) mem[2]++;
            else mem[1]++;
        }
    }
    for(int i=0;i<3;i++){
        cout<<mem[i]<<" ";
    }
    cout<<mem[3]<<endl;
}