You are in charge of the cake for a child's birthday. You have decided the cake will have one candle for each year of their total age. They will only be able to blow out the tallest of the candles. Count how many candles are tallest.
Example
Candles = [4,4,1,3]
The maximum height of candles is 4 units high. There are 2 of them, so return 2.
So basically the way I'm doing so is by moving from each place of the array comparing each other with two for cycles, the second cycle will count the repeated numbers, some people use Math.max imported function but I didn't know it before started looking for the answer, and I think this way should work, but can't get to the answer, any ideas?
function birthdayCakeCandles(candles) {
let height=1;
let b=0;
for (let i=0; i<candles.length; i++)
{
for (b=0; b<candles.length; b++)
{
if(b!=i && candles[b]===candles[i])
{height++;}
b++;
}
}
return height;
This should be straightforward, iterate through the array find max if max exists again increase count, if some other element greater than max set it to max and reset count to 1
function findTallestCandleCount(candles){
let max = 0, count = 0
for (let candle of candles) {
if (candle > max) {
max = candle
count = 1
} else if (candle === max){
count++
}
}
return count;
}
I solved it this way
function birthdayCakeCandles(candles) {
let height=0;
let max=Math.max(...candles);
for (let i=0; i<candles.length; i++)
{
if (candles[i]==max)
{height++;}
}
return height;
}
well I solved that challenge with this
function birthdayCakeCandles(candles) {
const maxVal = Math.max(...candles)
//use an array to save all the biggest/max number
const newArr = []
for(let val of candles){
if(val === maxVal) {
newArr.push(val)
}
}
return newArr.length
}
But If you don't want to use Math.max() we have to find biggest value first. we can use for of loop to find max/biggest value like this:
function birthdayCakeCandles(candles) {
let maxVal = 0
//use loop to find the biggest number
for(let val of candles) {
if(val > maxVal) {
maxVal = val
}
if(val < maxVal) {
maxVal = maxVal
}
if(val === maxVal) {
maxVal = maxVal
}
}
//use an array to save all the biggest/max number
const newArr = []
for(let val of candles){
if(val === maxVal) {
newArr.push(val)
}
}
return newArr.length
}
You can try this below.
The logic that i used is that first store the values in newArr[] with candles[0] and Highest numbers from candles[] array. It is because the logic used in first for loop that compares max_val = candles[0] with candles[i]. And so when storing max_val to newArr[], it taking candles[0] and its comparing values (equal to or greatern than candles[0]) along with largest numbers in candles[] array.
Now the second for() loop filtering values based on max_val == newArr[j]. The max_val in first for() loop already loaded with largest value, so that after comparison only largest numbers are filtered and stored into resultArr[]. Then return the function with length property.
var max_val = candles[0];
var newArr = [];
var resultArr = [];
var resultMax;
for(var i = 0; i < candles.length; i++)
{
if(max_val <= candles[i])
{
max_val = candles[i];
newArr.push(candles[i]);
}
}
for(var j = 0; j < newArr.length; j++)
{
if(max_val == newArr[j])
{
resultArr.push(newArr[j]);
}
}
var num = resultArr.length;
return num;
Related
I need help with writing some code that will create a random number from an array of 12 numbers and print it 9 times without dupes. This has been tough for me to accomplish. Any ideas?
var nums = [1,2,3,4,5,6,7,8,9,10,11,12];
var gen_nums = [];
function in_array(array, el) {
for(var i = 0 ; i < array.length; i++)
if(array[i] == el) return true;
return false;
}
function get_rand(array) {
var rand = array[Math.floor(Math.random()*array.length)];
if(!in_array(gen_nums, rand)) {
gen_nums.push(rand);
return rand;
}
return get_rand(array);
}
for(var i = 0; i < 9; i++) {
console.log(get_rand(nums));
}
The most effective and efficient way to do this is to shuffle your numbers then print the first nine of them. Use a good shuffle algorithm.What Thilo suggested will give you poor results. See here.
Edit
Here's a brief Knuth Shuffle algorithm example:
void shuffle(vector<int> nums)
{
for (int i = nums.size()-1; i >= 0; i--)
{
// this line is really shorthand, but gets the point across, I hope.
swap(nums[i],nums[rand()%i]);
}
}
Try this once:
//Here o is the array;
var testArr = [6, 7, 12, 15, 17, 20, 21];
shuffle = function(o){ //v1.0
for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
return o;
};
shuffle(testArr);
This is relatively simple to do, the theory behind it is creating another array which keeps track of which elements of the array you have used.
var tempArray = new Array(12),i,r;
for (i=0;i<9;i++)
{
r = Math.floor(Math.random()*12); // Get a random index
if (tempArray[r] === undefined) // If the index hasn't been used yet
{
document.write(numberArray[r]); // Display it
tempArray[r] = true; // Flag it as have been used
}
else // Otherwise
{
i--; // Try again
}
}
Other methods include shuffling the array, removing used elements from the array, or moving used elements to the end of the array.
If I understand you correctly, you want to shuffle your array.
Loop a couple of times (length of array should do), and in every iteration, get two random array indexes and swap the two elements there. (Update: if you are really serious about this, this may not be the best algorithm).
You can then print the first nine array elements, which will be in random order and not repeat.
Here is a generic way of getting random numbers between min and max without duplicates:
function inArray(arr, el) {
for(var i = 0 ; i < arr.length; i++)
if(arr[i] == el) return true;
return false;
}
function getRandomIntNoDuplicates(min, max, DuplicateArr) {
var RandomInt = Math.floor(Math.random() * (max - min + 1)) + min;
if (DuplicateArr.length > (max-min) ) return false; // break endless recursion
if(!inArray(DuplicateArr, RandomInt)) {
DuplicateArr.push(RandomInt);
return RandomInt;
}
return getRandomIntNoDuplicates(min, max, DuplicateArr); //recurse
}
call with:
var duplicates =[];
for (var i = 1; i <= 6 ; i++) {
console.log(getRandomIntNoDuplicates(1,10,duplicates));
}
const nums = [1,2,3,4,5,6,7,8,9,10,11,12];
for(var i = 1 ; i < 10; i++){
result = nums[Math.floor(Math.random()*nums.length)];
const index = nums.indexOf(result);
nums.splice(index, 1);
console.log(i+' - '+result);
}
As can be seen from the title I'm having some issues getting my code to work. If I choose min, max, or sum, they post the correct output but then the other two buttons return undefined for min/max if Sum was done first and return as 0 sum if min or max was chosen first. Any and all help is appreciated, apologies for my ignorance.
Here is what I've been working with:
function GetSum(){
for (var index = 0; index < arr.length; index++) {
number += arr[index];
}
return number;
}
function ShowSum(){
let sum = GetSum();
if(arr = !isNaN && arr.length> 0){
return sum;}
ShowData("sum",sum);} //ShowData posts the sum to HTML page
function GetMaximum(){
let i;
var largest =arr[0];
for(i = 1; i < arr.length; i++){
if(arr[i]>largest) { largest = arr[i];
}return largest;
}console.log(largest); }
// this all works fine, then when other buttons are chosen it's no go
function ShowMax(){
let maxNum = GetMaximum(arr);
if(arr = !isNaN && arr.length> 0){
return maxNum
} ShowData("max",maxNum);}
Why is ShowMax displaying the correct result, but unidentified when I've already used ShowSum?
It's the same testing in the console too. Same with ShowSum returning 0 once I've had a correct go with ShowMax. Thanks everybody
you have multiple problem, isNaN() is a function to check if string is number or not, then use parseInt() to convert string to number.
the GetMaximum() will not alyways return largest number because it set return in for loop and there will be remaining value.
function GetSum() {
let number = 0;
for (var index = 0; index < arr.length; index++) {
if (!isNaN(arr[index]))
number += parseInt(arr[index]);
}
return number;
}
function ShowSum() {
let sum = 0;
if (arr.length > 0) {
sum = GetSum();
}
ShowData("sum", sum);
return sum;
}
//ShowData posts the sum to HTML page
function GetMaximum() {
let i, largest = 0;
for (i = 1; i < arr.length; i++) {
let num = isNaN(arr[i]) ? 0 : parseInt(arr[i]);
if (num > largest) {
largest = parseInt(arr[i]);
}
}
//console.log(largest);
return largest;
}
function ShowMax() {
let maxNum = 0;
if (arr.length > 0) {
maxNum = GetMaximum(arr);
}
ShowData("max", maxNum);
return maxNum
}
function ShowData(...args) {
return console.log(args.join(' '))
}
var arr = [2.3, 6, 8, 1];
ShowMax()
ShowSum()
I'm trying to understand why my solution to this problem is only partially working.
Problem:
Given a sorted array nums, remove the duplicates in-place such that each element appears only once and returns the new length.
Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.
My Solution:
var removeDuplicates = function(nums) {
if (nums.length === 0) return 0;
for (let i = 1; i <= nums.length; i++){
if(nums[i] === nums[i-1]){
nums.splice(nums[i], 1);
}
}
return nums.length;
};
This is the outcome I'm getting on leetcode but I don't understand why my solution stops working and the '3s' are not removed?
Output screenshot:
When you splice an array while iterating over it, the whole array will change in-place. For example, let's say that indexes 0 and 1 are duplicates (i is 1). Then, if you remove index 1 from the array, what used to be at index 2 will now be at index 1, and what used to be at index 3 will now be at index 2, etc.
So, you need to subtract 1 from i when an element is removed, otherwise the next element will be skipped.
You also have an off-by-one-error - iterate i from 1 to i < nums.length so you don't go past the end of the array.
You also need to pass the index to remove to splice, not the value to remove.
var removeDuplicates = function(nums) {
for (let i = 1; i < nums.length; i++){
if(nums[i] === nums[i-1]){
nums.splice(i, 1);
i--;
}
}
return nums.length;
};
console.log(removeDuplicates([0, 0, 0]));
Simple version. Using functions already created
let array = new Set(nums);
let values = array.values();
return Array.from(values);
This'd also pass just fine on constant memory:
const removeDuplicates = function (nums) {
let count = 0;
nums.forEach(function (num) {
if (num !== nums[count]) {
nums[++count] = num;
}
});
return nums.length && count + 1;
};
function removeDuplicates(nums) {
let i = 0;
while(i < nums.length - 1) {
i += 1 - ((nums[i] === nums[i+1]) && nums.splice(i, 1).length)
}
return nums.length;
}
C# simple solution:
public int RemoveDuplicates(int[] nums) {
if (nums.Length == 0)
return 0;
var i = 0;
var start = 0;
var end = 0;
while (end < nums.Length)
{
if (nums[start] != nums[end])
{
nums[++i] = nums[end];
start = end;
}
end++;
}
return i + 1;
}
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 need help with writing some code that will create a random number from an array of 12 numbers and print it 9 times without dupes. This has been tough for me to accomplish. Any ideas?
var nums = [1,2,3,4,5,6,7,8,9,10,11,12];
var gen_nums = [];
function in_array(array, el) {
for(var i = 0 ; i < array.length; i++)
if(array[i] == el) return true;
return false;
}
function get_rand(array) {
var rand = array[Math.floor(Math.random()*array.length)];
if(!in_array(gen_nums, rand)) {
gen_nums.push(rand);
return rand;
}
return get_rand(array);
}
for(var i = 0; i < 9; i++) {
console.log(get_rand(nums));
}
The most effective and efficient way to do this is to shuffle your numbers then print the first nine of them. Use a good shuffle algorithm.What Thilo suggested will give you poor results. See here.
Edit
Here's a brief Knuth Shuffle algorithm example:
void shuffle(vector<int> nums)
{
for (int i = nums.size()-1; i >= 0; i--)
{
// this line is really shorthand, but gets the point across, I hope.
swap(nums[i],nums[rand()%i]);
}
}
Try this once:
//Here o is the array;
var testArr = [6, 7, 12, 15, 17, 20, 21];
shuffle = function(o){ //v1.0
for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
return o;
};
shuffle(testArr);
This is relatively simple to do, the theory behind it is creating another array which keeps track of which elements of the array you have used.
var tempArray = new Array(12),i,r;
for (i=0;i<9;i++)
{
r = Math.floor(Math.random()*12); // Get a random index
if (tempArray[r] === undefined) // If the index hasn't been used yet
{
document.write(numberArray[r]); // Display it
tempArray[r] = true; // Flag it as have been used
}
else // Otherwise
{
i--; // Try again
}
}
Other methods include shuffling the array, removing used elements from the array, or moving used elements to the end of the array.
If I understand you correctly, you want to shuffle your array.
Loop a couple of times (length of array should do), and in every iteration, get two random array indexes and swap the two elements there. (Update: if you are really serious about this, this may not be the best algorithm).
You can then print the first nine array elements, which will be in random order and not repeat.
Here is a generic way of getting random numbers between min and max without duplicates:
function inArray(arr, el) {
for(var i = 0 ; i < arr.length; i++)
if(arr[i] == el) return true;
return false;
}
function getRandomIntNoDuplicates(min, max, DuplicateArr) {
var RandomInt = Math.floor(Math.random() * (max - min + 1)) + min;
if (DuplicateArr.length > (max-min) ) return false; // break endless recursion
if(!inArray(DuplicateArr, RandomInt)) {
DuplicateArr.push(RandomInt);
return RandomInt;
}
return getRandomIntNoDuplicates(min, max, DuplicateArr); //recurse
}
call with:
var duplicates =[];
for (var i = 1; i <= 6 ; i++) {
console.log(getRandomIntNoDuplicates(1,10,duplicates));
}
const nums = [1,2,3,4,5,6,7,8,9,10,11,12];
for(var i = 1 ; i < 10; i++){
result = nums[Math.floor(Math.random()*nums.length)];
const index = nums.indexOf(result);
nums.splice(index, 1);
console.log(i+' - '+result);
}