mirror of
https://github.com/captbaritone/webamp.git
synced 2026-07-19 09:33:47 +00:00
Start sketching out new resize algo
This commit is contained in:
parent
8a13222aa0
commit
797aeffa17
3 changed files with 374 additions and 0 deletions
|
|
@ -0,0 +1,157 @@
|
|||
=== doubles a simple box
|
||||
11111111
|
||||
11111111
|
||||
11111111
|
||||
---
|
||||
1111111111111111
|
||||
1111111111111111
|
||||
1111111111111111
|
||||
1111111111111111
|
||||
1111111111111111
|
||||
1111111111111111
|
||||
=== moves adjacent boxes
|
||||
11111111
|
||||
11111111
|
||||
11111111
|
||||
22222222
|
||||
22222222
|
||||
22222222
|
||||
---
|
||||
1111111111111111
|
||||
1111111111111111
|
||||
1111111111111111
|
||||
1111111111111111
|
||||
1111111111111111
|
||||
1111111111111111
|
||||
2222222222222222
|
||||
2222222222222222
|
||||
2222222222222222
|
||||
2222222222222222
|
||||
2222222222222222
|
||||
2222222222222222
|
||||
=== moves the bottom adjacent box independent of order
|
||||
22222222
|
||||
22222222
|
||||
22222222
|
||||
11111111
|
||||
11111111
|
||||
11111111
|
||||
---
|
||||
2222222222222222
|
||||
2222222222222222
|
||||
2222222222222222
|
||||
2222222222222222
|
||||
2222222222222222
|
||||
2222222222222222
|
||||
1111111111111111
|
||||
1111111111111111
|
||||
1111111111111111
|
||||
1111111111111111
|
||||
1111111111111111
|
||||
1111111111111111
|
||||
=== moves the bottom adjacent box only in the y axis
|
||||
22222222
|
||||
22222222
|
||||
22222222
|
||||
11111111
|
||||
11111111
|
||||
11111111
|
||||
---
|
||||
2222222222222222
|
||||
2222222222222222
|
||||
2222222222222222
|
||||
2222222222222222
|
||||
2222222222222222
|
||||
2222222222222222
|
||||
1111111111111111
|
||||
1111111111111111
|
||||
1111111111111111
|
||||
1111111111111111
|
||||
1111111111111111
|
||||
1111111111111111
|
||||
=== moves the right adjacent box only in the y axis
|
||||
22222222
|
||||
2222222211111111
|
||||
2222222211111111
|
||||
11111111
|
||||
---
|
||||
2222222222222222
|
||||
22222222222222221111111111111111
|
||||
22222222222222221111111111111111
|
||||
22222222222222221111111111111111
|
||||
22222222222222221111111111111111
|
||||
22222222222222221111111111111111
|
||||
1111111111111111
|
||||
=== does not move nearly adjacent boxes
|
||||
11111111
|
||||
11111111
|
||||
11111111
|
||||
|
||||
22222222
|
||||
22222222
|
||||
22222222
|
||||
---
|
||||
1111111111111111
|
||||
1111111111111111
|
||||
1111111111111111
|
||||
1111111111111111
|
||||
3333333333333333
|
||||
3333333333333333
|
||||
2222222222222222
|
||||
2222222222222222
|
||||
2222222222222222
|
||||
2222222222222222
|
||||
=== does not push kitty corner neighbors
|
||||
11111111
|
||||
11111111
|
||||
11111111
|
||||
22222222
|
||||
22222222
|
||||
22222222
|
||||
---
|
||||
1111111111111111
|
||||
1111111111111111
|
||||
1111111111111111
|
||||
1111111133333333
|
||||
1111111133333333
|
||||
1111111133333333
|
||||
=== moves a box with two adjacent neighbors down and to the right
|
||||
11111111
|
||||
11111111
|
||||
2233333311
|
||||
2233333311
|
||||
2222222244444444
|
||||
2222222244444444
|
||||
44444444
|
||||
44444444
|
||||
---
|
||||
1111111111111111
|
||||
1111111111111111
|
||||
223333333333333311
|
||||
223333333333333311
|
||||
223333333333333311
|
||||
223333333333333311
|
||||
223333333333333311
|
||||
223333333333333311
|
||||
22222222222222224444444444444444
|
||||
22222222222222224444444444444444
|
||||
4444444444444444
|
||||
4444444444444444
|
||||
4444444444444444
|
||||
4444444444444444
|
||||
4444444444444444
|
||||
4444444444444444
|
||||
=== wat
|
||||
2222
|
||||
2222
|
||||
11114444
|
||||
11114444
|
||||
---
|
||||
22222222
|
||||
22222222
|
||||
111133332222
|
||||
111133332222
|
||||
1111111144444444
|
||||
1111111144444444
|
||||
44444444
|
||||
44444444
|
||||
18
experiments/resizeAlgorithm/resizeUtils.js
Normal file
18
experiments/resizeAlgorithm/resizeUtils.js
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
export function double(boxes) {
|
||||
const doubledBoxes = new Map();
|
||||
// Find the top/left most box
|
||||
// Update the width/height of the first box.
|
||||
// Find any boxes that are touching the bottom of that box
|
||||
// Move those boxes down
|
||||
// Find any boxes that are touching the right of that box
|
||||
// Move those boxes right
|
||||
// Repeat for boxes that are touching
|
||||
// Resize any remaining boxes
|
||||
for (const [key, box] of boxes) {
|
||||
const width = box.width * 2;
|
||||
const height = box.height * 2;
|
||||
const top = box.top * 2;
|
||||
doubledBoxes.set(key, { ...box, top, width, height });
|
||||
}
|
||||
return doubledBoxes;
|
||||
}
|
||||
199
experiments/resizeAlgorithm/resizeUtils.test.js
Normal file
199
experiments/resizeAlgorithm/resizeUtils.test.js
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
import fs from "fs";
|
||||
|
||||
import { double } from "./resizeUtils";
|
||||
|
||||
function compositeContains(composite, value) {
|
||||
return !!(composite & value);
|
||||
}
|
||||
|
||||
const decomposeValues = composite =>
|
||||
[1, 2, 4].filter(value => compositeContains(composite, value));
|
||||
|
||||
function matrixFromMap(map) {
|
||||
return map
|
||||
.trim()
|
||||
.split("\n")
|
||||
.map(row => row.trim().split(""));
|
||||
}
|
||||
|
||||
function walkMatrix(matrix, cb) {
|
||||
matrix.forEach((row, y) => {
|
||||
row.forEach((value, x) => {
|
||||
cb(x, y, value);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function boxesFromMatrix(matrix) {
|
||||
const boxes = new Map();
|
||||
walkMatrix(matrix, (x, y, composite) => {
|
||||
const values = decomposeValues(composite);
|
||||
values.forEach(value => {
|
||||
if (!boxes.has(value)) {
|
||||
// Initialize the box
|
||||
boxes.set(value, { top: y, left: x, width: 1, height: 1 });
|
||||
} else {
|
||||
const box = boxes.get(value);
|
||||
if (box.top === y && x - box.left === box.width) {
|
||||
// The top side is still growing.
|
||||
box.width++;
|
||||
} else if (box.left === x && y - box.top === box.height) {
|
||||
// The left side is still growing.
|
||||
box.height++;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
return boxes;
|
||||
}
|
||||
|
||||
function parseBoxes(map) {
|
||||
return boxesFromMatrix(matrixFromMap(map));
|
||||
}
|
||||
|
||||
function boxContains(box, pos) {
|
||||
if (
|
||||
pos.x >= box.left &&
|
||||
pos.x < box.left + box.width &&
|
||||
pos.y >= box.top &&
|
||||
pos.y < box.top + box.height
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function matrixFromBoxes(boxes) {
|
||||
let width = 0;
|
||||
let height = 0;
|
||||
boxes.forEach(box => {
|
||||
width = Math.max(width, box.left + box.width);
|
||||
height = Math.max(height, box.top + box.height);
|
||||
});
|
||||
const matrix = [];
|
||||
for (let y = 0; y < height; y++) {
|
||||
if (!matrix[y]) {
|
||||
matrix[y] = [];
|
||||
}
|
||||
for (let x = 0; x < width; x++) {
|
||||
let cellNumber = 0;
|
||||
boxes.forEach((box, boxNumber) => {
|
||||
if (boxContains(box, { x, y })) {
|
||||
cellNumber += Number(boxNumber);
|
||||
}
|
||||
});
|
||||
matrix[y].push(String(cellNumber || " "));
|
||||
}
|
||||
}
|
||||
return matrix;
|
||||
}
|
||||
|
||||
function mapFromMatrix(matrix) {
|
||||
return matrix.map(row => row.join("")).join("\n");
|
||||
}
|
||||
|
||||
function assertionsFromTxt(txtPath) {
|
||||
return fs
|
||||
.readFileSync(txtPath, "utf8")
|
||||
.split(/\=\=\= /)
|
||||
.filter(Boolean)
|
||||
.map(assertionText => {
|
||||
const lines = assertionText.split("\n");
|
||||
const [message, ...bodyLines] = lines;
|
||||
let [input, output] = bodyLines.join("\n").split("---\n");
|
||||
input = input.trim();
|
||||
output = output.trim();
|
||||
return { message, input, output };
|
||||
});
|
||||
}
|
||||
|
||||
xdescribe("integration", () => {
|
||||
assertionsFromTxt(
|
||||
"./js/__fixtures__/resizeDoubleTestCases.txt"
|
||||
).forEach(({ input, output, message }) => {
|
||||
it(message, () => {
|
||||
const matrix = matrixFromMap(input);
|
||||
const boxes = boxesFromMatrix(matrix);
|
||||
const doubledBoxes = double(boxes);
|
||||
const derivedMatrix = matrixFromBoxes(doubledBoxes);
|
||||
const derivedMap = mapFromMatrix(derivedMatrix);
|
||||
expect(derivedMap).toEqual(output);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("matrixFromBoxes", () => {
|
||||
it("can make a matrix from a box", () => {
|
||||
const boxes = new Map([["1", { top: 0, left: 0, width: 4, height: 4 }]]);
|
||||
expect(matrixFromBoxes(boxes)).toEqual(
|
||||
matrixFromMap(`
|
||||
1111
|
||||
1111
|
||||
1111
|
||||
1111
|
||||
`)
|
||||
);
|
||||
});
|
||||
it("can make a matrix from two boxes", () => {
|
||||
const boxes = new Map([
|
||||
["1", { top: 0, left: 0, width: 4, height: 4 }],
|
||||
["2", { top: 1, left: 1, width: 2, height: 2 }]
|
||||
]);
|
||||
expect(matrixFromBoxes(boxes)).toEqual(
|
||||
matrixFromMap(`
|
||||
1111
|
||||
1331
|
||||
1331
|
||||
1111
|
||||
`)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("parseBoxes", () => {
|
||||
it("parses a box", () => {
|
||||
const boxes = parseBoxes(`
|
||||
1111
|
||||
1111
|
||||
1111
|
||||
1111
|
||||
`);
|
||||
expect(boxes.get(1)).toEqual({ top: 0, left: 0, width: 4, height: 4 });
|
||||
});
|
||||
it("parses a smaller box", () => {
|
||||
const boxes = parseBoxes(`
|
||||
11
|
||||
11
|
||||
`);
|
||||
expect(boxes.get(1)).toEqual({ top: 0, left: 0, width: 2, height: 2 });
|
||||
});
|
||||
it("parses nested boxes", () => {
|
||||
const boxes = parseBoxes(`
|
||||
1111
|
||||
1331
|
||||
1331
|
||||
1111
|
||||
`);
|
||||
expect(boxes.get(1)).toEqual({ top: 0, left: 0, width: 4, height: 4 });
|
||||
expect(boxes.get(2)).toEqual({ top: 1, left: 1, width: 2, height: 2 });
|
||||
});
|
||||
it("parses overlapping boxes", () => {
|
||||
const boxes = parseBoxes(`
|
||||
110
|
||||
132
|
||||
022
|
||||
`);
|
||||
expect(boxes.get(1)).toEqual({ top: 0, left: 0, width: 2, height: 2 });
|
||||
expect(boxes.get(2)).toEqual({ top: 1, left: 1, width: 2, height: 2 });
|
||||
});
|
||||
it("parses three overlapping boxes", () => {
|
||||
const boxes = parseBoxes(`
|
||||
1154
|
||||
1374
|
||||
0220
|
||||
`);
|
||||
expect(boxes.get(1)).toEqual({ top: 0, left: 0, width: 3, height: 2 });
|
||||
expect(boxes.get(2)).toEqual({ top: 1, left: 1, width: 2, height: 2 });
|
||||
expect(boxes.get(4)).toEqual({ top: 0, left: 2, width: 2, height: 2 });
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue