Go: package main

import (
	"bufio"
	"os"
	"strconv"
	"strings"
	"fmt"
)

var scanner = bufio.NewScanner(os.Stdin)
var (
	dat = [5000][5]int{}
	m = [5]int{}
)

func main() {
	for scanner.Scan() {
		for i := range dat {
			for j := range dat[i] {
				dat[i][j] = 0
			}
		}
		for i := range m {
			m[i] = 0
		}
		n, _ := strconv.Atoi(scanner.Text())
		if n == 0 {
			break
		}
		count := 0
		for i := 0; i < n; i++ {
			scanner.Scan()
			buf := strings.Split(scanner.Text(), " ")
			d, _ := strconv.Atoi(buf[0])
			p, _ := strconv.Atoi(buf[1])
			q, _ := strconv.Atoi(buf[2])
			q--
			count += p
			if d == 2 {
				for j := 0; j < p; j++ {
					dat[m[q]][q] = 1
					ok := true
					for k := 0; k < 5; k++ {
						if dat[m[q]][k] == 0 {
							ok = false
						}
					}
					if ok {
						for k := 0; k < 5; k++ {
							dat[m[q]][k] = 0
							for l := m[q]; l < 4999; l++ {
								dat[l][k] = dat[l+1][k]
							}
							for l := 4999; l >= 0; l-- {
								if dat[l][k] != 0 {
									m[k] = l+1
									break
								}
								if l == 0 {
									m[k] = 0
								}
							}
						}
						count -= 5
					} else {
						m[q]++
					}
				}
			} else {
				h := 0
				for i := 0; i < p; i++ {
					h = max(h, m[i+q])
				}
				for i := 0; i < p; i++ {
					dat[h][i+q] = 1
				}
				for i := 0; i < p; i++ {
					m[i+q] = h+1
				}
				ok := true
				for j := 0; j < 5; j++ {
					if dat[h][j] == 0 {
						ok = false
					}
				}
				if ok {
					for j := 0; j < 5; j++ {
						dat[h][j] = 0
						for k := h; k < 4999; k++ {
							dat[k][j]=dat[k+1][j]
						}
						for k := 4999; k>= 0; k-- {
							if dat[k][j] != 0 {
								m[j]=k+1
								break
							}
							if k == 0 {
								m[j] = 0
							}
						}
					}
					count -= 5
				}
			}
		}
		fmt.Println(count)
	}
}

func max(a, b int) int {
	if a < b {
		return b
	}
	return a
}

C++: #include<bits/stdc++.h>
#define rep(i,n)for(int i=0;i<n;i++)
using namespace std;

int main() {
	int n;
	while (scanf("%d", &n), n) {
		deque<int>E[5];
		rep(i, n) {
			int d, p, q; scanf("%d%d%d", &d, &p, &q); q--;
			if (d == 1) {
				int Max = 0;
				rep(i, p)Max = max(Max, (int)E[q + i].size());
				rep(i, p) {
					int k = E[q + i].size();
					rep(j, Max - k)E[q + i].push_back(0);
					E[q + i].push_back(1);
				}
			}
			else {
				rep(i, p)E[q].push_back(1);
			}
			int Min = INT_MAX;
			rep(i, 5)Min = min(Min, (int)E[i].size());
			rep(i, Min) {
				bool ok = true;
				rep(j, 5)ok &= E[j][i];
				if(ok)rep(j, 5)E[j][i] = -1;
			}
			rep(i, 5)E[i].erase(remove(E[i].begin(), E[i].end(), -1), E[i].end());
		}
		int sum = 0;
		rep(i, 5)rep(j, E[i].size()) {
			if (E[i][j])sum++;
		}
		printf("%d\n", sum);
	}
}

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

const int WIDTH = 5;
const int BLOCK_LENGTH_MAX = 5;

