| Leo Repp | 58b9f11 | 2021-11-22 11:57:47 +0100 | [diff] [blame^] | 1 | module.exports = compile; |
| 2 | |
| 3 | var BaseFuncs = require("boolbase"), |
| 4 | trueFunc = BaseFuncs.trueFunc, |
| 5 | falseFunc = BaseFuncs.falseFunc; |
| 6 | |
| 7 | /* |
| 8 | returns a function that checks if an elements index matches the given rule |
| 9 | highly optimized to return the fastest solution |
| 10 | */ |
| 11 | function compile(parsed){ |
| 12 | var a = parsed[0], |
| 13 | b = parsed[1] - 1; |
| 14 | |
| 15 | //when b <= 0, a*n won't be possible for any matches when a < 0 |
| 16 | //besides, the specification says that no element is matched when a and b are 0 |
| 17 | if(b < 0 && a <= 0) return falseFunc; |
| 18 | |
| 19 | //when a is in the range -1..1, it matches any element (so only b is checked) |
| 20 | if(a ===-1) return function(pos){ return pos <= b; }; |
| 21 | if(a === 0) return function(pos){ return pos === b; }; |
| 22 | //when b <= 0 and a === 1, they match any element |
| 23 | if(a === 1) return b < 0 ? trueFunc : function(pos){ return pos >= b; }; |
| 24 | |
| 25 | //when a > 0, modulo can be used to check if there is a match |
| 26 | var bMod = b % a; |
| 27 | if(bMod < 0) bMod += a; |
| 28 | |
| 29 | if(a > 1){ |
| 30 | return function(pos){ |
| 31 | return pos >= b && pos % a === bMod; |
| 32 | }; |
| 33 | } |
| 34 | |
| 35 | a *= -1; //make `a` positive |
| 36 | |
| 37 | return function(pos){ |
| 38 | return pos <= b && pos % a === bMod; |
| 39 | }; |
| 40 | } |