Skip to content

Commit

Permalink
feat: improve performance (#11)
Browse files Browse the repository at this point in the history
* feat: improve performance

* feat: improve performance

* feat: improve perf

* feat: improve perf

* feat: improve perf

* feat: add test
  • Loading branch information
rei1024 authored Oct 22, 2024
1 parent d20ec46 commit c1cc425
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 32 deletions.
15 changes: 15 additions & 0 deletions src/lib/analyzeOscillator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,20 @@ describe("analyzeOscillator", () => {
[2, 1, 2],
[0, 2, 0],
]);

expect(
result.frequencyMap.data.slice(15, 18).map((row) => row.slice(31, 34))
).toEqual([
[0, 1, 0],
[1, 2, 1],
[0, 1, 0],
]);
expect(
result.heatMap.data.slice(15, 18).map((row) => row.slice(31, 34))
).toEqual([
[-1, 2, -1],
[2, 0, 2],
[-1, 2, -1],
]);
});
});
102 changes: 70 additions & 32 deletions src/lib/getMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,34 +55,77 @@ export function getMap({
.map(() => -1)
);

const historiesArray = histories.map((h) => h.getArray());
const firstBitGrid = histories[0];
if (firstBitGrid === undefined) {
throw new Error("no history");
}
const firstBitGridUint32Array = firstBitGrid.asInternalUint32Array();
const orUint32Array = or.asInternalUint32Array();

or.forEachAlive((x, y) => {
const states: (0 | 1)[] = [];
let heat = 0;
let prevCell = historiesArray[0]?.[y][x];
for (const h of historiesArray) {
const cell = h[y][x];
if (prevCell !== undefined && prevCell !== cell) {
heat++;
}
prevCell = cell;
states.push(cell);
if (cell !== 0) {
frequencyArray[y][x]++;
}
{
function getAlive(array: Uint32Array, offset: number, u: number): 0 | 1 {
const value = array[offset]!;
const alive = (value & (1 << (BITS_MINUS_1 - u))) !== 0 ? 1 : 0;
return alive;
}

if (
historiesArray.length !== 0 &&
historiesArray[0][y][x] !==
historiesArray[historiesArray.length - 1][y][x]
) {
heat++;
const width = firstBitGrid.getWidth32();
const height = firstBitGrid.getHeight();
const BITS = 32;
const BITS_MINUS_1 = BITS - 1;
for (let i = 0; i < height; i++) {
const rowIndex = i * width;
for (let j = 0; j < width; j++) {
const offset = rowIndex + j;
// skip if empty
if (orUint32Array[offset] === 0) {
continue;
}
const BITS_J = j * BITS;
for (let u = 0; u < BITS; u++) {
// skip if dead
if (getAlive(orUint32Array, offset, u) === 0) {
continue;
}

const x = BITS_J + u;
const y = i;

const states: (0 | 1)[] = [];
let heat = 0;
const firstCell = getAlive(firstBitGridUint32Array, offset, u);
let prevCell = firstCell;
let frequency = 0;
for (const h of histories) {
const array = h.asInternalUint32Array();
const cell = getAlive(array, offset, u);
if (prevCell !== undefined && prevCell !== cell) {
heat++;
}
prevCell = cell;
states.push(cell);
if (cell !== 0) {
frequency++;
}
}

if (
firstCell !==
getAlive(
histories[histories.length - 1]!.asInternalUint32Array(),
offset,
u
)
) {
heat++;
}
heatArray[y][x] = heat;
periodArray[y][x] = findPeriod(states);
frequencyArray[y][x] = frequency;
}
}
}
heatArray[y][x] = heat;
periodArray[y][x] = findPeriod(states);
});
}

const periodCountMap = getCountMap(periodArray);
periodCountMap.delete(0);
Expand All @@ -96,27 +139,22 @@ export function getMap({
return {
periodMap: {
data: periodArray,
list: mapUnique(periodArray).filter((x) => x !== 0),
list: [...periodCountMap.keys()].sort((a, b) => a - b),
countMap: periodCountMap,
},
frequencyMap: {
data: frequencyArray,
list: mapUnique(frequencyArray).filter((x) => x !== 0),
list: [...frequencyCountMap.keys()].sort((a, b) => a - b),
countMap: frequencyCountMap,
},
heatMap: {
data: heatArray,
list: mapUnique(heatArray).filter((x) => x !== -1),
list: [...heatCountMap.keys()].sort((a, b) => a - b),
countMap: heatCountMap,
},
};
}

function mapUnique(map: number[][]): number[] {
const set = new Set(map.flat());
return [...set].sort((a, b) => a - b);
}

function getCountMap(map: number[][]): Map<number, number> {
const countMap = new Map<number, number>();
for (const row of map) {
Expand Down

0 comments on commit c1cc425

Please sign in to comment.