Skip to content

Commit 320d10e

Browse files
committed
half the memory for a point set
1 parent f310518 commit 320d10e

File tree

6 files changed

+83
-40
lines changed

6 files changed

+83
-40
lines changed

src/main/java/com/bernd/game/PointQueue.java

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,62 @@
11
package com.bernd.game;
22

3+
import static com.bernd.util.Util.divideUp;
4+
35
final class PointQueue {
46

7+
private static final int LO = 0xffff;
8+
private static final int HI = 0xffff0000;
9+
10+
private final int capacity;
11+
private final int dim;
12+
513
private int write;
614
private int read;
7-
private final int dim;
815
private final int[] buffer;
916

10-
private PointQueue(int dim, int[] buffer) {
17+
private PointQueue(
18+
int capacity,
19+
int dim,
20+
int[] buffer) {
21+
this.capacity = capacity;
1122
this.dim = dim;
1223
this.buffer = buffer;
1324
}
1425

1526
static PointQueue create(int dim) {
16-
// Assumption: All algorithms proceed from the starting point outward in a diamond shape.
17-
// The circumference of the diamond shape is not greater than 2 * dim.
18-
return new PointQueue(dim, new int[2 * dim + 1]);
27+
// Assumption 1: All algorithms proceed from the starting point outward in a diamond shape.
28+
// Assumption 2: The circumference of the diamond shape is not greater than 2 * dim + 1.
29+
int capacity = 2 * dim + 1;
30+
return new PointQueue(capacity, dim, new int[divideUp(capacity, 2)]);
1931
}
2032

2133
void offer(int x, int y) {
22-
buffer[write] = dim * y + x;
23-
write = (write + 1) % buffer.length;
34+
int ptId = dim * y + x;
35+
set(ptId);
36+
write = (write + 1) % capacity;
2437
if (write == read) {
2538
throw new RuntimeException("buffer overflow");
2639
}
2740
}
2841

2942
int poll() {
30-
int result = buffer[read];
31-
read = (read + 1) % buffer.length;
32-
return result;
43+
int ptId = get();
44+
read = (read + 1) % capacity;
45+
return ptId;
46+
}
47+
48+
private int get() {
49+
int code = buffer[read / 2];
50+
return read % 2 == 0 ? code & LO : (code >> 16);
51+
}
52+
53+
private void set(int ptId) {
54+
int pos = write / 2;
55+
if (write % 2 == 0) {
56+
buffer[pos] = (buffer[pos] & HI) | ptId;
57+
} else {
58+
buffer[pos] = (ptId << 16) | (buffer[pos] & LO);
59+
}
3360
}
3461

3562
boolean isEmpty() {
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.bernd.game;
22

3+
import static com.bernd.util.Util.divideUp;
4+
35
final class PointSet {
46

57
private final int dim;
@@ -11,22 +13,20 @@ private PointSet(int dim, int[] points) {
1113
}
1214

1315
static PointSet create(int dim) {
14-
return new PointSet(dim, new int[1 + ((dim * dim) / 16)]);
16+
return new PointSet(dim, new int[divideUp(dim * dim, 0x11)]);
1517
}
1618

1719
void add(int x, int y) {
1820
int ptId = y * dim + x;
19-
int base = ptId / 16;
20-
int off = ptId % 16;
21-
int shift = 1 << off;
22-
points[base] = points[base] | shift;
21+
int pos = ptId >> 5;
22+
int test = 1 << (ptId & 0x1f);
23+
points[pos] = points[pos] | test;
2324
}
2425

2526
boolean has(int x, int y) {
2627
int ptId = y * dim + x;
27-
int base = ptId / 16;
28-
int off = ptId % 16;
29-
int shift = 1 << off;
30-
return (points[base] & shift) != 0;
28+
int pos = ptId >> 5;
29+
int test = 1 << (ptId & 0x1f);
30+
return (points[pos] & test) != 0;
3131
}
3232
}

src/main/java/com/bernd/util/BoardUpdate.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66

77
public class BoardUpdate implements Function<int[][], int[][]> {
88

9-
private static final int SHIFT = 256; // > max(B, W)
9+
private static final int LO = 0xffff;
10+
1011
private int pos;
1112
private final int dim;
1213
private int[] updates;
@@ -38,7 +39,7 @@ public void add(int x, int y, int value) {
3839
updates = Arrays.copyOf(updates, dim * dim);
3940
}
4041
int ptId = dim * y + x;
41-
updates[pos] = SHIFT * ptId + value;
42+
updates[pos] = (value << 16) | ptId;
4243
pos++;
4344
}
4445

@@ -52,13 +53,13 @@ public void add(Point point, int value) {
5253

5354
public int x(int i) {
5455
int code = updates[i];
55-
int ptId = code / SHIFT;
56+
int ptId = code & LO;
5657
return ptId % dim;
5758
}
5859

5960
public int y(int i) {
6061
int code = updates[i];
61-
int ptId = code / SHIFT;
62+
int ptId = code & LO;
6263
return ptId / dim;
6364
}
6465

@@ -71,8 +72,8 @@ public int[][] apply(int[][] board) {
7172
int[][] result = Arrays.copyOf(board, board.length);
7273
for (int i = 0; i < pos; i++) {
7374
int code = updates[i];
74-
int value = code % SHIFT;
75-
int ptId = code / SHIFT;
75+
int value = code >> 16;
76+
int ptId = code & LO;
7677
int x = ptId % dim;
7778
int y = ptId / dim;
7879
if (result[y] == board[y]) {

src/main/java/com/bernd/util/Util.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,8 @@ public static String boardToString(int[][] board) {
1616
sb.append("};");
1717
return sb.toString();
1818
}
19+
20+
public static int divideUp(int i, int div) {
21+
return i % div == 0 ? i / div : (i / div) + 1;
22+
}
1923
}

src/test/java/com/bernd/game/CountTest.java

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010

1111
class CountTest {
1212

13-
private static final int C = B + TERRITORY;
14-
private static final int X = W + TERRITORY;
13+
private static final int b = B + TERRITORY;
14+
private static final int w = W + TERRITORY;
1515

1616
@Test
1717
void testRemoveOneStone() {
@@ -39,11 +39,11 @@ void testCountBlackTerritory() {
3939
};
4040
int[][] result = Count.count(position);
4141
assertArrayEquals(new int[][]{
42-
new int[]{C, C, C, C, C},
43-
new int[]{C, B, B, B, C},
44-
new int[]{C, B, C, B, C},
45-
new int[]{C, B, B, B, C},
46-
new int[]{C, C, C, C, C},
42+
new int[]{b, b, b, b, b},
43+
new int[]{b, B, B, B, b},
44+
new int[]{b, B, b, B, b},
45+
new int[]{b, B, B, B, b},
46+
new int[]{b, b, b, b, b},
4747
}, result);
4848
}
4949

@@ -57,10 +57,10 @@ void testCountFull() {
5757
};
5858
int[][] result = Count.count(position);
5959
assertArrayEquals(new int[][]{
60-
new int[]{C, C, C, C},
60+
new int[]{b, b, b, b},
6161
new int[]{B, B, B, B},
6262
new int[]{W, W, W, W},
63-
new int[]{X, X, X, X},
63+
new int[]{w, w, w, w},
6464
}, result);
6565
}
6666

@@ -77,7 +77,7 @@ void testCountPartial() {
7777
new int[]{0, W, 0, 0},
7878
new int[]{B, B, B, B},
7979
new int[]{W, W, W, W},
80-
new int[]{X, X, X, X},
80+
new int[]{w, w, w, w},
8181
}, result);
8282
}
8383

@@ -95,12 +95,12 @@ void testMarkBig() {
9595
new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0},
9696
};
9797
int[][] acc = Count.createAcc(position);
98-
acc[0] = new int[]{B, C, B, B, B, W, -1, -1, -1};
98+
acc[0] = new int[]{B, b, B, B, B, W, -1, -1, -1};
9999
acc[1] = new int[]{B, B, B, W, W, B, -1, -1, -1};
100100
acc[2] = new int[]{W, W, W, W, -1, -1, -1, -1, -1};
101101
Count.markStonesAround(acc, position, 6, 0);
102102
assertArrayEquals(new int[][]{
103-
new int[]{B, C, B, B, B, W, 0, 0, 0},
103+
new int[]{B, b, B, B, B, W, 0, 0, 0},
104104
new int[]{B, B, B, W, W, B, 0, 0, 0},
105105
new int[]{W, W, W, W, 0, 0, 0, 0, 0},
106106
new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0},
@@ -128,7 +128,7 @@ void testMarkSmall() {
128128
int[][] acc = Count.createAcc(position);
129129
acc[0][0] = B;
130130
Count.markStonesAround(acc, position, 1, 0);
131-
assertArrayEquals(new int[]{B, C, -1, -1, -1, -1, -1, -1, -1}, acc[0]);
131+
assertArrayEquals(new int[]{B, b, -1, -1, -1, -1, -1, -1, -1}, acc[0]);
132132
}
133133

134134
@Test
@@ -146,7 +146,7 @@ void testCountLargeArea() {
146146
};
147147
int[][] result = Count.count(position);
148148
assertArrayEquals(new int[][]{
149-
new int[]{B, C, B, B, B, W, 0, 0, 0},
149+
new int[]{B, b, B, B, B, W, 0, 0, 0},
150150
new int[]{B, B, B, W, W, B, 0, 0, 0},
151151
new int[]{W, W, W, W, 0, 0, 0, 0, 0},
152152
new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0},

src/test/java/com/bernd/game/PointSetTest.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
class PointSetTest {
99

1010
@Test
11-
void add() {
11+
void testSmall() {
1212
PointSet pointSet = PointSet.create(2);
1313
pointSet.add(0, 1);
1414
pointSet.add(1, 1);
@@ -17,4 +17,15 @@ void add() {
1717
assertFalse(pointSet.has(1, 0));
1818
assertTrue(pointSet.has(1, 1));
1919
}
20+
21+
@Test
22+
void testBig() {
23+
PointSet pointSet = PointSet.create(19);
24+
pointSet.add(10, 10);
25+
assertFalse(pointSet.has(9, 10));
26+
assertFalse(pointSet.has(10, 9));
27+
assertTrue(pointSet.has(10, 10));
28+
assertFalse(pointSet.has(10, 11));
29+
assertFalse(pointSet.has(11, 10));
30+
}
2031
}

0 commit comments

Comments
 (0)