I was doing some basic linear search exercises (I've been coding for 2 months or so) with javascript and stumbled upon the following problem:
I get input from the user that goes to an array and the program tells in which position of the array the number they decided to retrieve is. I wanted to do something clean like "I've retrieved the number 69 for you. It was on the 22nd position of the array of inputs you created."
So I wanted to check the last digit of the number and respond accordingly with X1st, X2nd and X3rd or Xth.
But I don't know how to check the last digit of the desired number. Should I convert it into a string and then check with the .pop() function?
I only accounted for 30 inputs. But I would like for it to work not depending on a set number of inputs.
let inputsArray = [];
let totalInputs;
do
{
totalInputs = Number(prompt("How many number do you want to input? (max. 30)"));
}
while(totalInputs >= 31 || totalInputs <= 0)
for(i = 0; i < totalInputs; i++) //Get the inputs from the user and add them into the inputsArray
{
let input = Number(prompt("Type a number"));
inputsArray.push(input);
}
let desiredNum = Number(prompt(`What number do you want to retrieve? (Select from ${inputsArray})`));
let validator = 0;
for(i = 0; i < inputsArray.length; i++) //Check on each index of the inputsArray for the number prompted
{
if(inputsArray[i] == desiredNum)
{
if (i + 1 == 1 || i + 1 == 21) //Tell the user which position in the array the prompted number was
{
alert(`I've retrieved the number ${desiredNum} for you. It was on the ${i+1}st position on the array of numbers you created.`);
validator++;
}
else if (i + 1 == 2 || i + 1 == 22)
{
alert(`I've retrieved the number ${desiredNum} for you. It was on the ${i+1}nd position on the array of numbers you created.`);
validator++;
}
else if (i + 1 == 3 || i + 1 == 23)
{
alert(`I've retrieved the number ${desiredNum} for you. It was on the ${i+1}rd position on the array of numbers you created.`);
validator++;
}
else
{
alert(`I've retrieved the number ${desiredNum} for you. It was on the ${i+1}th position on the array of numbers you created.`);
validator++;
}
}
}
if(validator != 1) //If the desiredNum is invalid
{
alert("The number you specified does not exist in the array.");
}
What if you tried a modulo operator like
last_digit = number % 10;
Yes, the easiest way would be just convert to string:
var str_number = number.toString(); //converts number to string
var last_char = str_number.slice(-1); //gets last character
var last_digit = +(last_char); //convert last character to number
No need to convert to string. Let's just address what we are looking for with the number. The case is either 0, 1, 2, or other; the +1 you use is not necessary for computing this.
You can use % (modulo) here in order to check what the last digit is. Ensure that it avoids the edge case of 12nd with an extra condition.
This will allow for a single response to be issued instead of looking at multiple cases.
var desiredNum = 20;
var suffixes = ["st","nd","rd"];
var suffix = num => (num < 4 || num > 13) && suffixes[num%10] ? suffixes[num%10] : "th";
for(let i = 0; i < 56; i+=11)
console.log(`I've retrieved the number ${desiredNum} for you. It was on the ${(i+1)+suffix(i)} position on the array of numbers you created.`);
I have the following code
let range = [1,2,3];
let multiples = [1,2,3,4,5,6,2,4,6,3,6];
I want to find the first number in the multiples array that occurs range.lenght times (3);
I want to start with multiples[0] check how many times it occurs in multiples, if it occurs 3 times I want to return multiples[0], if it is less than 3 times, I want to check how many times multiples[1] occurs in the multiples array. If multiples[1] occurs 3 times I want to return multiples[1], else I move on to check multiples[2], etc. until I find a number that occurs 3 times. In the code above I should return 6.
I've looked at
How to count the number of certain element in an array?
and
Idiomatically find the number of occurrences a given value has in an array
and
get closest number out of array
among other research but have not figured it out yet.
I tried to simplify the question as much as possible. But if more info is needed it relates to this challenge on freeCodeCamp. Where I am at with my code is
function smallestCommons(arr) {
let sortArr = arr.sort((a, b) => a - b);
console.log(sortArr);
let range = [];
for (let i = sortArr[0]; i <= sortArr[1]; i++) {
range.push(i);
}
console.log("range = " + range);
let maxNum = range.reduce( (a, b) => a * b);
console.log("maxNum = " + maxNum);
let multiples = [];
for (let i = 0; i < maxNum; i++) {
let j = 0;
do {
multiples.push(j + range[i]);
j += range[i];
} while (j < maxNum);
//j = 0;
}
for (let i = 0; i < multiples.length; i++) {
let numberToFind = multiples[i];
/*stuck here hence my question, maybe I shouldn't even start with a for loop*/
//tried reduce, forEach, filter, while loop, do while loop
}
console.log("multiples = " + multiples);
}
console.log(smallestCommons([1,3]));
The logs are
1,3
range = 1,2,3
maxNum = 6
multiples = 1,2,3,4,5,6,2,4,6,3,6,NaN,NaN,NaN
What you can do is, first split your string with , and then using below function loop for check.
function countLength(arr, checkNumber) {
var count = 0;
for (var i = 0; i < arr.length; i++) {
if (arr[i] === checkNumber) {
count++;
}
}
return count;
}
countLength(list, NUMBER YOU WANT TO CHECK);
And if you want to check first number occur for 3 time then you need to make change in function and introduce .map or .filter in action to count number.
Example
const multiples = [1,2,3,4,5,6,2,4,6,3,6];
let occurance_arr=[];
const aCount = [...new Set(multiples)].map(x => {
if(multiples.filter(y=> y==x).length == 3) {
occurance_arr.push(x);
}
});
console.log(occurance_arr);
Above code will give you 6 in console, if you have multiple value then 0th element is the answer you are looking for which is first three time occurrence of item.
You can loop through your list keeping an object that maps each number to the number of times you've seen it. You can check the counts object as you loop, so if you see a number and the count is one less than your target, you can return it. If you make it through the loop without returning you didn't find what you're looking for — return something sensible :
let range = [1,2,3]
let multiples = [1,2,3,4,5,6,2,4,6,3,6]
function findFirstMult(arr, len){
let counts = {} // to keep track of how many times you've seen something
for (let n of arr){ // loop throught the array
if (!counts[n]) counts[n] = 0 // if it's then first time you've seen n, defined that key
if (counts[n] == len - 1) return n // found it
counts[n] +=1 // otherwise increase the count
}
return undefined
}
console.log(findFirstMult(multiples, range.length))
This will require only one loop through the array in the worse case and will return early if if finds something.
If a number, when divided by two, has a remainder that is not equal to 0, this number must be odd. I'm trying to use that logic in my if statement to keep only odd values, and get rid of even ones. I'm not sure how I'm doing this wrong, but myArray is returning even values as well as odd. Any ideas?
function sumFibs(num) {
var myArray = [1,1];
// Create fibonacci sequence
// Stop creating fibonacci numbers at num
// Push odd numbers to oddNums array
for (var i = 0; i < myArray.length; i++) {
if (myArray[i+1] + myArray[i] <= num && myArray[i+1] + myArray[i] % 2 !== 0) {
myArray.push(myArray[i+1] + myArray[i]);
}
} // End loop.
console.log(myArray);
// Summation of oddNums array.
return myArray.reduce(function(a,b) {
return a + b;
});
} // End function.
sumFibs(1000);
You are trying to filter odd values while generating your fib sequence, which probably not the best approach. If you wrap the modulo expression in parentheses,
(myArray[i+1] + myArray[i]) % 2
Your array will not contain the values necessary to continue generating the sequence. Ideally you should generate the full fib series and then filter:
var myArray = [1,1];
for (var i = 0; i <= num; i++) {
myArray.push(myArray[i+1] + myArray[i]);
} // End loop.
myArray = myArray.filter(function(a){ return a%2 !== 0 })
or save some reference to the even values so that they can be used to calculate the desired subset of the series.
I have a project i'm working on.
I am to basically recreate lotto on the client side using javascript to generate 6 random numbers plus a bonus ball. as we all know, lotto numbers cannot be the same. this is where my question comes in.
Is it possible to remove a number that has been generated from being available in the next time round in the loop? This would make the function completely random. or do I need to still compare the number with the others in the array using indexOf?
for example, is the following possible?,
the first number that generates is 25,
the function then removes that number from being able to come up again.
so on...
Here is my js code,
function play(){
numbersArray = [];
for (i=0; i<=6;){
n = Math.floor(Math.random()*40)+1;
a = numbersArray.indexOf(n);
if ( a == "-1"){
numbersArray[i] = n;
i++;
var ballId = "ball"+i;
if( i != "7"){
document.getElementById(ballId).innerHTML = '<p>'+ n +'</p>';
} else {
document.getElementById("bonus").innerHTML = '<p>'+ n +'</p>';
}
} //end of if
}//end of for loop
}//end of play function
You need to create an object, in this case you could use an array, that holds all the possible numbers that can appear on the ball, we'll cal it n. Then you can use a while loop to keep picking numbers from that array, and splice/remove that specific number from the array on every iteration.
function play(n) {
var picks = [];
// Store possibilities in the numbersArr array
var numbersArr = [];
// n is the max number you can choose to appear on a ball
for ( var i = 0; i < n; i++ ) {
numbersArr.push(i);
}
while (picks.length < 7){
var randomIndex = Math.floor(Math.random() * numbersArr.length);
picks.push(numbersArr[randomIndex]);
numbersArr.splice(randomIndex, 1);
}
return picks;
}
I have 2 arrays of numbers. I want to go through each array and find the number of times 1 number from each array adds up to the particular amount x.
If the particular amount x is reached as many times as another set number n then the function should print 'YES'. If x does not reach the set number of n then the function should print 'NO'.
The values of x , n and both arrays are in a string input. These values have been split into arrays as seen below in the code.
I have set up 2 for loops to run through each array and an if statement that checks for the condition of x meeting n.
The arrays I'm using in this code should print out the result of 'YES' however every time I run the code I'm getting 'NO' ? I've tried tinkering with the code but nothing has worked.
Any idea on where this code is broke and how to fix the problem?
Thanks :)
code:
var input = '2\n3 10\n2 1 3\n7 8 9';
function processData(input) {
var inputArray = input.split('\n');
var n = inputArray[1][0];
var x = inputArray[1].split(' ')[1];
var arrayA = inputArray[2].split(' ');
var arrayB = inputArray[3].split(' ');
var total = 0;
for(var i = 0; i < arrayA.length; i++) {
for(var j = 0; j < arrayB.length; j++) {
if(arrayA[i] + arrayB[j] == x) {
total = total + 1;
} if (total == n) {
return 'YES';
}
}
}
return 'NO';
}
console.log(processData(input));
arrayA[i] and arrayB[j] are strings, so arrayA[i] + arrayB[j] will be the concatenation of them (ex: '2' + '3' === '23').
If your logic is correct (i didn't quite understand what you are trying to do), it should be enough to convert them to numbers before adding them, using parseInt or some other method:
if(+arrayA[i] + (+arrayB[j]) == +x) { // used unary + to convert to number
total = total + 1;
} if (total == n) {
return 'YES';
}
PS: A cleaner version would be to convert each string in the array to number, but that involves more than adding 3 characters to your code.
PS2: You have a weird way of getting the input data. If you get it from another place in your JS code, you could simply pass it as an object with the relevant structure, otherwise you could pass it around in a more ... common format, like JSON.