please i want to check if this string is sorted?
var myBucket = "1D2D1W2W1M2M3M4M5M6M9M1Y18M2Y30M3Y4Y5Y6Y8Y10Y15Y20Y25Y30Y1D2D1W2W1M2M3M4M5M6M9M1Y18M2Y30M3Y4Y5Y6Y8Y10Y15Y20Y25Y30Y";
1D=One Day 2D=2 Day ...
1W=1 Week
1M=1 Months 18M=18 Months
1Y=1 years
like 1D<2D<1W<3W<1M<10M<1Y<18M<2Y ...
How can i check this?
Thank you in advance.
I suggest to match a number and the length indicator. Then loop over with Array#every and split the part into number and length indicator. With a hash table for the length, you could calculate the length and test it with the last value before.
If greater, then proceed, else leave the loop and get false.
If the loop iterates over all elements, and the callback returns true, then it return true.
var myBucket = '1D2D1W2W1M2M3M4M5M6M9M1Y18M2Y30M3Y4Y5Y6Y8Y10Y15Y20Y25Y30Y1D2D1W2W1M2M3M4M5M6M9M1Y18M2Y30M3Y4Y5Y6Y8Y10Y15Y20Y25Y30Y',
values = { D: 1, W: 7, M: 30, Y: 365 },
result = myBucket.match(/\d+[DWMY]/g).every(function (a, i) {
var p = a.split(/(?=[DWMY])/),
value = p[0] * (values[p[1]] || 0);
if (value > this.last) {
this.last = value;
return true;
}
}, { last: -Infinity });
console.log(result);
Related
Goal
I am at the final stage of scripting a Luhn algorithm.
Problem
Let's say I have a final calculation of 73
How can I round it up to the next 0? So the final value is 80.
And lastly, how can I get the value that made the addition? e.g. 7 is the final answer.
Current code
function validateCred(array) {
// Array to return the result of the algorithm
const algorithmValue = [];
// Create a [2, 1, 2] Pattern
const pattern = array.map((x, y) => {
return 2 - (y % 2);
});
// From given array, multiply each element by it's pattern
const multiplyByPattern = array.map((n, i) => {
return n * pattern[i];
});
// From the new array, split the numbers with length of 2 e.g. 12 and add them together e.g. 1 + 2 = 3
multiplyByPattern.forEach(el => {
// Check for lenght of 2
if(el.toString().length == 2) {
// Split the number
const splitNum = el.toString().split('');
// Add the 2 numbers together
const addSplitNum = splitNum.map(Number).reduce(add, 0);
// Function to add number together
function add(accumalator, a) {
return accumalator + a;
}
algorithmValue.push(addSplitNum);
}
// Check for lenght of 1
else if(el.toString().length == 1){
algorithmValue.push(el);
}
});
// Sum up the algorithmValue together
const additionOfAlgorithmValue = algorithmValue.reduce((a, b) => {
return a + b;
});
// Mod the final value by 10
if((additionOfAlgorithmValue % 10) == 0) {
return true;
}
else{
return false;
}
}
// Output is False
console.log(validateCred([2,7,6,9,1,4,8,3,0,4,0,5,9,9,8]));
Summary of the code above
The output should be True. This is because, I have given the total length of 15 digits in the array. Whereas it should be 16. I know the 16th value is 7, because the total value of the array given is 73, and rounding it up to the next 0 is 80, meaning the check digit is 7.
Question
How can I get the check number if given array length is less than 15?
You could do something like this:
let x = [73,81,92,101,423];
let y = x.map((v) => {
let remainder = v % 10;
let nextRounded = v + (10-remainder);
/* or you could use
let nextRounded = (parseInt(v/10)+1)*10;
*/
let amountToNextRounded = 10 - remainder;
return [nextRounded,amountToNextRounded];
});
console.log(y);
EDIT
As noticed by #pilchard you could find nextRounded using this more simplified way:
let nextRounded = v + (10-remainder);
https://stackoverflow.com/users/13762301/pilchard
I think what you need is this:
var oldNum = 73
var newNum = Math.ceil((oldNum+1) / 10) * 10;;
Then check the difference using this:
Math.abs(newNum - oldNum);
object -> let error = {3:1, 4:1, 10:2, 12:1, 13:2} or {3:1, 4:1, 12:1, 13:2}
map -> let map = new Map([[3,1],[4,1],[10,2],[12,1],[13,2]]}
if my number is 10 means I need to get the value of 4 ie immediate less and if no less value then I need to return largest value.
for now, I will decrement the value and check if the exists in the map and return the value. Currently, I am using an object. If the passed number exists or not need to find immediate less value.
my obj contains 1, 3, 7, 10 is my keys and 5 is the number passed and I need to find the immediate less value 3 < 5 . if value passed 7 also 3<7. it is not based on index. its based on keys.
myFunction = (number) => {
let index;
for(int i = number; i>=number ; i--){
if(error[i] != undefined){
index = i;
break;
}
}
return index;
}
Is there any better way to do the same ?
You can sort the values in descending order and then use find the first value which is less than number, if the value is found return that value else return the last value
let mapper = [[3,1],[4,1],[10,2],[12,1],[13,2]].sort((a,b)=>b[0]-a[0])
let myFunction = (number) => {
let value = mapper.find((v, i) => {
if (v[0] < number) {
return v[1]
}
})
return value || mapper[0]
}
console.log(myFunction(10))
console.log(myFunction(9))
console.log(myFunction(2))
You could take the number directly and decrement the value until it reaches zero.
function fn(number) {
while (number--) if (number in error) return number;
}
var error = { 3: 1, 4: 1, 10: 2, 12: 1, 13: 2 };
console.log(fn(9));
console.log(fn(10));
For clarity sake, this is what I mean. I want to look for the two least numbers in an array(sorted) that will generate a particular number. The steps go thus:
Loop through the array and each time set a current value that other
numbers will be deducted from.
Keep doing that till you find the numbers that match the problem and return them.
Example. I need two numbers that when subtracted from the array will give a result of 2.
let givenArray = [1, 4, 8, 10];
The subtraction should go thus: 4 - 1 = 3(doesn't match); //continue
8 - 4 = 1(doesn't match);// continue
8 - 1 = 7(doesn't match); //continue
10 - 8 = 2(match found); //stop and return 8, 10.
NOTE: This same array may contain a 6 and 8 or 8 and 10 that will both yield 2 but 6 and 8 should be returned instead. The way the array is generated isn't of much importance.
P.S: I eventually solved it yesterday but I won't mind other ideas on how to go about it.
This solution takes the advantage of a hash table and uses a single loop approach for getting the two values out of an array to balance two values.
First, take the absolute delta of the two values of arrayA and take this for getting the values out of the greater array.
Then reduce the greater array arrayB by checking if the needed value exist and if the sum is smaller then a previously found set.
The argument for checking is build out of the absolute delta of delta and v, the actual value of the array or by taking the sum of delta and v.
The last point, and to make this all working, the actual value v is included into the hash table, for a later look up.
The result is either an array of two values, which balance the other two values or undefined, if no values are found.
var arrayA = [3, 5],
arrayB = [2, 9, 5, 4],
delta = Math.abs(arrayA[0] - arrayA[1]),
values = {},
result = arrayB.reduce((r, v) => {
function check(w) {
if (!values[w] || r && r[0] + r[1] < v + w) return;
r = [w, v];
}
check(Math.abs(delta - v));
check(delta + v);
values[v] = true;
return r;
}, undefined);
console.log(result);
I'm not sure I understood correctly, but perhaps this is what you need:
let result = arrayA[1] - arrayA[0];
let i, j;
for (i = arrayB.length - 1; i >= 1; i--) { // Set the first value
for (j = arrayB.length - 1; j >= 1; j--) { // Set the second value
if (i !== j) {
if (
arrayB[i] - arrayB[j] === result // Check substraction
|| arrayB[i] + arrayB[j] === result // Check addition
) return [arrayB[i], arrayB[j]];
}
}
}
I have an array of values as such:
var array_1 = ["1W", "2W", "3W","1M", "2M", "3M", "6M","9M","1Y"]
W stands for weeks, M for months, Y for years. How do I do a string comparison such that a comparison between
"1Y" > "9M"
will return true
You could take the same base, like days for every information and take the letter for an equivalent of days and return the product.
function getDays(string) {
return string.slice(0, -1) * { W: 7, M: 30, Y: 365 }[string.slice(-1)];
}
var array = ["1W", "2W", "3W","1M", "2M", "3M", "6M","9M","1Y"]
console.log(array.map(getDays));
Here is a simple decoder that is easy to expand upon.
In essence it filters the numeric value and then returns it multiplied by some constant based upon the what time symbol it finds in the string (W, M, ...).
function decodeDateCode(dateCode) {
var numeric = parseInt(dateCode.replace(/\D/igm, ''), 10);
if (dateCode.indexOf("D") >= 0) {
return numeric;
}
if (dateCode.indexOf("W") >= 0) {
return numeric * 7;
}
if (dateCode.indexOf("M") >= 0) {
return numeric * (365 / 12);
}
if (dateCode.indexOf("Y") >= 0) {
return numeric * 365;
}
}
//test
var dateCodes = ["1W", "2W", "3W", "1M", "2M", "3M", "6M", "9M", "1Y", "50W"];
//Decode entire list
console.log("Decoded list:", dateCodes.map(decodeDateCode));
//Sort entire list in descending order
console.log("Sorted descending list:", dateCodes.sort(function(a, b) {
return decodeDateCode(b) - decodeDateCode(a);
}));
//Make simple comparison
console.log("Simple comparison:", decodeDateCode("1Y") > decodeDateCode("9M"));
I am doing a challenge on Coderbyte and I would be grateful for any advice on my question:
The challenge given to me:
"Using the JavaScript language, have the function ArrayAdditionI(arr)
take the array of numbers stored in arr and return the string true if
any combination of numbers in the array can be added up to equal the
largest number in the array, otherwise return the string false.
For example: if arr contains [4, 6, 23, 10, 1, 3] the output should
return true because 4 + 6 + 10 + 3 = 23. The array will not be empty,
will not contain all the same elements, and may contain negative numbers. "
The way I attempted to solve it: http://jsfiddle.net/reLsg0fg/
function ArrayAdditionI(arr){
var newArr=arr.sort(); // sorted from smallest to largest.
var largestNum=newArr.slice(-1); // Gets the last number, which would be the largest.
var loopArr=arr.sort().pop(); // Takes out the largest number for adding later.
var result=0;
for(var i=0; i<loopArr.length; i++){ // loops through all numbers.
if(result/largestNum !== 1){ //when you divide a number by itself it will be 1.
result+=loopArr[i]; // keep adding each number until get largest number.
}else if(result === largestNum){
return true;
}
}
return false;
}
// TESTS
console.log("-----");
console.log(ArrayAdditionI([4,6,23,10,1,3]));
console.log(ArrayAdditionI([5,7,16,1,2]));
console.log(ArrayAdditionI([3,5,-1,8,12]));
I'm supposed to get true, false, true. But I get false, false, false as if something is wrong within my loop. JSFiddle: http://jsfiddle.net/reLsg0fg/
I would appreciate any suggestions. Thank you ^^
Sort Array using
arr.sort(function (a, b) { return a - b })
I have tried to solve this problem with a for loop but I missed the fact that the challenge
is not asking that all numbers need to add up to equal the largest num, but it is also possible to
add up to the largest num if we take some numbers out. Thus I decided to solve with recursion.
Tips:
* The Math.max.apply() method takes an array and returns the largest number. Note that it usually works on strings as Math.max().
* the sort() method can take a parameter to further expand it's purpose. Usually it only
sorts strings, but to sort numbers we include a function that finds which number is bigger.
* First get the largest number.
* Sort the array and remove the largest number to be used for recursion later.
* Create a recursion function that checks if the numbers add up to the largest number, and if not, check that if some numbers in array are subtracted from the largest num they are equal to the largest number.
function ArrayAdditionI(array){
var largestNum = Math.max.apply(0, array); // gets the largest number in array.
array.sort(function(a,b){ return a-b;}).pop(); // sorts array and removes last(largest) number.
function recursionCheck(arr, sum){
// the base case when array empty.
if(arr.length === 0){
return sum === 0;
}
var arrBeginNum=arr[0];
// for every recursion take away one number(the first one in this case).
arr = arr.slice(1);
// first check if numbers sum up to largest num if not, check if removing numbers adds up to largest num.
return recursionCheck(arr, sum) || recursionCheck(arr, sum - arrBeginNum);
}
// recursion needs to be called for it to start.
return recursionCheck(array, largestNum);
}
// TESTS
console.log("-----");
console.log(ArrayAdditionI([1,2,3,5,4])); ==> true
console.log(ArrayAdditionI([21,10,12,9,2])); ==> true
console.log(ArrayAdditionI([4,6,23,10,1,3])); ===> true
console.log(ArrayAdditionI([5,7,16,1,2])); ===> false
console.log(ArrayAdditionI([3,5,-1,8,12])); ===> true
This might not be the complete solution yet, but here are the JavaScript-Problems:
largestNum was an array in you algorithm
.sort() was not working
function ArrayAdditionI(arr){
var largestNum = Math.max.apply(0, arr); // Gets the last number, which would be the largest.
arr.sort(function(a, b){return a-b})
arr.pop(); // Takes out the largest number for adding later.
var result=0;
Also use if(result !== largestNum) {, Division is expensive and might have unexpected results with floating-point numbers.
Thats it for your JavaScript. But I am pretty sure the Algorithm is wrong - but I think this is up to you
Note that the example [4, 6, 23, 10, 1, 3] => 4 + 6 + 10 + 3 = 23 is not just adding up the lowest to the biggest value to try and match it.
A possible example of a solution for the problem.
How this works:
First sort all items descending
Shift the first element to largest
Call the recursive function y with the reduced array, the largest value and a variable which holds an empty array for the successfully added items.
The recursive function works basically in two parts
Test if the remaining sum is zero, if so the result is achieved and return true, which finished the function.
If not iterate through the array and
Make a copy from the array
Get the value from the position with splice
Test, if the value is smaller or equal the remaining sum and the result of the call of y with the shorted array, sum minus value and a new array with the used items and the acual item.
If true return true and finish the function.
If not finished before return false.
function x(array) {
function y(a, s, result) {
var aa, i, v;
if (s === 0) {
document.write('<pre>result: ' + JSON.stringify(result, 0, 4) + '</pre>');
return true;
}
for (i = 0; i < a.length; i++) {
aa = a.slice();
v = aa.splice(i, 1)[0];
if (v <= s && y(aa, s - v, result.concat(v))) {
return true;
}
}
return false;
}
var largest,
r = [];
array.sort(function (a, b) { return b - a; });
largest = array.shift();
document.write('largest value: ' + largest + '<br>');
return y(array, largest, r);
}
document.write(x([4, 6, 23, 10, 1, 3]) + '<hr>');
document.write(x([5, 7, 16, 1, 2]) + '<hr>');
document.write(x([3, 5, -1, 8, 12]));
Thanks #mar
Here is a version in Kotlin if someone needs
private fun returnResult(arr: Array<Int>): Boolean {
arr.sort()
val largestNumber = arr.last()
val arrWithoutLargest = arr.dropLast(1).toTypedArray()
return recursionCheck(arrWithoutLargest, largestNumber)
}
private fun recursionCheck(arr: Array<Int>, sum:Int): Boolean {
if (arr.isEmpty()) return sum == 0
val arrBeginNum = arr[0]
val arr2 = arr.drop(1).toTypedArray()
return recursionCheck(arr2, sum) || recursionCheck(arr2, sum - arrBeginNum)
}