So I am trying to "write a function Single() that takes a number and returns the number of times you must multiply the digits in num so as to reach a single digit. e.g. Single(456)//4*5*6=120, 1*2*0=0//it takes two loops to to reach the single digit so the return would be 2.
My problem is that now I have to put in an array of individual digits instead of a number. So I probably need to combine the two functions.
function numberToArray(num) {
var tmpString = num.toString();
var tempArray = [];
for (var i = 0; i < tmpString.length; i++) {
tempArray.push(tmpString[i]);
}
return tempArray;
}
function reachSingle(tempArray) {
var count = 0;
var k = 1;
for (var i = 0; i < tempArray.length; i++) {
k *= tempArray[i];
}
count++;
if (k <= 10) return count;
else {
var newArray = numberToArray(k);
return count + reachSingle(newArray);
}
}
document.write(reachSingle([2, 9, 3, 7, 6]));
You could take a recursive approach with an exit condition for numbers smaller than 10 and return in this case zero. Otherwise return one plus the result of the call of the product of the digits.
function reachSingle(n) {
if (n < 10) return 0;
return 1 + reachSingle(Array.from(n.toString()).reduce((a, b) => a * b));
}
console.log(reachSingle(29376)); // 4
Related
I'm doing an interview prep challenge on FCC: https://www.freecodecamp.org/learn/coding-interview-prep/algorithms/no-repeats-please. The function takes a string of letters as an argument and creates all possible permutations of it, so abc becomes
abc, acb, bca, bac, cab, cba . It then returns the amount of permutations that don't have repeated consecutive letters in it, so aab returns 2. I wrote a function that does the job but does it so horribly that it still fails two of the conditions of the test, even though it still does return the correct results…after 46 seconds. But that’s for 7 letters, for a smaller number of letters it works ok. Some code editors will crash if you use 7 letters though, so use a sturdy one like Programiz if you want to run this code. My question is, can this code be modified to pass the test, while still preserving the logic?
function permAlone(arg) {
let length = arg.length
let arr = []
function uniqueIndices() { // generate a set of non-repeating integers to represent indices
let indices = new Array(length)
for (let i = 0; i < indices.length; i++) {
let r = Math.floor(Math.random() * length)
if (indices.indexOf(r) === -1) {
indices[i] = r
} else {
i--
}
}
return indices
}
function factorial(n) {
let product = 1;
for (let i = 2; i <= n; i++) {
product *= i;
}
return product;
}
let length2 = factorial(arg.length) // factorialize the length of arg to set the length of next loop which will be filled with sets of non-repeating integers
for (let i = 0; i < length2; i++) {
let val = uniqueIndices(arg)
if (arr.map(a => a.join('')).indexOf(val.join('')) === -1) { // make sure the sets of integers are all unique
arr[i] = val
} else {
i--
}
}
for (let indices of arr) { // now that we have the unique sets of non-repeating indices, convert each integer in the set to a letter in arg with the corresponding index
for (let i = 0; i < indices.length; i++) {
indices[i] = arg[indices[i]]
}
}
function final(a) { // final function to record the number of sets that have repeated consecutive letters
let ct = 0;
for (let x of a) {
for (let i = 0; i < x.length; i++) {
if (x[i] === x[i + 1]) {
ct++
break;
}
}
}
return ct
}
// to find the number of sets without repeated consecutive letters, substract the number of sets with repeated consecutive letters from arr.length
return arr.length - final(arr)
}
console.log(permAlone(['a', 'b', 'c', 'd', 'e']))
I need to Write a function "giveMeRandom" which accepts a number n and returns an array containing n random numbers between 0 and 10
I can't push generate array of n (arg) length.
It generates only one.
const giveMeRandom = function(n) {
let arrWithNums = [];
for(i = 0; i < n.length; i++) {
return arrWithNums.push(Math.floor(Math.random() * 10));
}
return arrWithNums;
}
console.log(giveMeRandom(4));
n is a number which does not have a length. Just use following for loop:
for (let i = 0; i < n; i++) {...}
Also remove the return statement inside of the loop.
The first problem is n.length. The number 4 has a length of one, and if i < 1 then the loop will not run at all. You just want n in this place instead.
The other problem is that you're returning a value at every repetition of the loop, which stops the function running. Only return a value once at the end to fix this problem.
Here's the full code:
function giveMeRandom(n) {
let arrWithNums = [];
for(i = 0; i < n; i++) {
arrWithNums.push(Math.floor(Math.random() * 10));
}
return arrWithNums;
}
console.log(giveMeRandom(4));
const giveMeRandom = function(n) {
let arrWithNums = [];
for (i = 0; i < n; i++) {
arrWithNums.push(Math.floor(Math.random() * 10));
}
return arrWithNums;
}
console.log(giveMeRandom(6));
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'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));
I am trying to take a given array and iterate through it to create a new array containing only the numbers that are prime from the given array.
What I'm not sure of is the syntax for doing so - I know this is butchered and wrong, but I'm not sure how to fix it? Or if I'm even going about it the right way.
var myArray = isPrime([1,5,17,25,30])
console.log(myArray)
function isPrime(array){
var primes = [];
for(var i = 0; i < array.length; i++){
if(array[i] /= 1 || array[i] / 1 == array[i]){
primes.push([i]);
}
}
return primes;
}
A simple way to do it is creating a isElementPrime(number) function that tells if the number is prime or not (find an implementation here), and loop through it!
function isPrime(array){
var primes = [];
for(var i = 0; i < array.length; i++){
if(isElementPrime(array[i]){
primes.push(array[i]);
}
}
return primes;
}
The idea is to divide the number by every number smaller than it and greater than 1 and see if there is a remainder.
Using filter you can apply this to all elements in the array;
See example:
function isPrime(element) {
for(var i = 2; i < element; i++) {
if(element % i === 0) {
return false;
}
}
return element !== 1;
}
var array = [1, 5, 17, 25, 30];
var primes = array.filter(isPrime);
console.log("array: " + array);
console.log("primes: " + primes);