Go: 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":
					r_t++
				}
				t++
			}	else {
				break
			}
			
	}
	fmt.Println(t, r_t, s_t, o_t)
}

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

int main() {
  vector<int> cnt(3,0);
  while(true) {
    vector<int> v(3);
    cin >> v[0] >> v[1] >> v[2];
    sort(v.begin(),v.end());
    if(v[2] >= v[0]+v[1])
       break;
    if(v[2]*v[2] > v[0]*v[0] + v[1]*v[1])
      cnt[2]++;
    if(v[2]*v[2] == v[0]*v[0] + v[1]*v[1])
      cnt[1]++;
    else
      cnt[0]++;
  }
  cout << cnt[0] << " " << cnt[1] << " " << cnt[2] << endl;
}

C++: #include <stdio.h>
#include <algorithm>
using namespace std;
int main(){
    int a[3],x=0,y=0,z=0;
    while(scanf("%d%d%d",&a[0],&a[1],&a[2])!=EOF){
        sort(a,a+3);
        if(a[0]+a[1]<=a[2])break;
        if(a[0]*a[0]+a[1]*a[1]==a[2]*a[2])x++;
        else if(a[0]*a[0]+a[1]*a[1]<a[2]*a[2])y++;
        else z++;
    }
    printf("%d %d %d %d\n",x+y+z,x,z,y);
}

C++: // clang-format off
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define loop(i, a, n) for (int i = (a); i < (n); i++)
#define rep(i, n) loop(i, 0, n)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define prec(n) fixed << setprecision(n)
constexpr int INF = sizeof(int) == sizeof(long long) ? 1000000000000000000LL : 1000000000;
constexpr int MOD = 1000000007;
constexpr double PI = 3.14159265358979;
template<typename A, typename B> bool cmin(A &a, const B &b) { return a > b ? (a = b, true) : false; }
template<typename A, typename B> bool cmax(A &a, const B &b) { return a < b ? (a = b, true) : false; }
bool odd(const int &n) { return n & 1; }
bool even(const int &n) { return ~n & 1; }
template<typename T> int len(const T &v) { return v.size(); }
template<typename T = int> T in() { T x; cin >> x; return x; }
template<typename T = int> T in(T &&x) { T z(forward<T>(x)); cin >> z; return z; }
template<typename T> istream &operator>>(istream &is, vector<T> &v) { for (T &x : v) is >> x; return is; }
template<typename A, typename B> istream &operator>>(istream &is, pair<A, B> &p) { return is >> p.first >> p.second; }
template<typename T> ostream &operator<<(ostream &os, const vector<vector<T>> &v) { int n = v.size(); rep(i, n) os << v[i] << (i == n - 1 ? "" : "\n"); return os; }
template<typename T> ostream &operator<<(ostream &os, const vector<T> &v) { int n = v.size(); rep(i, n) os << v[i] << (i == n - 1 ? "" : " "); return os; }
template<typename A, typename B> ostream &operator<<(ostream &os, const pair<A, B> &p) { return os << p.first << ' ' << p.second; }
template<typename Head, typename Value> auto vectors(const Head &head, const Value &v) { return vector<Value>(head, v); }
template<typename Head, typename... Tail> auto vectors(Head x, Tail... tail) { auto inner = vectors(tail...); return vector<decltype(inner)>(x, inner); }
// clang-format on

main() {
  vector<int> v(3), x(4);
  while (cin >> v[0] >> v[1] >> v[2]) {
    sort(all(v));
    int a = v[0], b = v[1], c = v[2];
    if (a + b <= c) break;
    x[0]++;
    if (a * a + b * b == c * c) x[1]++;
    if (a * a + b * b > c * c) x[2]++;
    if (a * a + b * b < c * c) x[3]++;
  }
  cout << x << endl;
}

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){ cout << san << ' ' << cho << ' ' << ei << ' ' << don << endl;
                    return 0;}

        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++;
        }
    }
}

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

using namespace std;

int main()
{

    int acute = 0;
    int obtuse = 0;
    int right = 0;

    while (true) {
        int a, b, c;
        cin >> a >> b >> c;

        auto checkTriangle = [](int a, int b, int c) { return a < (b + c); };
        auto angle = [](int a, int b, int c) {
            auto x = static_cast<double>(b * b + c * c - a * a) / (2 * b * c);
            return acos(x);
        };
        auto isObtuse = [](double theta) {
            return M_PI_2 < theta && theta < M_PI;
        };
        auto isRight = [](double theta) {
            return abs(theta - M_PI_2) < 0.0001;
        };

        if (checkTriangle(a, b, c) && checkTriangle(b, a, c) &&
            checkTriangle(c, a, b)) {
            auto theta1 = angle(a, b, c);
            auto theta2 = angle(b, a, c);
            auto theta3 = angle(c, a, b);
            if (isRight(theta1) || isRight(theta2) || isRight(theta3)) {
                right += 1;
            }
            else if (isObtuse(theta1) || isObtuse(theta2) || isObtuse(theta3)) {
                obtuse += 1;
            }
            else {
                acute += 1;
            }
        }
        else {
            cout << (acute + obtuse + right) << " " << right << " " << acute
                 << " " << obtuse << endl;
            break;
        }
    }
}

C++: #include <bits/stdc++.h>

using namespace std;

int main(void) {
  vector<int> v(3);
  int right = 0, acute = 0, obtuse = 0, total = 0;
  
  while (true) {
    for (int i = 0; i < 3; i++) {
      cin >> v[i];
    }
    sort(v.begin(), v.end());
    if (v[0] + v[1] <= v[2]) break;

    int A = v[0] * v[0], B = v[1] * v[1], C = v[2] * v[2];
    if (A + B == C) right++;
    else if (A + B > C) acute++;
    else obtuse++;
    total++;
  }

  cout << total << " " << right << " " << acute << " " << obtuse << endl;

  return 0;
}

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

int ca=0,cb=0,cc=0,cd=0;
int main(){
	int a=0,b=0,c=0;
	int l[3]={0,0,0};
	while(cin>>l[0]>>l[1]>>l[2]){
		sort(l,l+3);
		a=l[0];
		b=l[1];
		c=l[2];
		if(c>=a+b)break;
		ca++;
		
		if((a*a)+(b*b)==c*c){cb++;}
		if((a*a)+(b*b)>(c*c)){cc++;}
		if((a*a)+(b*b)<(c*c)){cd++;}
	}
	cout<<ca<<" "<<cb<<" "<<cc<<" "<<cd<<endl;
	return 0;
}