<!-- --> <script> // Euler problem 1, in APL semantics implemented in JS
// Count zero to n, not including n. function iota(n) { var rv = []; for (var ii = 0; ii < n; ii++) rv.push(ii); return aplify(rv); } // Some basic binary operations. function add(a, b) { return a + b } function mod(a, b) { return a % b } function eq(a, b) { return a === b } function or(a, b) { return a || b } // Add aggregate operations to an array. function aplify(array) { array.reduce = apl_reduce; array.where = apl_where; array.mod = apl_mod; array.eq = apl_eq; array.or = apl_or; return array; } // Generalization of sum. Mostly useful with associative functions. function apl_reduce(op) { if (this.length === 0) return op.identity; var rv = this[0]; for (var ii = 1; ii < this.length; ii++) rv = op(rv, this[ii]); return rv; } // aka "compress", with the arguments backwards; returns items corresponding to true indices. function apl_where(indices) { var rv = aplify([]); for (var ii = 0; ii < indices.length; ii++) if (indices[ii]) rv.push(this[ii]); return rv; } // The aggregate functions we're using. function apl_mod(rand) { return apl_simd(this, mod, rand) } function apl_eq(rand) { return apl_simd(this, eq, rand) } function apl_or(rand) { return apl_simd(this, or, rand) } // Aggregate functions in general. function apl_simd(left, op, right) { var left_scalar = (left.length === undefined); var right_scalar = (right.length === undefined); if (left_scalar && right_scalar) return op(left, right); var length = left_scalar ? right.length : left.length; if (!left_scalar && !right_scalar && left.length != right.length) { throw new Error("mismatched argument sizes " + left + " : " + right); } var rv = aplify([]); for (var ii = 0; ii < length; ii++) { rv.push(op(left_scalar ? left : left[ii], right_scalar ? right : right[ii])); } return rv; } // === End of APL semantics implementation. Solutions: // APL way: var x = iota(1000); document.write(x.where(x.mod(3).eq(0).or(x.mod(5).eq(0))).reduce(add)); // Conventional imperative way: var total = 0; for (var ii = 0; ii < 1000; ii++) if (ii % 3 === 0 || ii % 5 === 0) total += ii; document.write("\nimperative: " + total); // </script> -- To unsubscribe: http://lists.canonical.org/mailman/listinfo/kragen-hacks