Last active
August 4, 2020 16:45
-
-
Save jda0/01070831825ed63efcd1f626653a16a3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Calculates Hamming weight of a positive integer. | |
* The Hamming weight of an integer can be calculated by seeing if the last bit is set, then shifting the number | |
* down by one bit, and doing likewise until the number is zero then returning the bitcount. | |
* @param {number} n | |
* @returns {number} Hamming weight | |
*/ | |
H = n => n ? (n & 1) + H(n>>1) : 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let alternateChars; | |
/** | |
* | |
* @param {string} a | |
* @returns {string} | |
*/ | |
alternateChars = a => | |
[].reduce.call(a, ([r, s], x) => // reducing over the input string | |
( | |
/[a-z]/i.test(x) | |
? ( | |
/[aeiou]/i.test(x) === /[aeiou]/i.test(s) // if a vowel or consonant is followed by like | |
? (s < x ? (s = x) : 1) // consume the letter with greater unicode value | |
: ((r += s) || 1) && (s = x) // else consume the next letter | |
// and output the previously consumed codepoint | |
) | |
: (r += x) || 1 // consume if not alphanumeric and continue | |
) && [r, s], // continue reduction with consumption and pending output | |
['', ''] // starting with each empty | |
).join('') // then append the last consumption to the output. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* `SortNode` is a sorted linked list with `insert` and `flat` methods. | |
* @class | |
* @constructor | |
* @param {*} value | |
*/ | |
function SortNode (value) { | |
this.value = value; | |
return this; | |
} | |
/** | |
* Compares a `SortNode` to a value. | |
* @memberof SortNode | |
* @this SortNode | |
* @param {*} value | |
* @returns {number} | |
*/ | |
SortNode.prototype.compare = function (value) { | |
return typeof this.value === 'string' | |
? this.value.localeCompare(value) | |
: typeof value === 'string' | |
? -value.localeCompare(this.value) | |
: this.value - value; | |
} | |
/** | |
* Inserts a value into the linked list containing `SortNode`. | |
* @memberof SortNode | |
* @this SortNode | |
* @param {*} value | |
* @returns {SortNode} A `SortNode` containing the inserted value. | |
* | |
SortNode.prototype.insert = function (value) { | |
if (this.value === undefined) { | |
this.value = value; | |
return this; | |
} | |
if (this.prev && this.prev.compare(value) > 0) { | |
return this.prev.insert(value); | |
} | |
if (this.next && this.next.compare(value) <= 0) { | |
return this.next.insert(value); | |
} | |
if (this.compare(value) > 0) { | |
const prev = new SortNode(value); | |
prev.prev = this.prev; | |
if (this.prev) { | |
this.prev.next = prev; | |
} | |
prev.next = this; | |
return this.prev = prev; | |
} else { | |
const next = new SortNode(value); | |
next.next = this.next; | |
if (this.next) { | |
this.next.prev = next; | |
} | |
next.prev = this; | |
return this.next = next; | |
} | |
} | |
/** | |
* Flattens the linked list containing `SortNode` to an array of values. | |
* @memberof SortNode | |
* @this SortNode | |
* @param {number} dir [INTERNAL] Used to recursively flatten the list from linked nodes. | |
* @returns {*[]} | |
SortNode.prototype.flat = function (dir) { | |
return [ | |
...(this.prev && dir !== +1 ? this.prev.flat(-1) : []), | |
this.value, | |
...(this.next && dir !== -1 ? this.next.flat(+1) : []), | |
] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let f, c, d, g, i; | |
/** | |
* Note: this will pollute global scope. | |
* Accepts a floating point number and returns a fractional representation of `n` | |
* in the form `[numerator, denominator]`. | |
* If you encounter a stack overflow, try increasing the value of `e`, | |
* i.e. do not set `e` to `Number.EPSILON`. | |
* @param {number} n a floating point number | |
* @param {number?} e epsilon | |
* @returns {[number, number]} a fractional representation of `n` | |
*/ | |
f = (n, e = 1e-3) => | |
( | |
c = ( | |
g = (n, e, c = []) => // `g` is a lambda that builds a continued fractional | |
// representation of an `n`: | |
(d = n - (i = ~~n)) > e // if the fractional component of the number passed to `g` | |
// is greater than the epsilon | |
? [...c, i, ...g(1 / d, e, c)] // ...append the natural component of `n`, and the result | |
// of recursively calling `g` on the inverse of the | |
// fractional component (e.g. | |
// `g(3.5, e, [1]) == g(1 / 0.5, e, [1, 3])`) | |
: [...c, i] // ...else append `n` and return the generated continued | |
// fraction. | |
)(n, e).reverse() // call `g` with our initial arguments and reverse | |
// the result. | |
).reduce( // then, reduce our RTL continued fraction into a standard | |
// fractional form of `n`: | |
([d, n], a) => [a * d + n, d], // by recursively reducing `1 / [a + n / d]` into the | |
// equivalent `d / [a * d + n]` (e.g. | |
// 1 / [2 + 3 / 4] == 4 / [2 * 4 + 3] == 4 / 11) | |
[c.shift(), 1] // starting with the smallest component of the | |
// continued fraction and working outwards | |
) // leaving us with a fractional representation of `n`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let f, c, q; | |
/** | |
* Note: this will pollute global scope. | |
* Accepts a string and returns a list of valid formable IPv4 addresses. | |
* @example f('127001') ~> ['12.70.0.1', '127.0.0.1'] | |
* | |
* @param {string} s A string representation of IPv4 address (digits only) | |
* @param {number} d [INTERNAL] Recursion depth / group count - 1 | |
* @param {string} p [INTERNAL] | |
* @param {string[]} r [INTERNAL] Results array | |
* @returns {string[]} | |
*/ | |
f = (s, d = 3, p = '', r = []) => | |
[1,2,3].map(n => // Take each number 1 to 3 in turn (`n`). | |
d // If we have more groups to form... | |
? ( | |
( | |
c = s => // We check groups by | |
s && // checking that they're not empty, | |
( | |
!s[1] || // that they don't contain a zero prefixing | |
s[0] != '0' // another digit (e.g. '02') | |
) && | |
+s < 256 // and that they have a value less than 256. | |
)( | |
q = s.slice(0, n) // Check the next `n` characters (our next | |
) && // potential group) and if it's OK, | |
f( // recursively create groups from | |
s.slice(n), // what's left over, | |
d - 1, | |
d == 3 // joining our new group to what we had | |
? q // already and making sure we don't prepend | |
: p + '.' + q, // the entire IP address with a period. | |
r | |
) | |
) | |
: ( // If we don't have any more groups to form, | |
s.length == n && // we have exactly enough characters left to | |
c(s) && // form a group and the final group is OK, | |
r.push(p + '.' + s) // push our result to our results array | |
) | |
) && | |
r // and return the results array when we're done. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let f,g,h; | |
/** | |
* Shoutout to Nick. If you see this, I hope this formatting doesn't "hurt your | |
* soul" quite as much as last week's. | |
*/ | |
/** | |
* Note: this will pollute global scope. | |
* Accepts an array of strings and sorts them by ascending number of | |
* distinct characters, tie-breaking by descending string length. | |
* @example f(['Bananas', 'do', 'not', 'grow', 'in', 'Mississippi']) | |
* ~> ['do', 'in', 'not', 'Mississippi', 'Bananas', 'grow'] | |
* | |
* @param {string} x An array of strings to sort | |
* @returns {string[]} | |
*/ | |
f = x => | |
x.sort((a, b) => // First, we sort by length | |
(h = x => x.length)(b) - // descending (b - a ~> desc.). | |
h(a) // `Array.prototype.length` is | |
// hereby aliased to `h`. | |
).sort((a, b) => // Then, we sort by distinct | |
h(( // characters by comparing the | |
g = x => [].reduce.call( // lengths of the strings once | |
x, // we've removed all | |
(a,b) => a.includes(b) ? a : a + b // duplicates (`g`) — if they're | |
) // equal, the original order | |
)(a)) - // (which is determined by the | |
h(g(b)) // previous sort) breaks ties. | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let f,g; | |
/** | |
* Note: this will pollute global scope. | |
* Accepts an array of strings and sorts them by ascending number of | |
* distinct characters, tie-breaking by descending string length. | |
* @example f(['Bananas', 'do', 'not', 'grow', 'in', 'Mississippi']) | |
* ~> ['do', 'in', 'not', 'Mississippi', 'Bananas', 'grow'] | |
* | |
* @param {string} x An array of strings to sort | |
* @returns {string[]} | |
*/ | |
f = x => | |
x.sort((a, b) => // Then, we sort by distinct | |
( // characters by comparing the | |
g = x => new Set(x).size // lengths of the strings | |
)(a) - // once we've removed all | |
g(b) || // duplicates (`g`) — if they're | |
( // characters by comparing the | |
g = x => x.length // lengths of the strings | |
)(b) - // once we've removed all | |
g(a) // equal, comparing the length | |
) // of the string breaks ties. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment