Given a number n
, a minimum number min
, a maximum number max
, what is the most efficient method to determine
Numbe
Solution 1
test using regex
var min = 2;
var max = 7;
res = "";
arr = [81, 35, 22, 45, 49]
arr.push("");
regex=new RegExp("[" + min + "-" + max + "](.)(?!=\1)", "g")
var result = arr.reduce(function(a, b) {
if (regex.test(a)) {
res = res + a + " is true\n"
} else {
res = res + a + " is false\n"
};
return b
});
console.log(res)
The reduce method is different in a sense that it is like a generator function like in python (produces output on the fly)
Its simply loops through each elements in an array using a callback function. I cannot say how efficient is the reduce function.
Nevertheless consider two elements in the array
81 35
^
take this value take the result
and do something from the previous
element and add it
to the result computed
for this element
further information https://msdn.microsoft.com/en-us/library/ff679975%28v=vs.94%29.aspx
SOlution 2
Using list to store value and their boolean
var min = 2;
var max = 7;
res = [""];
arr = [81, 35, 22, 45, 49]
arr.push("");
regex=new RegExp("[" + min + "-" + max + "](.)(?!=\1)", "g")
var result = arr.reduce(function(a, b) {
if (regex.test(a)) {
res.push([a,true])
} else {
res.push([a,false])
};
return b
});
console.log(res)
This has the advantage of being easily understandable.
function checkDigits(min, max, n) {
var digits = Array(10); // Declare the length of the array (the 10 digits) to avoid any further memory allocation
while (n) {
d = (n % 10); // Get last digit
n = n / 10 >>0; // Remove it from our number (the >>0 bit is equivalent to compose(Math.floor, Math.abs))
if (d < min || d > max || digits[d]) // Test if "d" is outside the range or if it has been checked in the "digits" array
return false;
else
digits[d] = true; // Mark the digit as existing
}
}
var min = 2
, max = 7
, arr = [81, 35, 22, 45, 49];
function checkDigits(min, max, n) {
var digits = Array(10); // Declare the length of the array (the 10 digits) to avoid any further memory allocation
while (n) {
d = (n % 10); // Get last digit
n = n / 10 >>0; // Remove it from our number (the >>0 bit is equivalent to compose(Math.floor, Math.abs))
if (d < min || d > max || digits[d]) // Test if "d" is outside the range or if it has been checked in the "digits" array
return false;
else
digits[d] = true; // Mark the digit as existing
}
return true;
}
for (var i = 0; i < arr.length; i++) {
console.log(checkDigits(min, max, arr[i]), i, arr[i])
}
This replaces the Array with an integer that is in effect used as an array of bits. It should be faster.
function checkDigits(min, max, n) {
var digits = 0;
while (n) {
d = (n % 10);
n = n / 10 >>0;
if (d < min || d > max || (digits & (1 << d)))
return false;
else
digits |= 1 << d;
}
return true;
}
function checkDigits(min, max, n) {
var digits = 0;
while (n) {
d = (n % 10);
n = n / 10 >>0;
if (d < min || d > max || (digits & (1 << d)))
return false;
else
digits |= 1 << d;
}
return true;
}
1 << d
creates a bit mask, an integer with the d
bit set and all other bits set to 0.
digits |= 1 << d
sets the bit marked by our bit mask on the integer digits
.
digits & (1 << d)
compares the bit marked by our bit mask with digits
, the collection of previously marked bits.
See the docs on bitwise operators if you want to understand this in detail.
So, if we were to check 626, our numbers would go like this:
________n_____626_______________
|
d | 6
mask | 0001000000
digits | 0000000000
|
________n_____62________________
|
d | 2
mask | 0000000100
digits | 0001000000
|
________n_____6_________________
|
d | 6
mask | 0001000000
digits | 0001000100
^
bit was already set, return false