01: #ifndef CBITPART_H
02: #define CBITPART_H
03: 
04: #include <iostream>
05: #include <fstream>
06: 
07: using namespace std;
08: 
09: typedef long long INT64;
10: 
11: const int X = 3, Y = 4, Z = 5;
12: const int BITS = X*Y*Z;
13: 
14: const INT64 zero = 0;
15: const INT64 one = 1;
16: const INT64 full = ~0;
17: 
18: 
19: class CBitPart
20: {
21:         private:
22:         static int B2X[BITS], B2Y[BITS], B2Z[BITS];
23:         static int XYZ[X][Y][Z];
24:         static bool init;
25: 
26:         public:
27:         INT64 bits;
28: 
29:         CBitPart()                                : bits(0) { if (!init) InitCoords(); }
30:         CBitPart(int b)                : bits(b) { if (!init) InitCoords(); }
31:         CBitPart(INT64 b)        : bits(b) { if (!init) InitCoords(); }
32: 
33:         void FromStream(ifstream& ifs);
34: 
35:         void InitCoords();
36: 
37:         void set                (const CBitPart& bp) { bits |= bp.bits; }
38:         void set                (int bit) { bits |= (one << bit); }
39:         void set                (int x, int y, int z) { set(XYZ[x][y][z]); }
40: 
41:         void set                (INT64& sbits, int bit) { sbits |= (one << bit); }
42: 
43:         void unset        (const CBitPart& bp) { bits ^= bp.bits; }
44: 
45:         void change        (int bit) { bits ^= (one << bit); }
46: 
47:         bool test                (const CBitPart& bp) const { return (bits & bp.bits); }
48:         bool is_set        (int bit) const { return (bits & (one << bit)); }
49: 
50:         CBitPart& operator= (INT64 _bits) { bits = _bits; return *this; }
51:         CBitPart& operator= (const CBitPart& bp) { bits = bp.bits; return *this; }
52: 
53:         bool operator== (INT64 _bits) const { return (bits == _bits); }
54:         bool operator== (const CBitPart& bp) const { return (bits == bp.bits); }
55:         bool operator!= (const CBitPart& bp) const { return (bits != bp.bits); }
56: 
57:         int NextSetBit                (int r) { while ((r < BITS) && !is_set(r)) ++r; return r; }
58:         int NextUnsetBit        (int r) { while (is_set(r)) ++r; return r; } // bit 60-63 = 0
59: 
60:         void Print() const { for (int i = 0; i < BITS; ++i) cout << (int)is_set(i); }
61: 
62:         int Density();
63: 
64:         void Swap                (int a, int b);
65: 
66:         int FirstHalf() { return (bits & (~(15 << 28))); }
67:         int SecondHalf() { return (bits >> 28); }
68: 
69:         CBitPart& Move                (int mx, int my, int mz);
70: 
71:         bool RotateLocalF90();
72:         bool RotateLocalT90();
73:         bool RotateLocalS90();
74:         bool RotateLocalF180();
75:         bool RotateLocalT180();
76:         bool RotateLocalS180();
77: 
78:         void RotateCubeF180();
79:         void RotateCubeT180();
80:         void RotateCubeS180();
81: 
82:         void ReverseBits();
83: 
84:         int GetX        (int bit) { return B2X[bit]; }
85:         int GetY        (int bit) { return B2Y[bit]; }
86:         int GetZ        (int bit) { return B2Z[bit]; }
87: 
88:         void GetMaxima(int& max_x, int& max_y, int& max_z);
89: 
90:         int Coord2Bit(int x, int y, int z) { return XYZ[x][y][z]; }
91: 
92: };
93: 
94: #endif