I'm trying to return the array an array of numbers that conform to the two if statements. The prompt came from leet code, "Self Dividing Numbers", and asks to take in two arguments, a lower and upper bound and check if whether or not each number in that range is divisible by the digits of each individual number.
When I console.log(num) (the commented out portion, I get a correct list of numbers, but not in an array format. To fix this I thought to add a variable, result and return result after pushing an array to result inside the for loop. However when I do this, i only get the first correct term in an array, but not the full array.
How can this be fixed? I've tried moving the return statement in various locations, but that did not fix the issue.
The function should return [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 15, 22];
function selfDividingNumbers(left, right) {
for (let j = left; j <= right; j++) {
let num = j;
let result = []
let strNum = num.toString();
let dividingDigit = 0;
for (let i = 0; i < strNum.length; i++) {
if (num % parseInt(strNum[i]) == 0) {
dividingDigit++;
}
if (dividingDigit == strNum.length) {
result.push(num)
//console.log(num)
}
}
return result
}
};
console.log(selfDividingNumbers(1, 22));
From your expected output, define result at the very top of the function, and then return only after completely iterating through both loops:
function selfDividingNumbers(left, right) {
let result = []
for (let j = left; j <= right; j++) {
let num = j;
let strNum = num.toString();
let dividingDigit = 0;
for (let i = 0; i < strNum.length; i++) {
if (num % parseInt(strNum[i]) == 0) {
dividingDigit++;
}
if (dividingDigit == strNum.length) {
result.push(num)
//console.log(num)
}
}
}
return result
};
console.log(selfDividingNumbers(1, 22));
To be more concise, you might use .filter check whether .every digit divides evenly:
function selfDividingNumbers(left, right) {
return Array.from(
{ length: right - left },
(_, i) => i + left
)
.filter((num) => {
const digits = String(num).split('');
if (digits.includes(0)) {
return false;
}
return digits.every(digit => num % digit === 0);
});
}
console.log(selfDividingNumbers(1, 22));
When you declare let result = [] inside your for loop you are telling your code to recreate this array every time your loop iterates, thus, removing all previous results pushed into it. Instead, you need to move this outside your for loop to stop this from happening.
Lastly, you need to return only after you're outer for loop is complete, as returning inside your for loop will stop the function from running (and thus stop the loop).
See working example below:
function selfDividingNumbers(left, right) {
let result = [];
for (let j = left; j <= right; j++) {
let num = j;
let strNum = num.toString();
let dividingDigit = 0;
for (let i = 0; i < strNum.length; i++) {
if (num % parseInt(strNum[i]) == 0) {
dividingDigit++;
}
if (dividingDigit == strNum.length) {
result.push(num)
}
}
}
return result
};
console.log(selfDividingNumbers(1, 22));
Related
I am trying to solve a problem , Two Sum for those who know it , I started learning JavaScript coming from Lua , and I am stuck , I don't know why the function returns "undefined" I fill like the variable is defined
var num = [2, 7, 11, 15]
function numbers(target) {
var idx = {}
num.forEach(function(n, i) {
var j = idx[target - n]
if (j) {
var res = '[ ${j} ${i} ]'
return res
}
console.log(n)
idx[n] = i
})
}
console.log(numbers(9))
output:
2
7
11
15
undefined
Problem: https://leetcode.com/problems/two-sum/
I found the solution I think , I don't think it's the best one , but it works
Code:
var nums = [2,7,11,15]
var twoSum = function(target) {
for (let i = 0; i < nums.length; i++) {
for (let j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] == target) {
return [i, j]
}
}
}
}
console.log(twoSum(9))
You have a few issues:
Your current code is returning a string '[ ${j} ${i} ]', you need to return an array [j, i].
Using return from within .forEach() does not return from your numbers function, it instead returns from the inner callback function function(n, i) { which doesn't do much except just skips to the next item in the loop. You need to change your forEach() to a regular for loop so that when you return you return from your numbers function, and not an inner callback.
Your condition if (j) { is flawed. Consider if j is 0, which occurs when the number you're after to add to the current number n is at index 0. In this case, your if-block won't run because 0 is considered falsy. Your condition should instead be more specific by checking that it returned a value if(j !== undefined). See this answer for more details about the condition.
You should be passing nums into your numbers() function rather than relying on a global variable to exist for your function to work correctly.
Example of modified code:
function numbers(nums, target) {
const idx = {}
for(let i = 0; i < nums.length; i++) {
let n = nums[i];
let j = idx[target - n]
if (j !== undefined) {
return [j, i];
}
idx[n] = i;
}
}
console.log(numbers([2, 7, 11, 15], 9));
console.log(numbers([3,2,4], 6));
console.log(numbers([3,3], 6));
See the answers for this question for more details for solving this problem.
var twoSum = function(nums, target) {
let newArr = nums
let sum = 0
outputArr = []
for(let i = 0 ; i < nums.length ; i++){
let val1 = nums[i]
for(let j = 0 ; j < newArr.length ; j++){
if(i !==j) {
let val2 = newArr[j]
if(val1 + val2 === target) {
sum = val1 + val2
outputArr.push(i)
outputArr.push(j)
break;
}
}
}
if(sum === target)
break;
}
return outputArr
};
try this If helps and you need explanation I will help you
I have an array of numbers. I need to find the maximum number of consecutive 1s in the array.
var arr = [1, 1, 3, 2, 3, 1, 1, 1];
const maxOne = (arr) => {
for (var i = 0; i < arr.length; i++) {
let count = 0;
let result = 0;
if (arr[i] ==1) {
count += 1;
result = Math.max(result, count);
} else {
count = 0
}
return result
}
}
console.log(maxOne(arr));
desired output: 3
my output : 1
I am not sure where I am going wrong
You algorithm works, you just did few misstakes:
create variables outside of loop
return after loop, not in it(it will break loop at first iteration)
const maxOne = (arr) => {
let count = 0;
let result = 0;
for (var i = 0; i < arr.length; i++) {
if (arr[i] === 1) {
count += 1;
result = Math.max(result, count);
} else {
count = 0
}
}
return result
}
You can do like this.
let arr=[1,2,3,1,1,2,1,1,12,1,1,1,1];
let count=0;
for(let i=0;i<arr.length;i++){
arr[i]==1 ? count+=1 :count=0;
}
console.log(count).
const numbers = [1,1,0,0,1,1,1,0,1];
const maxString = Math.max(...numbers.join('').split('0')); // remove zero items and convert
// the sequential Ones to a string. After that Find the string with the largest number of characters.
console.log('max:', maxString.toString().length) // Take the string length
//3
you can use *Math.max.apply(Math, numbers.join('').split('0'))* instead of second line.
First of all, any of built-in methods cannot be used. ex. pop(), shift(). What I can use is merely loops, array and so on.
I would like to make a function which takes an array as an argument and generate random strings of numbers, which does not contain these numbers given in the array.
For instance, func([6, 2]) //=> "20353" (2 and 6 would not be there).
The array length could change ([6, 2, 9], [7, 2, 1, 9]). So the function has to have an ability to accommodate any length of an array.
In order to tackle this practice question, I have used for and while loops. However, I ran into a problem that, when the second index is checked (whether numbers randomly generated contain 2 or not, in the example), if it contains, I regenerate the random number and it could produce the first index number (in this case, 6) which I do not want.
Please see the code I posted below and help me solve this. On top of that, if there is another way to get the same result which is a better way, please let me know too.
let str = "";
let arr = [];
let tem
const func = arg2 => {
for (let i = 0; i < 5; i++) {
arr[i] = Math.floor(Math.random() * 10);
}
for (let i = 0; i < arr.length; i++) {
for (let v = 0; v < arg2.length; v++) {
if (arg2[v] == arr[i]) {
do {
tem = Math.floor(Math.random() * 10);
} while (tem == arr[i])
arr[i] = tem;
}
}
}
for (let i = 0; i < arr.length; i++) str += arr[i]
return str
}
console.log(func([6, 2]))
// the output will not contain 2, which is the last index element
// however, when the second index number is removed, the output might replace it with 6, which is the first index element
Expected output:
func([6, 3, 8]) //=> "45102"
func([4, 9]) //=> "55108"
First, you already use two native methods (floor and random), but I'll assume you're OK with that.
Secondly, in your question the term digit would have been more appropriate in some instances than number. There is a difference...
To avoid that you still select a digit that is not allowed, you could first build an array with digits that are still allowed, and then randomly pick values from that array. That way you will not ever pick a wrong one.
Here is how that would look:
const func = arg2 => {
const digits = [0,1,2,3,4,5,6,7,8,9];
// Mark digits that are not allowed with -1
for (let i=0; i<arg2.length; i++) {
digits[arg2[i]] = -1;
}
// Collect digits that are still allowed
const allowed = [];
for (let i=0; i<digits.length; i++) {
if (digits[i] > -1) allowed[allowed.length] = digits[i];
}
// Pick random digits from the allowed digits
let str = "";
for(let i=0; i<5; i++) {
str += allowed[Math.floor(Math.random() * allowed.length)];
}
return str;
}
console.log(func([6, 2]));
Just for fun, if you lift the restrictions on what language aspects cannot be used, you can do this as follows:
const func = arg2 => {
const digits = new Set(Array(10).keys());
for (let digit of arg2) digits.delete(digit);
const allowed = [...digits];
return Array.from({length:5}, () =>
allowed[Math.floor(Math.random() * allowed.length)]
).join``;
}
console.log(func([6, 2]));
I suspect you're overthinking this. The basic algorithm is:
In a loop:
If output has 5 digits, return it.
Otherwise
Pick a random digit n from 0 to 9.
If n is not in the list of excluded numbers, it to output.
This maps pretty directly to the following function:
function fn(exclude, length = 5) {
let output = '';
while (output.length < length) {
const n = Math.floor(Math.random() * 10)
if (!exclude.includes(n)) {
output += n;
}
}
return output;
}
console.log(fn([6,3,8]));
There are, of course, other ways to achieve this, such as initializing an array with five elements and then joining the elements:
function fn(exclude, length = 5) {
return Array.from({ length }, () => {
let n;
while (n = Math.floor(Math.random() * 10), exclude.includes(n)) {}
return n;
}).join('');
}
console.log(fn([6,3,8]));
You need to loop through the entire arg2 array each time you pick a random digit. You can't replace the value in the arg2 loop, because then you won't check against earlier elements.
You don't need the arr array, you can append to str in the loop.
const func = arg2 => {
let str = "";
let arr = [];
for (let i = 0; i < 5; i++) {
let random;
while (true) {
let ok = true;
random = Math.floor(Math.random() * 10);
for (let j = 0; j < arg2.length; j++) {
if (random == arg2[j]) {
ok = false;
break;
}
}
if (ok) {
break;
}
}
str += random
}
return str
}
console.log(func([6, 2]))
Besides the fact (what others stated as well) that you use native array-methods yourself, I would probably go for it with something like this (using only what you used so far):
const func = without => {
let result = '';
while (result.length < 5) {
let rand = Math.floor(Math.random() * 10);
let add = true;
for (i=0; i<without.length; i++) {
if (rand === without[i]) {
add = false;
}
}
if (add) {
result += rand;
}
}
return result;
}
console.log(func([6, 2]))
a more concise version using native array methods could look like this:
const func = without => {
let result = '';
while (result.length < 5) {
let rand = Math.floor(Math.random() * 10);
if (!without.includes(rand)) {
result += rand;
}
}
return result;
}
console.log(func([6, 2]))
I have been working on the two sum problem for the past few hours and can't seem to account for the case where there are only two numbers and their sum is the same as the first number doubled.
The result should be [0,1], but i'm getting [0,0].
let nums = [3,3];
let targetNum = 6;
function twoSum(nums, target) {
for (let i = 0; i < nums.length; i++) {
for (let b = i+1; b < nums.length; b++) {
if ((nums[i] + nums[b]) == target) {
return [nums.indexOf(nums[i]), nums.indexOf(nums[b])];
}
}
}
}
console.log(twoSum(nums, targetNum))
Two Sum
My approach uses a javascript object and completes the algorithm in O(n) time complexity.
const twoSum = (nums, target) => {
let hash = {}
for(i=0;i<nums.length;i++) {
if (hash[nums[i]]!==undefined) {
return [hash[nums[i]], i];
}
hash[target-nums[i]] = i;
}
};
console.log(twoSum([2,7,11,15], 9)); // example
This is not the way to solve the problem. Step through the array and save the complement of the target wrt the number in the array. This will also solve your corner case.
You should consider, indexOf(i) -> start from the first element, returns the index when match found! That is why in your code, nums.indexOf(nums[i]) and nums.indexOf(nums[b]) which is basically 3 in all two cases, it will return 0, cause 3 is the first element in array.
instead of doing this, return the index itself.
let nums = [3,3];
let targetNum = 6;
function twoSum(nums, target) {
for (let i = 0; i < nums.length; i++) {
for (let b = i+1; b < nums.length; b++) {
if ((nums[i] + nums[b]) == target) {
return i + "" +b;
}
}
}
}
console.log(twoSum(nums, targetNum))
I am trying to create a function that builds an array up to a number set by the function parameter, with an if condition on being included based on whether the remainder is zero. The last number in the array should be no higher than the parameter. Here's what I came up with so far --
function justThreesUpTo(num) {
var array = [];
array.length = num;
for (i = 1; i < array.length; i++) {
if(i % 3 === 0){
array.push(i);
}
else i;
}
array.splice(0, num);
return array;
}
When I console log this, with justThreesUpTo(20), I get --
// [ 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42 ]
I see the issue being setting the limiter at array.length, which maxes out the number of items that can be in the array, but I can't figure out what else to call to make sure the last number in the array goes no higher than the "num" parameter specified by the function call. Any ideas?
Setting an array's length to something before the array is populated isn't a great idea - better to just iterate over the num itself. For example
for (var i = 1; i < num; i++) {
// push to array if i % 3 === 0
Your else i won't do anything - you can just leave it off completely.
You could make your code a whole lot shorter and cleaner if you wanted:
function justThreesUpTo(num) {
const length = Math.floor(num / 3);
return Array.from({ length }, (_, i) => (i + 1) * 3);
}
console.log(justThreesUpTo(20));
Modifying an array while looping over it (or its indices, which is what you’re doing with i < array.length) is a recipe for confusion. Start with an empty array and compare with num instead:
function justThreesUpTo(num) {
var array = [];
for (var i = 1; i < num; i++) {
if (i % 3 === 0) {
array.push(i);
}
}
return array;
}
Now you can optimize the check out of that entirely by moving up the appropriate amount each time.
function justThreesUpTo(num) {
var array = [];
for (var i = 3; i < num; i += 3) {
array.push(i);
}
return array;
}
(In your original code, the entire first num holes created by array.length = num; are unused and get spliced off, and else i does nothing.)
You can try with a simple while loop
function justThreesUpTo(num) {
var array = [];
var i = 0;
while (i < num) {
if(i % 3 === 0){
array.push(i);
}
i++;
}
return array;
}
console.log(justThreesUpTo(20));
You can use map method and spread syntax in order to write a clean solution.
function justThreesUpTo(num) {
return [ ...Array(Math.floor(num/3)).keys() ].map((_,i)=> (i+1) * 3);
}
console.log(justThreesUpTo(20));
Hmm. Looks like it was a pretty simple solution. Changed the limiter from "array.length" to "num", and it worked fine.
function justThreesUpTo(num) {
var array = [];
array.length = num;
for (i = 1; i < num; i++) {
if(i % 3 === 0){
array.push(i);
}
else i;
}
array.splice(0, num);
return array;
}
Never mind!
Use while with i+=3; inside the while loop:
function justThreesUpTo(num) {
var array = [];
var i = 0;
while(i<num){
array.push(i);
i+=3;
}
return array;
}
console.log(justThreesUpTo(20));