Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
54
Task/Hilbert-curve/JavaScript/hilbert-curve-1.js
Normal file
54
Task/Hilbert-curve/JavaScript/hilbert-curve-1.js
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
const hilbert = (width, spacing, points) => (x, y, lg, i1, i2, f) => {
|
||||
if (lg === 1) {
|
||||
const px = (width - x) * spacing;
|
||||
const py = (width - y) * spacing;
|
||||
points.push(px, py);
|
||||
return;
|
||||
}
|
||||
lg >>= 1;
|
||||
f(x + i1 * lg, y + i1 * lg, lg, i1, 1 - i2, f);
|
||||
f(x + i2 * lg, y + (1 - i2) * lg, lg, i1, i2, f);
|
||||
f(x + (1 - i1) * lg, y + (1 - i1) * lg, lg, i1, i2, f);
|
||||
f(x + (1 - i2) * lg, y + i2 * lg, lg, 1 - i1, i2, f);
|
||||
return points;
|
||||
};
|
||||
|
||||
/**
|
||||
* Draw a hilbert curve of the given order.
|
||||
* Outputs a svg string. Save the string as a .svg file and open in a browser.
|
||||
* @param {!Number} order
|
||||
*/
|
||||
const drawHilbert = order => {
|
||||
if (!order || order < 1) {
|
||||
throw 'You need to give a valid positive integer';
|
||||
} else {
|
||||
order = Math.floor(order);
|
||||
}
|
||||
|
||||
|
||||
// Curve Constants
|
||||
const width = 2 ** order;
|
||||
const space = 10;
|
||||
|
||||
// SVG Setup
|
||||
const size = 500;
|
||||
const stroke = 2;
|
||||
const col = "red";
|
||||
const fill = "transparent";
|
||||
|
||||
// Prep and run function
|
||||
const f = hilbert(width, space, []);
|
||||
const points = f(0, 0, width, 0, 0, f);
|
||||
const path = points.join(' ');
|
||||
|
||||
console.log(
|
||||
`<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="${size}"
|
||||
height="${size}"
|
||||
viewBox="${space / 2} ${space / 2} ${width * space} ${width * space}">
|
||||
<path d="M${path}" stroke-width="${stroke}" stroke="${col}" fill="${fill}"/>
|
||||
</svg>`);
|
||||
|
||||
};
|
||||
|
||||
drawHilbert(6);
|
||||
204
Task/Hilbert-curve/JavaScript/hilbert-curve-2.js
Normal file
204
Task/Hilbert-curve/JavaScript/hilbert-curve-2.js
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
(() => {
|
||||
"use strict";
|
||||
|
||||
// ------------------ HILBERT CURVE ------------------
|
||||
|
||||
// hilbertCurve :: Dict Char [(Int, Int)] ->
|
||||
// Dict Char [Char] -> Int -> Int -> SVG string
|
||||
const hilbertCurve = dictVector =>
|
||||
dictRule => width => compose(
|
||||
svgFromPoints(width),
|
||||
hilbertPoints(dictVector)(width),
|
||||
hilbertTree(dictRule)
|
||||
);
|
||||
|
||||
|
||||
// hilbertTree :: Dict Char [Char] -> Int -> Tree Char
|
||||
const hilbertTree = rule =>
|
||||
n => {
|
||||
const go = tree => {
|
||||
const xs = tree.nest;
|
||||
|
||||
return Node(tree.root)(
|
||||
0 < xs.length
|
||||
? xs.map(go)
|
||||
: rule[tree.root].map(
|
||||
flip(Node)([])
|
||||
)
|
||||
);
|
||||
};
|
||||
const seed = Node("a")([]);
|
||||
|
||||
return 0 < n
|
||||
? take(n)(
|
||||
iterate(go)(seed)
|
||||
)
|
||||
.slice(-1)[0]
|
||||
: seed;
|
||||
};
|
||||
|
||||
|
||||
// hilbertPoints :: Size -> Tree Char -> [(x, y)]
|
||||
// hilbertPoints :: Int -> Tree Char -> [(Int, Int)]
|
||||
const hilbertPoints = dict =>
|
||||
w => tree => {
|
||||
const go = d => (xy, t) => {
|
||||
const
|
||||
r = Math.floor(d / 2),
|
||||
centres = dict[t.root]
|
||||
.map(v => [
|
||||
xy[0] + (r * v[0]),
|
||||
xy[1] + (r * v[1])
|
||||
]);
|
||||
|
||||
return 0 < t.nest.length
|
||||
? zipWith(
|
||||
go(r)
|
||||
)(centres)(t.nest).flat()
|
||||
: centres;
|
||||
};
|
||||
const d = Math.floor(w / 2);
|
||||
|
||||
return go(d)([d, d], tree);
|
||||
};
|
||||
|
||||
|
||||
// svgFromPoints :: Int -> [(Int, Int)] -> String
|
||||
const svgFromPoints = w => xys => [
|
||||
"<svg xmlns=\"http://www.w3.org/2000/svg\"",
|
||||
`width="500" height="500" viewBox="5 5 ${w} ${w}">`,
|
||||
`<path d="M${(xys).flat().join(" ")}" `,
|
||||
// eslint-disable-next-line quotes
|
||||
'stroke-width="2" stroke="red" fill="transparent"/>',
|
||||
"</svg>"
|
||||
].join("\n");
|
||||
|
||||
|
||||
// -------------------- TEST ---------------------
|
||||
const main = () =>
|
||||
hilbertCurve({
|
||||
"a": [
|
||||
[-1, 1],
|
||||
[-1, -1],
|
||||
[1, -1],
|
||||
[1, 1]
|
||||
],
|
||||
"b": [
|
||||
[1, -1],
|
||||
[-1, -1],
|
||||
[-1, 1],
|
||||
[1, 1]
|
||||
],
|
||||
"c": [
|
||||
[1, -1],
|
||||
[1, 1],
|
||||
[-1, 1],
|
||||
[-1, -1]
|
||||
],
|
||||
"d": [
|
||||
[-1, 1],
|
||||
[1, 1],
|
||||
[1, -1],
|
||||
[-1, -1]
|
||||
]
|
||||
})({
|
||||
a: ["d", "a", "a", "b"],
|
||||
b: ["c", "b", "b", "a"],
|
||||
c: ["b", "c", "c", "d"],
|
||||
d: ["a", "d", "d", "c"]
|
||||
})(1024)(6);
|
||||
|
||||
|
||||
// ---------------- GENERIC FUNCTIONS ----------------
|
||||
|
||||
// Node :: a -> [Tree a] -> Tree a
|
||||
const Node = v =>
|
||||
// Constructor for a Tree node which connects a
|
||||
// value of some kind to a list of zero or
|
||||
// more child trees.
|
||||
xs => ({
|
||||
type: "Node",
|
||||
root: v,
|
||||
nest: xs || []
|
||||
});
|
||||
|
||||
|
||||
// compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
|
||||
const compose = (...fs) =>
|
||||
// A function defined by the right-to-left
|
||||
// composition of all the functions in fs.
|
||||
fs.reduce(
|
||||
(f, g) => x => f(g(x)),
|
||||
x => x
|
||||
);
|
||||
|
||||
|
||||
// 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));
|
||||
|
||||
|
||||
// iterate :: (a -> a) -> a -> Gen [a]
|
||||
const iterate = f =>
|
||||
// An infinite list of repeated applications
|
||||
// of f, starting with the seed value x.
|
||||
function* (x) {
|
||||
let v = x;
|
||||
|
||||
while (true) {
|
||||
yield v;
|
||||
v = f(v);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// length :: [a] -> Int
|
||||
const length = xs =>
|
||||
// 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
|
||||
"GeneratorFunction" !== xs.constructor
|
||||
.constructor.name ? (
|
||||
xs.length
|
||||
) : Infinity;
|
||||
|
||||
|
||||
// take :: Int -> [a] -> [a]
|
||||
// take :: Int -> String -> String
|
||||
const take = n =>
|
||||
// The first n elements of a list,
|
||||
// string of characters, or stream.
|
||||
xs => "GeneratorFunction" !== xs
|
||||
.constructor.constructor.name ? (
|
||||
xs.slice(0, n)
|
||||
) : Array.from({
|
||||
length: n
|
||||
}, () => {
|
||||
const x = xs.next();
|
||||
|
||||
return x.done ? [] : [x.value];
|
||||
}).flat();
|
||||
|
||||
|
||||
// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
|
||||
const zipWith = f =>
|
||||
xs => ys => {
|
||||
const
|
||||
n = Math.min(length(xs), length(ys)),
|
||||
as = take(n)(xs),
|
||||
bs = take(n)(ys);
|
||||
|
||||
return Array.from({
|
||||
length: n
|
||||
}, (_, i) => f(as[i], bs[i]));
|
||||
};
|
||||
|
||||
|
||||
// MAIN ---
|
||||
return main();
|
||||
})();
|
||||
Loading…
Add table
Add a link
Reference in a new issue