class Tetoris
{
public:
	Tetoris( int num ) :
		m_numBlocks( num ),
		m_pField( NULL ),
		m_heightMax( 0 ),
		m_cellCount( 0 )
	{
		memset( m_heights, 0, sizeof(m_heights) );
		m_pField = new bool[ num * BLOCK_LENGTH_MAX * WIDTH ]();
		m_pFullLine = new bool[ num * BLOCK_LENGTH_MAX ]();
	}
	~Tetoris()
	{
		delete[] m_pField;
		delete[] m_pFullLine;
	}
	void dropBlock( int direction, int length, int position )
	{
		m_cellCount += length;
		int h = 0;
		if( direction == 1 ){
			for( int i = 0; i < length; ++i ){
				if( h < m_heights[ i + position ] ) h = m_heights[ i + position ];
			}
			for( int i = 0; i < length; ++i ){
				m_pField[ h * WIDTH + i + position ] = true;
				m_heights[ i + position ] = h + 1;
			}
			if( isFilled( h ) ){
				m_pFullLine[ h ] = true;
			}
			detectHeights( h );
		}else{
			h = m_heights[ position ];
			int up = 0;
			for( int i = 0; i < length; ++i ){
				while( m_pFullLine[ h + i + up ] ){
					++up;
				}
				m_pField[ ( h + i + up ) * WIDTH + position ] = true;
			}
			m_heights[ position ] += length + up;
			for( int i = 0; i < length + up; ++i ){
				if( isFilled( h + i ) ){
					m_pFullLine[ h + i ] = true;
				}
			}
			detectHeights( h + length + up );
		}
	}
	bool isFilled( int h )
	{
		for( int i = 0; i < WIDTH; ++i ){
			if( !m_pField[ h * WIDTH + i ] ){
				return false;
			}
		}
		return true;
	}
	void detectHeights( int h )
	{
		m_heightMax = 0;
		for( int i = 0; i < WIDTH; ++i ){
			int p = h;
			while( p >= 0 && ( !m_pField[ p * WIDTH + i ] || m_pFullLine[ p ] ) ){
				--p;
			}
			p += 1;
			while( p < m_numBlocks * BLOCK_LENGTH_MAX && m_pField[ p * WIDTH + i ] ){
				++p;
			}
			m_heights[ i ] = p;
			if( m_heightMax < m_heights[ i ] ){
				m_heightMax = m_heights[ i ];
			}
		}
	}
	int getResult()
	{
		int countFilledLine = 0;
		for( int i = 0; i < m_heightMax; ++i ){
			if( m_pFullLine[ i ] ) ++countFilledLine;
		}
		return m_cellCount - countFilledLine * WIDTH;
	}
	void outputState()
	{
		for( int i = m_heightMax - 1; i >= 0; --i ){
			for( int j = 0; j < WIDTH; ++j ){
				cout << ( m_pField[ i * WIDTH + j ] ? 'o' : '.' );
			}
			cout << endl;
		}
		cout << "heights:" << endl;
		for( int i = 0; i < WIDTH; ++i ){
			cout << m_heights[ i ] << ' ';
		}
		cout << endl;
		cout << "heightMax : " << m_heightMax << endl << endl;
	}

private:
	int m_numBlocks;
	bool* m_pField;
	int m_heightMax;
	int m_heights[ WIDTH ];
	bool* m_pFullLine;
	int m_cellCount;
};

int main()
{
	int n;

	while( cin >> n && n )
	{
		Tetoris t( n );
		for( int i = 0; i < n; ++i ){
			int d, l, p;
			cin >> d >> l >> p;
			t.dropBlock( d, l, p - 1 );
//			t.outputState();
		}
		cout << t.getResult() << endl;
	}

	return 0;
}

C++: #include <iostream>
#include <vector>
using namespace std;
#define HORIZONTAL 1
#define VERTICAL 2

int bit(int bits)
{
	int ret = 0;
	while(bits != 0)
	{
		ret += bits & 0x00000001;
		bits >>= 1;
	}
	return ret;
}

int main()
{
	int n, a, b, c, block, ret;
	while(cin >>n, n)
	{
		vector<int> data(5001, 0);
		data[5000] = 63; /* 63 = 0x11111 */
		ret = 0;
		
		while(n--)
		{
			cin >> a >> b >> c;
			c--;
			if(a==HORIZONTAL)
			{
				block = ((1<<b)-1) << c;
				for(int i=0; i<data.size()-1; i++)
				{
					if(data[i+1] & block)
					{
						data[i] += block;
						break;
					}
				}
			}
			else
			{
				block = 1 << c;
				for(int i=0; i<data.size()-1; i++)
				{
					if(data[i+1] & block)
					{
						for(int j=0; j<b; j++)
						{
							data[i-j] += block;
						}
						break;
					}
				}
			}

			vector<int>::iterator it = data.begin();
			while(it != data.end())
			{
				if((*it) == 31)
				{
					it = data.erase(it);
					it--;
				}
				it++;
			}
		}
		ret = 0;
		for(int i=0; i<data.size()-1; i++)
		{
			ret += bit(data[i]);
		}
		cout << ret << endl;
	}
}