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

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

#define vec                vector<int>
#define vecll              vector<ll>
#define vecst              vector<string>
#define vecb               vector<bool>
#define vec2(var, n, m)    vector<vector<int>> var(n, vector<int>(m, 0))
#define vecll2(var, n, m)  vector<vector<ll>> var(n, vector<ll>(m, 0))

#define rep(i,n)         for(ll i=(ll)0; i<(ll)n; i++)
#define REP(i,m,n)       for(ll i=(ll)m; i<(ll)n; i++)
#define arr(var, n)      vec var(n); rep(i,n){cin >> var[i];}
#define arrll(var, n)    vecll var(n); rep(i,n){cin >> var[i];}
#define arrst(var, n)    vecst var(n); rep(i,n){cin >> var[i];}
#define all(var)         (var).begin(), (var).end()
#define sortall(var)     sort(all(var))
#define uniqueall(v)     v.erase(unique(v.begin(), v.end()), v.end());
#define f_sum(var)       accumulate(all(var), 0)
#define f_sumll(var)     accumulate(all(var), 0LL)
#define chmin(v1, v2)    v1 = min(v1, v2)
#define chmax(v1, v2)    v1 = max(v1, v2)
#define mp(v1, v2)       make_pair(v1, v2)
#define pb(var)          push_back(var)
#define prt(var)         cout << (var) << "\n"
#define prtd(n, var)     cout << fixed << setprecision(n) << var << "\n"
#define prtfill(n, var)  cout << setw(n) << setfill('0') << var;
#define prt2(v1, v2)     cout << v1 << " " << v2 << "\n"
#define prt3(v1, v2, v3) cout << v1 << " " << v2 << " " << v3 << "\n"
#define prtall(v)        rep(i,v.size()){cout<<v[i]<<(i!=v.size()-1?" ":"\n");}
void prtok(bool ok){prt(ok ? "Yes" : "No");}
//----------------------------------------------------------------
int main(void) {
  ll ans_num=0, ans_0=0, ans_p=0, ans_m=0;
  while(1){
    vec a(3, 0);
    cin >> a[0] >> a[1] >> a[2];
    sortall(a);

    if(a[2]<(a[0]+a[1])){
      ans_num++;
      ll judge=(a[0]*a[0] + a[1]*a[1] - a[2]*a[2]);
      if(judge>0) ans_p++;
      if(judge<0) ans_m++;
      if(judge==0) ans_0++;
    } else {
      cout << ans_num << " " << ans_0 << " " << ans_p << " " << ans_m << "\n";
      return 0;
    }
  }
}

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] << " " << cnt[1] << " " << cnt[0] << " " << cnt[2] << endl;
}

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

using pii = pair<int, int>;
using vi = vector<int>;
using ll = long long;

int main() {
    int x = 0, y = 0, z = 0;
    int a, b, c;
    while(cin >> a >> b >> c) {
        int a1 = min({a, b, c}), a3 = max({a, b, c}), a2 = a + b + c - a1 - a3;
        if(a1 + a2 <= a3) {
            break;
        }
        if(a1 * a1 + a2 * a2 == a3 * a3) {
            x += 1;
        } else if(a1 * a1 + a2 * a2 > a3 * a3) {
            y += 1;
        } else {
            z += 1;
        }
    }
    cout << x + y + z << ' ' << x << ' ' << y << ' ' << z << endl;
}

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

int main(){
	vector<int> a(3), ans(4, 0);
	while( cin >> a[0] >> a[1] >> a[2] ){
		sort(a.begin(), a.end());
		double cosX = (double) (a[0] * a[0] + a[1] * a[1] - a[2] * a[2]) / 2.0 * a[0] * a[1];
		 
		if( a[0] + a[1] <= a[2] ){ // 三角形でない
			cout << ans[0] << " " << ans[1] << " " << ans[2] << " " << ans[3] << endl;
			return 0;
		}else if( a[0] * a[0] + a[1] * a[1] == a[2] * a[2] ){ // 直角三角形
			ans[1]++;
		}else if( cosX <= 0 ){ // 鈍角三角形
			ans[3]++;
		}else{ // 鋭角三角形
			ans[2]++;
		}
		ans[0]++;
	}
}

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

typedef long long int ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<pair<int, int> > vii;
#define rrep(i, m, n) for(int (i)=(m); (i)<(n);  (i)++)
#define erep(i, m, n) for(int (i)=(m); (i)<=(n); (i)++)
#define  rep(i, n)    for(int (i)=0; (i)<(n);  (i)++)
#define rrev(i, m, n) for(int (i)=(n)-1; (i)>=(m); (i)--)
#define erev(i, m, n) for(int (i)=(n); (i)>=(m); (i)--)
#define  rev(i, n)    for(int (i)=(n)-1; (i)>=0; (i)--)
#define vrep(i, c)    for(__typeof((c).begin())i=(c).begin(); i!=(c).end(); i++)
#define  ALL(v)       (v).begin(), (v).end()
#define mp            make_pair
#define pb            push_back
template<class T, class S> inline bool minup(T& m, S x){ return m>(T)x ? (m=(T)x, true) : false; }
template<class T, class S> inline bool maxup(T& m, S x){ return m<(T)x ? (m=(T)x, true) : false; }

const int    INF = 1000000000;
const ll     MOD = 1000000007LL;
const double EPS = 1E-12;

template<typename T> ostream& operator <<(ostream& r, const vector<T> t){vrep(v,t)r<<*v<<(v+1==t.end()?"":" ");return r;}
template<typename T> ostream& operator <<(ostream& r, const pair<vector<T>, int> p){int n=p.second;minup(n,p.first.size());rep(i,n-1)r<<p.first[i]<<' ';r<<p.first[n-1];return r;}
template<typename T> ostream& operator <<(ostream& r, const pair<T*, int> p){int n=p.second-1;rep(i,n)r<<p.first[i]<<' ';return r<<p.first[n];}
template<typename T, size_t S> ostream& operator <<(ostream& r, const T (&a)[S]){rep(i,S-1)r<<a[i]<<' ';return r<<a[S-1];}


int l[3];
int res[4];

int main()
{
  while(cin >> l[0] >> l[1] >> l[2]){
    sort(l, l+3);
    if(l[0] + l[1] <= l[2]){
      cout << res << endl;
      break;
    }
    int s = l[0] * l[0] + l[1] * l[1];
    int t = l[2] * l[2];
    res[0] += 1;
    if(s == t) res[1] += 1;
    if(s  > t) res[2] += 1;
    if(s  < t) res[3] += 1;
  }

  return 0;
}

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

using namespace std;

// Checks the sides satisfies the triangle inequality.
inline bool Ok(int a, int b, int c) {
  return a < b + c && b < a + c && c < a + b;
}

int main() {
  size_t i = 0;
  size_t obtuse = 0;
  size_t acute = 0;
  size_t right = 0;

  int a, b, c;
  for (;;) {
    cin >> a >> b >> c;
    if (!Ok(a, b, c)) {
      printf("%lu %lu %lu %lu\n", i, right, acute, obtuse);
      break;
    }
    const auto m = max({a, b, c});
    int lhs = 0;
    int rhs = 0;
    if (m == a) {
      lhs = a * a;
      rhs = b * b + c * c;
    } else if (m == b) {
      lhs = b * b;
      rhs = a * a + c * c;
    } else { // m == c
      lhs = c * c;
      rhs = a * a + b * b;
    }
    if (lhs == rhs) {
      ++right;
    } else if (lhs < rhs) {
      ++acute;
    } else {
      ++obtuse;
    }

    ++i;
  }

  return 0;
}