lewisje All American 9196 Posts user info edit post |
I was inspired by the preview page in this article, showing how Douglas Adams may have wrote a function to list all of the primes less than or equal to a given number: http://arstechnica.com/information-technology/2014/11/holiday-reading-for-a-certain-sort-if-hemingway-wrote-javascript/
Below is the code, but I also put it into a JSFiddle: http://jsfiddle.net/b38L4p9q/2/
//Here I am, brain the size of a planet, and they ask me to write JavaScript... function kevinTheNumberMentioner(_){ l=[] /* mostly harmless --> */ with(l) {
//Sorry about all this, my babel fish has a headache today... for (ll=!+[]+!![];ll<_+(+!![]);ll++) { lll=+!![]; while (ll%++lll); //I've got this terrible pain in all the semicolons down my right-hand side. (ll==lll)&&push(ll); } forEach(alert);
}
//You're really not going to like this... return [!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]]; } Here are some unusual things about this code...
Line 2: The underscore is a perfectly good variable name, not a special character at all. Line 3: Usually, automatic semicolon insertion isn't used this early in a code-block. Line 4: with-blocks are deprecated and make code more difficult to follow. Line 7: Numerically, objects (including arrays) convert to NaN; however, they are also truthy (convert to true as booleans), while NaN is falsy. Numerically, false converts to 0 and true converts to 1. The prefix operator + converts to numbers, ! converts to boolean and yields the opposite, and the binary operator + performs numeric conversion if it wouldn't convert to NaN (for addition) and string conversion otherwise (for concatenation). This line sets a loop-counter to 2 and tests whether it is less than or equal to the argument of the function, incrementing by 1 at each iteration. Line 8: From the information in Line 7, this sets an inner variable to 1. Line 9: Keep incrementing that inner variable until the loop counter is divisible by it. Line 11: If the inner variable equals the loop counter, append it to the array declared in line 3. Line 13: Remember, this is still in a with-block. Line 18: This function is ultimately interested in the answer to the ultimate question of life, the universe, and everything.
Below is the same code, cleaned up a bit: http://jsfiddle.net/b38L4p9q/4/
function primeAlert(n) { 'use strict'; var arr = [], m, p; for (m = 2; m <= n; m++) { p = 1; while (m % ++p); if (m === p) arr.push(m); } arr.forEach(alert); return '42'; } It's still annoying and horribly inefficient (it doesn't even stop iterating at sqrt(m)) and unsafe (it doesn't even check whether its argument is a number), but at least it's more readable.
This is a slight bit more efficient and much safer, converting its argument to a number as well as possible first (another measure of safety could be throwing an error on non-numeric arguments; also I used n !== n instead of n.isNaN() and Math.pow(2, 53) instead of Number.MAX_SAFE_INTEGER for compatibility with older versions of JavaScript): http://jsfiddle.net/b38L4p9q/6/
function primeAlert(n) { 'use strict'; var arr, m, p, r; n = Math.floor(+n); if (n !== n || n < 2 || n >= Math.pow(2, 53)) return []; arr = []; for (m = 2; m < n; m++) { p = 1; r = Math.sqrt(m); while (m % ++p && p <= r); if (p > r) arr.push(m); } return arr; } 11/30/2014 2:29:09 AM |