diff --git a/index.html b/index.html
index 683ebb38..eef78ebd 100644
--- a/index.html
+++ b/index.html
@@ -6262,7 +6262,7 @@
-
+
@@ -6280,7 +6280,7 @@
-
+
diff --git a/modules/burgs-and-states.js b/modules/burgs-and-states.js
index f3f5164e..449e48a0 100644
--- a/modules/burgs-and-states.js
+++ b/modules/burgs-and-states.js
@@ -496,25 +496,20 @@ window.BurgsAndStates = (function () {
paths.push([s.i, relaxed]);
function getHull(start, state, maxLake) {
- const queue = [start],
- hull = new Set();
+ const queue = [start];
+ const hull = new Set();
while (queue.length) {
const q = queue.pop();
- const nQ = cells.c[q].filter(c => cells.state[c] === state);
+ const sameStateNeibs = cells.c[q].filter(c => cells.state[c] === state);
cells.c[q].forEach(function (c, d) {
const passableLake = features[cells.f[c]].type === "lake" && features[cells.f[c]].cells < maxLake;
- if (cells.b[c] || (cells.state[c] !== state && !passableLake)) {
- hull.add(cells.v[q][d]);
- return;
- }
- const nC = cells.c[c].filter(n => cells.state[n] === state);
- const intersected = common(nQ, nC).length;
- if (hull.size > 20 && !intersected && !passableLake) {
- hull.add(cells.v[q][d]);
- return;
- }
+ if (cells.b[c] || (cells.state[c] !== state && !passableLake)) return hull.add(cells.v[q][d]);
+
+ const hasCoadjacentSameStateCells = sameStateNeibs.some(neib => cells.c[c].includes(neib));
+ if (hull.size > 20 && !hasCoadjacentSameStateCells && !passableLake) return hull.add(cells.v[q][d]);
+
if (used[c]) return;
used[c] = 1;
queue.push(c);
diff --git a/utils/arrayUtils.js b/utils/arrayUtils.js
index b59d48e3..a7f0c35f 100644
--- a/utils/arrayUtils.js
+++ b/utils/arrayUtils.js
@@ -6,45 +6,39 @@ function last(array) {
return array[array.length - 1];
}
-// return array of values common for both array a and array b
-function common(a, b) {
- const setB = new Set(b);
- return [...new Set(a)].filter(a => setB.has(a));
-}
-
function unique(array) {
return [...new Set(array)];
}
// deep copy for Arrays (and other objects)
function deepCopy(obj) {
- const id = x=>x;
+ const id = x => x;
const dcTArray = a => a.map(id);
- const dcObject = x => Object.fromEntries(Object.entries(x).map(([k,d])=>[k,dcAny(d)]));
- const dcAny = x => x instanceof Object ? (cf.get(x.constructor)||id)(x) : x;
+ const dcObject = x => Object.fromEntries(Object.entries(x).map(([k, d]) => [k, dcAny(d)]));
+ const dcAny = x => (x instanceof Object ? (cf.get(x.constructor) || id)(x) : x);
// don't map keys, probably this is what we would expect
- const dcMapCore = m => [...m.entries()].map(([k,v])=>[k, dcAny(v)]);
+ const dcMapCore = m => [...m.entries()].map(([k, v]) => [k, dcAny(v)]);
const cf = new Map([
- [Int8Array, dcTArray],
- [Uint8Array, dcTArray],
- [Uint8ClampedArray, dcTArray],
- [Int16Array, dcTArray],
- [Uint16Array, dcTArray],
- [Int32Array, dcTArray],
- [Uint32Array, dcTArray],
- [Float32Array, dcTArray],
- [Float64Array, dcTArray],
- [BigInt64Array, dcTArray],
- [BigUint64Array, dcTArray],
- [Map, m => new Map(dcMapCore(m))],
- [WeakMap, m => new WeakMap(dcMapCore(m))],
- [Array, a => a.map(dcAny)],
- [Set, s => [...s.values()].map(dcAny)],
- [Date, d => new Date(d.getTime())],
- [Object, dcObject],
- // other types will be referenced
- // ... extend here to implement their custom deep copy
+ [Int8Array, dcTArray],
+ [Uint8Array, dcTArray],
+ [Uint8ClampedArray, dcTArray],
+ [Int16Array, dcTArray],
+ [Uint16Array, dcTArray],
+ [Int32Array, dcTArray],
+ [Uint32Array, dcTArray],
+ [Float32Array, dcTArray],
+ [Float64Array, dcTArray],
+ [BigInt64Array, dcTArray],
+ [BigUint64Array, dcTArray],
+ [Map, m => new Map(dcMapCore(m))],
+ [WeakMap, m => new WeakMap(dcMapCore(m))],
+ [Array, a => a.map(dcAny)],
+ [Set, s => [...s.values()].map(dcAny)],
+ [Date, d => new Date(d.getTime())],
+ [Object, dcObject]
+ // other types will be referenced
+ // ... extend here to implement their custom deep copy
]);
return dcAny(obj);