Create a gist now

Instantly share code, notes, and snippets.

#include <bits/stdc++.h>
using namespace std;
#define iota(i,n,b,s) for(int i=int(b);i!=int((b)+(s)*(n));i+=(s))
#define range(i,n,m) iota(i,(((n)>(m))?((n)-(m)+1):((m)-(n)+1)),(n),((n)>(m)?-1:1))
#define rep(i,n) iota(i,(n),0,1)
#define INF (1e9)
#define EPS (1e-9)
#define cons(a,b) (make_pair(a,b))
#define car(a) (a.first)
#define cdr(a) (a.second)
#define cadr(a) (car(cdr(a)))
#define cddr(a) (cdr(cdr(a)))
#define all(a) a.begin(), a.end()
#define trace(var) cerr<<">>> "<<#var<<" = "<<var<<endl;
typedef long long Integer;
typedef double Real;
template<class S, class T>
ostream& operator<<(ostream& os, pair<S,T> p) {
os << '(' << car(p) << ", " << cdr(p) << ')';
return os;
}
template<class T>
ostream& operator<<(ostream& os, vector<T> v) {
os << v[0];
for (int i=1, len=v.size(); i<len; ++i) os << ' ' << v[i];
return os;
}
int dx[] = { -1, 0, 1, 0 };
int dy[] = { 0, -1, 0, 1 };
int dice_line1[4] = {2,3,5,4};
int dice_line2[4] = {1,4,6,3};
int dice_line3[4] = {1,2,6,5};
struct Dice {
enum Face {
U, D, L, R, F, B
};
int get_right(int u, int f) {
if (u > 3) {
return 7 - get_right(7 - u, f);
}
int *line;
if (u == 1) line = dice_line1;
if (u == 2) line = dice_line2;
if (u == 3) line = dice_line3;
for (int i = 0; i < 4; ++i) {
if (line[i] == f) return line[-~i % 4];
}
assert(false);
}
int up; int down;
int left; int right;
int front; int back;
Dice (int u, int f) : up(u), front(f) {
assert(1 <= u && u <= 6);
assert(1 <= f && f <= 6);
assert(u != f);
assert(u + f != 7);
right = get_right(u, f);
left = 7 - right;
down = 7 - up;
back = 7 - front;
}
void roll(Face f) {
if (f == U) return;
if (f == D) return;
if (f == R) { // roll to right
int tmp = up;
up = left;
left = down;
down = right;
right = tmp;
} else if (f == L) {
int tmp = up;
up = right;
right = down;
down = left;
left = tmp;
} else if (f == F) {
int tmp = up;
up = back;
back = down;
down = front;
front = tmp;
} else if (f == B) {
int tmp = up;
up = front;
front = down;
down = back;
back = tmp;
}
assert(up + down == 7);
assert(left + right == 7);
assert(front + back == 7);
}
};
ostream& operator<<(ostream& os, Dice d) {
os << "(dice "
<< d.up << ' '
<< d.front << ' '
<< d.right << ' '
<< d.down << ' '
<< d.back << ' '
<< d.left << ")" << endl;
return os;
}
int main() {
for (int n; cin >> n, n; ) {
int cx[201][201];
int ux[201][201];
rep (i, 201) {
rep (j, 201) {
cx[i][j] = 0;
ux[i][j] = 0;
}
}
rep (i, n) {
//cerr << "# " << i << endl;
int u, f; cin >> u >> f;
Dice d(u, f);
int x = 100;
int y = 100;
for (;;) {
bool b = true;
for (int k=6; k>=4; --k) {
if (d.front == k && cx[x][y] > cx[x+1][y]) {
d.roll(d.F);
x++;
goto less;
}
else if (d.right == k && cx[x][y] > cx[x][y+1]) {
d.roll(d.R);
y++;
goto less;
}
else if (d.back == k && cx[x][y] > cx[x-1][y]) {
d.roll(d.B);
x--;
goto less;
}
else if (d.left == k && cx[x][y] > cx[x][y-1]) {
d.roll(d.L);
y--;
goto less;
}
}
goto more;
less:;
//cerr << "roll to " << cons(x-100, y-100) << endl;
}
more:;
//cerr << "at " << cons(x-100, y-100) << endl;
ux[x][y] = d.up;
cx[x][y]++;
}
vector<int> count(6, 0);
rep (i, 201) {
rep (j, 201) {
if (ux[i][j] > 0) count[ux[i][j] - 1]++;
}
}
for (int i=0; i<5; ++i) cout << count[i] << ' ';
cout << count[5] << endl;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment