--- id: 5eb3e4b20aa93c437f9e9717 title: Set of real numbers challengeType: 5 forumTopicId: 385322 --- ## Description
All real numbers form the uncountable set ℝ. Among its subsets, relatively simple are the convex sets, each expressed as a range between two real numbers a and b where ab. There are actually four cases for the meaning of "between", depending on open or closed boundary: Note that if a = b, of the four only [a, a] would be non-empty. Task
## Instructions
Write a function that takes 2 objects, a string and an array as parameters. The objects represents the set and have attributes: `low`, `high` and `rangeType`. The `rangeType` can have values 0, 1, 2 and 3 for `CLOSED`, `BOTH_OPEN`, `LEFT_OPEN` and `RIGHT_OPEN`, respectively. The function should implement a set using this information. The string represents the operation to be performed on the sets. It can be: `"union"`, `"intersect"` and `"subtract"` (difference). After performing the operation, the function should check if the values in the array are present in the resultant set and store a corresponding boolean value to an array. The function should return this array.
## Tests
```yml tests: - text: realSet should be a function. testString: assert(typeof realSet=='function'); - text: realSet({"low":0, "high":1, "rangeType":2}, {"low":0, "high":2, "rangeType":3}, "union", [1, 2, 3]) should return a array. testString: assert(Array.isArray(realSet({"low":0, "high":1, "rangeType":2}, {"low":0, "high":2, "rangeType":3}, "union", [1, 2, 3]))); - text: realSet({"low":0, "high":1, "rangeType":2}, {"low":0, "high":2, "rangeType":3}, "union", [1, 2, 3]) should return [true, false, false]. testString: assert.deepEqual(realSet({"low":0, "high":1, "rangeType":2}, {"low":0, "high":2, "rangeType":3}, "union", [1, 2, 3]), [true, false, false]); - text: realSet({"low":0, "high":2, "rangeType":3}, {"low":1, "high":2, "rangeType":2}, "intersect", [0, 1, 2]) should return [false, false, false]. testString: assert.deepEqual(realSet({"low":0, "high":2, "rangeType":3}, {"low":1, "high":2, "rangeType":2}, "intersect", [0, 1, 2]), [false, false, false]); - text: realSet({"low":0, "high":3, "rangeType":3}, {"low":0, "high":1, "rangeType":1}, "subtract", [0, 1, 2]) should return [true, true, true]. testString: assert.deepEqual(realSet({"low":0, "high":3, "rangeType":3}, {"low":0, "high":1, "rangeType":1}, "subtract", [0, 1, 2]), [true, true, true]); - text: realSet({"low":0, "high":3, "rangeType":3}, {"low":0, "high":1, "rangeType":0}, "subtract", [0, 1, 2]) should return [false, false, true]. testString: assert.deepEqual(realSet({"low":0, "high":3, "rangeType":3}, {"low":0, "high":1, "rangeType":0}, "subtract", [0, 1, 2]), [false, false, true]); - text: realSet({"low":0, "high":33, "rangeType":1}, {"low":30, "high":31, "rangeType":0}, "intersect", [30, 31, 32]) should return [true, true, false]. testString: assert.deepEqual(realSet({"low":0, "high":33, "rangeType":1}, {"low":30, "high":31, "rangeType":0}, "intersect", [30, 31, 32]), [true, true, false]); ```
## Challenge Seed
```js function realSet(set1, set2, operation, values) { } ```
## Solution
```js function realSet(set1, set2, operation, values) { const RangeType = { CLOSED: 0, BOTH_OPEN: 1, LEFT_OPEN: 2, RIGHT_OPEN: 3 }; function Predicate(test) { this.test = test; this.or = function(other) { return new Predicate(t => this.test(t) || other.test(t)); }; this.and = function(other) { return new Predicate(t => this.test(t) && other.test(t)); }; this.negate = function() { return new Predicate(t => !this.test(t)); }; } function RealSet(start, end, rangeType, predF) { this.low = start; this.high = end; if (predF) { this.predicate = new Predicate(predF); } else { this.predicate = new Predicate(d => { switch (rangeType) { case RangeType.CLOSED: return start <= d && d <= end; case RangeType.BOTH_OPEN: return start < d && d < end; case RangeType.LEFT_OPEN: return start < d && d <= end; case RangeType.RIGHT_OPEN: return start <= d && d < end; } }); } this.contains = function(d) { return this.predicate.test(d); }; this.union = function(other) { var low2 = Math.min(this.low, other.low); var high2 = Math.max(this.high, other.high); return new RealSet(low2, high2, null, d => this.predicate.or(other.predicate).test(d) ); }; this.intersect = function(other) { var low2 = Math.min(this.low, other.low); var high2 = Math.max(this.high, other.high); return new RealSet(low2, high2, null, d => this.predicate.and(other.predicate).test(d) ); }; this.subtract = function(other) { return new RealSet(this.low, this.high, null, d => this.predicate.and(other.predicate.negate()).test(d) ); }; } set1 = new RealSet(set1.low, set1.high, set1.rangeType); set2 = new RealSet(set2.low, set2.high, set2.rangeType); var result = []; values.forEach(function(value) { result.push(set1[operation](set2).contains(value)); }); return result; } ```