Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
45
Task/Box-the-compass/JavaScript/box-the-compass-1.js
Normal file
45
Task/Box-the-compass/JavaScript/box-the-compass-1.js
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
function createRow(i, point, heading) {
|
||||
var tr = document.createElement('tr'),
|
||||
td;
|
||||
|
||||
td = document.createElement('td');
|
||||
td.appendChild(document.createTextNode(i));
|
||||
tr.appendChild(td);
|
||||
|
||||
td = document.createElement('td');
|
||||
point = point.substr(0, 1).toUpperCase() + point.substr(1);
|
||||
td.appendChild(document.createTextNode(point));
|
||||
tr.appendChild(td);
|
||||
|
||||
td = document.createElement('td');
|
||||
td.appendChild(document.createTextNode(heading));
|
||||
tr.appendChild(td);
|
||||
|
||||
return tr;
|
||||
}
|
||||
|
||||
function getPoint(i) {
|
||||
var j = i % 8,
|
||||
i = Math.floor(i / 8) % 4,
|
||||
cardinal = ['north', 'east', 'south', 'west'],
|
||||
pointDesc = ['1', '1 by 2', '1-C', 'C by 1', 'C', 'C by 2', '2-C', '2 by 1'],
|
||||
str1, str2, strC;
|
||||
|
||||
str1 = cardinal[i];
|
||||
str2 = cardinal[(i + 1) % 4];
|
||||
strC = (str1 === 'north' || str1 === 'south') ? str1 + str2 : str2 + str1;
|
||||
return pointDesc[j].replace('1', str1).replace('2', str2).replace('C', strC);
|
||||
}
|
||||
|
||||
var i,
|
||||
heading,
|
||||
table = document.createElement('table'),
|
||||
tbody = document.createElement('tbody'),
|
||||
tr;
|
||||
for (i = 0; i <= 32; i += 1) {
|
||||
heading = i * 11.25 + [0, 5.62, -5.62][i % 3];
|
||||
tr = createRow(i % 32 + 1, getPoint(i), heading + '°');
|
||||
tbody.appendChild(tr);
|
||||
}
|
||||
table.appendChild(tbody);
|
||||
document.body.appendChild(table);
|
||||
239
Task/Box-the-compass/JavaScript/box-the-compass-2.js
Normal file
239
Task/Box-the-compass/JavaScript/box-the-compass-2.js
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
(() => {
|
||||
'use strict';
|
||||
|
||||
// GENERIC FUNCTIONS
|
||||
|
||||
// toTitle :: String -> String
|
||||
let toTitle = s => s.length ? (s[0].toUpperCase() + s.slice(1)) : '';
|
||||
|
||||
// COMPASS DATA AND FUNCTIONS
|
||||
|
||||
// Scale invariant keys for points of the compass
|
||||
// (allows us to look up a translation for one scale of compass (32 here)
|
||||
// for use in another size of compass (8 or 16 points)
|
||||
// (Also semi-serviceable as more or less legible keys without translation)
|
||||
|
||||
// compassKeys :: Int -> [String]
|
||||
let compassKeys = depth => {
|
||||
let urCompass = ['N', 'S', 'N'],
|
||||
subdivision = (compass, n) => n <= 1 ? (
|
||||
compass
|
||||
) : subdivision( // Borders between N and S engender E and W.
|
||||
// other new boxes concatenate their parent keys.
|
||||
compass.reduce((a, x, i, xs) => {
|
||||
if (i > 0) {
|
||||
return (n === depth) ? (
|
||||
a.concat([x === 'N' ? 'W' : 'E'], x)
|
||||
) : a.concat([xs[i - 1] + x, x]);
|
||||
} else return a.concat(x);
|
||||
}, []),
|
||||
n - 1
|
||||
);
|
||||
return subdivision(urCompass, depth)
|
||||
.slice(0, -1);
|
||||
};
|
||||
|
||||
// https://zh.wikipedia.org/wiki/%E7%BD%97%E7%9B%98%E6%96%B9%E4%BD%8D
|
||||
let lstLangs = [{
|
||||
'name': 'English',
|
||||
expansions: {
|
||||
N: 'north',
|
||||
S: 'south',
|
||||
E: 'east',
|
||||
W: 'west',
|
||||
b: ' by ',
|
||||
'-': '-'
|
||||
},
|
||||
'N': 'N',
|
||||
'NNNE': 'NbE',
|
||||
'NNE': 'N-NE',
|
||||
'NNENE': 'NEbN',
|
||||
'NE': 'NE',
|
||||
'NENEE': 'NEbE',
|
||||
'NEE': 'E-NE',
|
||||
'NEEE': 'EbN',
|
||||
'E': 'E',
|
||||
'EEES': 'EbS',
|
||||
'EES': 'E-SE',
|
||||
'EESES': 'SEbE',
|
||||
'ES': 'SE',
|
||||
'ESESS': 'SEbS',
|
||||
'ESS': 'S-SE',
|
||||
'ESSS': 'SbE',
|
||||
'S': 'S',
|
||||
'SSSW': 'SbW',
|
||||
'SSW': 'S-SW',
|
||||
'SSWSW': 'SWbS',
|
||||
'SW': 'SW',
|
||||
'SWSWW': 'SWbW',
|
||||
'SWW': 'W-SW',
|
||||
'SWWW': 'WbS',
|
||||
'W': 'W',
|
||||
'WWWN': 'WbN',
|
||||
'WWN': 'W-NW',
|
||||
'WWNWN': 'NWbW',
|
||||
'WN': 'NW',
|
||||
'WNWNN': 'NWbN',
|
||||
'WNN': 'N-NW',
|
||||
'WNNN': 'NbW'
|
||||
}, {
|
||||
'name': 'Chinese',
|
||||
'N': '北',
|
||||
'NNNE': '北微东',
|
||||
'NNE': '东北偏北',
|
||||
'NNENE': '东北微北',
|
||||
'NE': '东北',
|
||||
'NENEE': '东北微东',
|
||||
'NEE': '东北偏东',
|
||||
'NEEE': '东微北',
|
||||
'E': '东',
|
||||
'EEES': '东微南',
|
||||
'EES': '东南偏东',
|
||||
'EESES': '东南微东',
|
||||
'ES': '东南',
|
||||
'ESESS': '东南微南',
|
||||
'ESS': '东南偏南',
|
||||
'ESSS': '南微东',
|
||||
'S': '南',
|
||||
'SSSW': '南微西',
|
||||
'SSW': '西南偏南',
|
||||
'SSWSW': '西南微南',
|
||||
'SW': '西南',
|
||||
'SWSWW': '西南微西',
|
||||
'SWW': '西南偏西',
|
||||
'SWWW': '西微南',
|
||||
'W': '西',
|
||||
'WWWN': '西微北',
|
||||
'WWN': '西北偏西',
|
||||
'WWNWN': '西北微西',
|
||||
'WN': '西北',
|
||||
'WNWNN': '西北微北',
|
||||
'WNN': '西北偏北',
|
||||
'WNNN': '北微西'
|
||||
}];
|
||||
|
||||
// pointIndex :: Int -> Num -> Int
|
||||
let pointIndex = (power, degrees) => {
|
||||
let nBoxes = (power ? Math.pow(2, power) : 32);
|
||||
return Math.ceil(
|
||||
(degrees + (360 / (nBoxes * 2))) % 360 * nBoxes / 360
|
||||
) || 1;
|
||||
};
|
||||
|
||||
// pointNames :: Int -> Int -> [String]
|
||||
let pointNames = (precision, iBox) => {
|
||||
let k = compassKeys(precision)[iBox - 1];
|
||||
return lstLangs.map(dctLang => {
|
||||
let s = dctLang[k] || k, // fallback to key if no translation
|
||||
dctEx = dctLang.expansions;
|
||||
|
||||
return dctEx ? toTitle(s.split('')
|
||||
.map(c => dctEx[c])
|
||||
.join(precision > 5 ? ' ' : ''))
|
||||
.replace(/ /g, ' ') : s;
|
||||
});
|
||||
};
|
||||
|
||||
// maximumBy :: (a -> a -> Ordering) -> [a] -> a
|
||||
let maximumBy = (f, xs) =>
|
||||
xs.reduce((a, x) => a === undefined ? x : (
|
||||
f(x, a) > 0 ? x : a
|
||||
), undefined);
|
||||
|
||||
// justifyLeft :: Int -> Char -> Text -> Text
|
||||
let justifyLeft = (n, cFiller, strText) =>
|
||||
n > strText.length ? (
|
||||
(strText + replicate(n, cFiller)
|
||||
.join(''))
|
||||
.substr(0, n)
|
||||
) : strText;
|
||||
|
||||
// justifyRight :: Int -> Char -> Text -> Text
|
||||
let justifyRight = (n, cFiller, strText) =>
|
||||
n > strText.length ? (
|
||||
(replicate(n, cFiller)
|
||||
.join('') + strText)
|
||||
.slice(-n)
|
||||
) : strText;
|
||||
|
||||
// replicate :: Int -> a -> [a]
|
||||
let replicate = (n, a) => {
|
||||
let v = [a],
|
||||
o = [];
|
||||
if (n < 1) return o;
|
||||
while (n > 1) {
|
||||
if (n & 1) o = o.concat(v);
|
||||
n >>= 1;
|
||||
v = v.concat(v);
|
||||
}
|
||||
return o.concat(v);
|
||||
};
|
||||
|
||||
// transpose :: [[a]] -> [[a]]
|
||||
let transpose = xs =>
|
||||
xs[0].map((_, iCol) => xs.map((row) => row[iCol]));
|
||||
|
||||
// length :: [a] -> Int
|
||||
// length :: Text -> Int
|
||||
let length = xs => xs.length;
|
||||
|
||||
// compareByLength = (a, a) -> (-1 | 0 | 1)
|
||||
let compareByLength = (a, b) => {
|
||||
let [na, nb] = [a, b].map(length);
|
||||
return na < nb ? -1 : na > nb ? 1 : 0;
|
||||
};
|
||||
|
||||
// maxLen :: [String] -> Int
|
||||
let maxLen = xs => maximumBy(compareByLength, xs)
|
||||
.length;
|
||||
|
||||
// compassTable :: Int -> [Num] -> Maybe String
|
||||
let compassTable = (precision, xs) => {
|
||||
if (precision < 1) return undefined;
|
||||
else {
|
||||
let intPad = 2;
|
||||
|
||||
let lstIndex = xs.map(x => pointIndex(precision, x)),
|
||||
lstStrIndex = lstIndex.map(x => x.toString()),
|
||||
nIndexWidth = maxLen(lstStrIndex),
|
||||
colIndex = lstStrIndex.map(
|
||||
x => justifyRight(nIndexWidth, ' ', x)
|
||||
);
|
||||
|
||||
let lstAngles = xs.map(x => x.toFixed(2) + '°'),
|
||||
nAngleWidth = maxLen(lstAngles) + intPad,
|
||||
colAngles = lstAngles.map(x => justifyRight(nAngleWidth, ' ', x));
|
||||
|
||||
let lstTrans = transpose(
|
||||
lstIndex.map(i => pointNames(precision, i))
|
||||
),
|
||||
lstTransWidths = lstTrans.map(x => maxLen(x) + 2),
|
||||
colsTrans = lstTrans
|
||||
.map((lstLang, i) => lstLang
|
||||
.map(x => justifyLeft(lstTransWidths[i], ' ', x))
|
||||
);
|
||||
|
||||
return transpose([colIndex]
|
||||
.concat([colAngles], [replicate(lstIndex.length, " ")])
|
||||
.concat(colsTrans))
|
||||
.map(x => x.join(''))
|
||||
.join('\n');
|
||||
}
|
||||
}
|
||||
|
||||
// TEST
|
||||
let xs = [0.0, 16.87, 16.88, 33.75, 50.62, 50.63, 67.5, 84.37,
|
||||
84.38, 101.25, 118.12, 118.13, 135.0, 151.87, 151.88, 168.75,
|
||||
185.62, 185.63, 202.5, 219.37, 219.38, 236.25, 253.12, 253.13,
|
||||
270.0, 286.87, 286.88, 303.75, 320.62, 320.63, 337.5, 354.37,
|
||||
354.38
|
||||
];
|
||||
|
||||
// If we supply other precisions, like 4 or 6, (2^n -> 16 or 64 boxes)
|
||||
// the bearings will be divided amongst smaller or larger numbers of boxes,
|
||||
// either using name translations retrieved by the generic hash
|
||||
// or using the hash itself (combined with any expansions)
|
||||
// to substitute for missing names for very finely divided boxes.
|
||||
|
||||
return compassTable(5, xs); // 2^5 -> 32 boxes
|
||||
})();
|
||||
Loading…
Add table
Add a link
Reference in a new issue