Hilbert curve: Difference between revisions

Content added Content deleted
(→‎JavaScript Functional: Updated primitives, tidied.)
Line 1,803: Line 1,803:
// hilbertTree :: Dict Char [Char] -> Int -> Tree Char
// hilbertTree :: Dict Char [Char] -> Int -> Tree Char
const hilbertTree = rule => n => {
const hilbertTree = rule => n => {
const go = tree =>
const go = tree => {
Node(tree.root)(
const xs = tree.nest;

Boolean(tree.nest.length) ? (
tree.nest.map(go)
return Node(tree.root)(
Boolean(xs.length) ? (
xs.map(go)
) : rule[tree.root].map(
) : rule[tree.root].map(
x => Node(x)([])
flip(Node)([])
)
)
);
);
};
const seed = Node("a")([]);
const seed = Node("a")([]);


return 0 < n ? (
return Boolean(n) ? (
take(n)(iterate(go)(seed)).slice(-1)[0]
take(n)(iterate(go)(seed)).slice(-1)[0]
) : seed;
) : seed;
Line 1,833: Line 1,836:


return Boolean(t.nest.length) ? (
return Boolean(t.nest.length) ? (
zipWith(go(r))(
zipWith(go(r))(centres)(t.nest)
centres
)(t.nest)
.flat()
.flat()
) : centres;
) : centres;
Line 1,843: Line 1,844:
return go(d)([d, d], tree);
return go(d)([d, d], tree);
};
};



// svgFromPoints :: Int -> [(Int, Int)] -> String
// svgFromPoints :: Int -> [(Int, Int)] -> String
Line 1,856: Line 1,858:


// -------------------- TEST ---------------------
// -------------------- TEST ---------------------
const main = () => {
const main = () =>
// rule :: Dict Char [Char]
hilbertCurve({
const rule = {
a: ["d", "a", "a", "b"],
b: ["c", "b", "b", "a"],
c: ["b", "c", "c", "d"],
d: ["a", "d", "d", "c"]
};

// vectors :: Dict Char [(Int, Int)]
const vectors = ({
"a": [
"a": [
[-1, 1],
[-1, 1],
Line 1,891: Line 1,884:
[-1, -1]
[-1, -1]
]
]
});
})({
a: ["d", "a", "a", "b"],

b: ["c", "b", "b", "a"],
return hilbertCurve(vectors)(rule)(6);
c: ["b", "c", "c", "d"],
};
d: ["a", "d", "d", "c"]
})(6);




Line 1,909: Line 1,904:
nest: xs || []
nest: xs || []
});
});


// flip :: (a -> b -> c) -> b -> a -> c
const flip = op =>
// The binary function op with
// its arguments reversed.
1 !== op.length ? (
(a, b) => op(b, a)
) : (a => b => op(b)(a));




Line 1,924: Line 1,928:
};
};



// Returns Infinity over objects without finite length.
// This enables zip and zipWith to choose the shorter
// argument when one is non-finite, like cycle, repeat etc


// length :: [a] -> Int
// length :: [a] -> Int