leetcode house robber incorrect output - javascript

I was doing this leetcode question: https://leetcode.com/problems/house-robber/
The question is
You are a professional robber planning to rob houses along a street.
Each house has a certain amount of money stashed, the only constraint
stopping you from robbing each of them is that adjacent houses have
security system connected and it will automatically contact the police
if two adjacent houses were broken into on the same night.
Given a list of non-negative integers representing the amount of money
of each house, determine the maximum amount of money you can rob
tonight without alerting the police.
With following example
Input: nums = [1,2,3,1]
Output: 4
Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).
Total amount you can rob = 1 + 3 = 4.
I wrote the following code for this
/**
* #param {number[]} nums
* #return {number}
*/
var rob = function(nums) {
if (nums.length === 0) return 0
let output = i = 0
while (i < nums.length) {
const currentHouse = nums[i]
i = i + 2
output += currentHouse
}
return output
};
console.log(rob([1, 2]));
console.log(rob([1, 2, 3, 1]));
but it fails for this particular
Input:
[1,2]
Output:
1
Expected:
2
I am not sure why the output should be 2 for the above test?

Your algorithm just takes the houses at even indexes without taking into account that you have different options.
For instance when there are 5 houses (numbered 0 to 4) you can consider the following alternatives:
rob house 0, 2 and 4
rob house 0 and 3
rob house 1 and 3
rob house 1 and 4
Each of these could be the optimal strategy for the robber... it all depends on the amounts of money in the houses. For instance:
When input is [1,1,1,1,1] then strategy 1 is optimal and your program produces the correct output (3)
When input is [2,1,1,3,1] then strategy 2 is optimal (5), while your program will output 4.
When input is [1,2,1,3,1] then strategy 3 is optimal (5), while your program will output 3.
When input is [1,3,1,1,2] then strategy 4 is optimal (5), while your program will output 4.
Once you realise you need to look at different patterns, you can see that sometimes you need skip a house even if it was not adjacent to a previously robbed house. It is also not guaranteed that robbing the first house is optimal. On the other hand, it is never optimal to skip 3 houses in row, as you then might as well rob the middle of those, as it is not adjacent to another robbed house.
You can have an algorithm that progressively adds a house to the problem, and keeps track what was the best for the two previous sub problems (so with 2 or 1 fewer houses).
We can then look at the situation where we rob the newly added house or not. If we rob it, we should add the money to the money we got from the problem with 2 fewer houses. If we don't rob it, we should just copy what we got from the problem with 1 fewer houses.
This is a so-called bottom up approach:
function rob(nums) {
// Represent the optimal amount we get from a problem with fewer houses:
let sumTwoHousesLess = 0;
let sumOneHouseLess = 0;
let sum = 0; // The amount for a problem without any houses.
for (let money of nums) { // Add a house to the problem in each iteration
// See what is best: rob this house or not:
sum = Math.max(money + sumTwoHousesLess, sumOneHouseLess);
// Shift the information we have, as we are about to go to the next house
sumTwoHousesLess = sumOneHouseLess;
sumOneHouseLess = sum;
}
return sum;
}
console.log(rob([1,2])); // 2
console.log(rob([1,1,1,1,1])); // 3
console.log(rob([2,1,1,3,1])); // 5
console.log(rob([1,2,1,3,1])); // 5
console.log(rob([1,3,1,1,2])); // 5

Related

Calculate chance for a given dice roll when using multiple dice

I'm having a variable number of dice and dice types (eg. 4-side, 6-sided, etc), but dice types are never mixed. I need to calculate the probability of a certain outcome using any variation of dice and sides. For example, given 3 six-sided dice (which we'll write as 3d6), the probability of rolling 3 is 0.46% (100 / 6^3 = 0.46).
Probability = Number of desired outcomes รท Number of possible outcomes
Number of possible outcomes: Number of sides to the power of the number of dice, eg. 6^3.
Number of desired outcomes: ?
The application for this is that the dice formula can have modifier, ex. 3d6-5, and I'd like to calculate the chance that the outcome is zero or lower.
Thus, I was thinking that by adding up the percentages of to sum the total chance. Example (using anydice.com), for (3d6)-5, I'd add the chance for rolls of 3 (0.46%),4 (1.39%), 5 (2.78%), to come to the conclusion that there is a 4.63% chance of rolling equal to or lower than 0.
I'm looking for a somewhat efficient way to do this in Javascript somehow.
EDIT: Order matters! a roll of 6, 1 and 2 is not the same as 1, 2 and 6. This is not a combinatorics problem, as presented in the Medium article suggested by Barmar.
EDIT: Comments ask (rightfully so) for code. As I don't have a hypothesis on how to calculate it, I don't have much to that end, but this is what I do have:
function dieAvg(sides) {
return ((sides+1)/2);
}
// dice = number of dice
// die = sides, eg. 6 for a square dice
// mod = a modifier, positive or negative to apply to the result
function getDiceStats(dice, die, mod) {
let avg = (dieAvg(die)*dice) + mod;
let min = dice + mod;
let max = die*dice) + mod;
let zeroChance = 0; // TODO!
return [min,max,avg, zeroChance];
}
Somewhat related question (java): Calculate the number of ways to roll a certain number

Logic for my land size calculator application

I'm making this acres and karats calculator for my uncle to help him in his work.
I'll explain the whole idea of this thing with this example. So if you add 3.22 + 2.2 it should be = 5.42 but in this calculator 3.22 + 2.2 should = 6, because 3 acres + 2 acres = 5 acres and 22 karats + 2 karats = 1 acre, so the total would be 6 acres.
The way I'm doing it in the code is that I'm splitting a number like 3.22 to two, 3 and 22 and the other number to 2 and 2 and I add the whole numbers together and the fractions together and if the fractions are >= 24 I add one to the whole numbers and if there're fractions left from the whole calculation I leave it. For example 3.15 + 2.15 = 6.6, but I'm stuck on how I can add the numbers, there's also an error in there that I don't know how to resolve.
Anyway here's the code
function getValue(v) {
return +v.toString().match(/\.(\d*)/)[1] || 0;
}
function getTotal() {
d += Math.floor(num);
p += getValue(num);
if (p >= 24) {
p -= 24;
++d;
}
total = d + p / 100;
ptag.textContent = total;
}
I added the part of the code where I'm stuck.
Note: I'm trying to make the thing able to add multiple numbers not only two. Also I'm trying to add subtraction but I have no idea how to start working on the subtraction because I haven't even finished the addition.
If the error you are talking about is something like this:
Uncaught TypeError: Cannot read property '1' of null
It is because of your getValue function.
My suggestion is, instead of using something as complicated as
function getValue(v) {
return +v.toString().match(/\.(\d*)/)[1] || 0;
}
use
function getValue(v) {
return floor((v % 1) * 100);
}
This has the same effect as the code you wrote. Which for example, from input 3.13, returns 13.
But there are few other problems.
First, you should update your num variable every now and often, otherwise, it is always going to stay as an empty string (you only defined it on line 20, and you didn't update it after that).
Second, you should clear the d and p variable after you use. As of right now, both of these variables just keeps on increasing every time you run the getTotal function
For your question of how you can add two numbers, I suggest you to create a variable where you can store the first number that the user typed.
For example, when the user typed in 4.19 and pressed the plus button, save that 4.19 into a variable (let's say firstNum).
Then when the user pressed equal button, add the number from the current input field with the firstNum variable.
On how exactly you are going to add two different numbers, break two numbers you want to add into Acres part and Karats parts. Then add them separately, then use your getTotal.
So if the number is 3.21 and 5.18, add 3 and 5, add 21 and 18, then add both of them.
you'll get 8.39. Finally, convert 8.39 into 9.15.
Sorry if my calculation is not correct. It is my first time with this concept!
But I believe this is the way to go.

Determining Powers of 2?

I am creating a simple bracket system and I need a way to check if there are a correct number of teams, OR if my program needs to compensate for bye rounds.
Right now, I am checking for "powers of two" with this function:
function validBracket(data) {
var x = data.teams.length;
return ((x != 0) && !(x & (x - 1)));
}
This works pretty well, but I am needing to know how many Bye rounds to add.
For instance, if I had 16 teams, I would not need to add anymore teams. However, if I had 12 teams, I would need the first 4 teams to get a bye round.
How can I calculate number of bye rounds to add to my bracket? And would hard-coding an array of powers of two be better?
In pseudo code, something like this is what i was thinking of:
if(validateBracket(data)) {
// Valid number of teams (power of two). Keep going.
} else {
var byeRounds = calculateByeRounds();
}
NOTE: I would rather not use an array of powers of two like below:
var powersOfTwo = [2,4,8,16,32,...];
The reasoning behind this is that I would be limiting the number of teams that could be put in the system (however, I don't think a person would have over 256 teams).
var needed = (1 << Math.ceil(Math.log2(n))) - n;
More generalized solution for extreme cases:
var needed = Math.pow(2, Math.ceil(Math.log2(n))) - n;

Understanding a function with modulo in Javascript

I had this code written by a user here yesterday and I'm having trouble understanding it. I understand all by line 9 of the deal function, it creates a random card out of 52 numbers but on the next line I don't understand what this does. Could somebody please explain what this code does so I could modify it and expand on it?
//Creates the deck
var Ace = 1;
var Face = 10;
var deck = [Ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, Face, Face, Face];
/*Creates a deal function that can deal cards to each player.
Use object_name.property_name = deal() to call this function.*/
var deal = function () {
var randomcard = Math.ceil(Math.random() * 52) + 1;
return deck[Math.floor(randomcard % 13)];
};
Well, first let's correct the code. The original code does give you a working result, but it does it in a confusing way. It doesn't pick a value between 0 and 51 which would be the natural thing to do, it picks a value between 2 and 53. (The result is still useful for getting a value between 0 and 12 to use for a value, but getting the suit for the card is not very straight forward.)
var randomcard = Math.floor(Math.random() * 52);
return deck[randomcard % 13];
The modulo operator gets the reminder from a division, so the result from the expression would get the value for the card. Up to 12 it returns the number itself, then at 13 it starts over at 0 again.
To get the index for the suit for the card, you would use Math.floor(randomcard / 13). With the original random value (2 to 53) you would have needed to use (Math.floor(randomcard / 13) % 4) instead.
There are 52 cards in the deck. 13 different values with 4 different suit( clubs/diamonds...). Note 4 * 13 = 52. The modulus 13 is just there to assure that one of the values from in the deck variables gets picked, and the suit is ignored.
You have an array of only 13 items -- the cards. 0 through 12.
If you take any number and % 13 it, you will always get a value between 0 and 12 -- the remainder of a division of that number by 13. The deck of 52 then % 13 basically reduces the deck from suit + card to just card.
This could have equally been written as Math.ceil(Math.random() * 13) + 1 instead of 52. However if the code needs to be expanded to also have a suit, then you might likely
The code is only half-valid. The modulo is poorly selecting the type of card to draw out of the deck, but not the suit the card is. In addition, the code doesn't account for having already dealt out a specific card (it's never removed from the deck), so multiple players could have identical cards.
See this page for information on how deck structure looks in JavaScript:
http://www.brainjar.com/js/cards/default2.asp

How to use bitwise operators to return bits that have 0

I've been struggling for quite a long time on this problem. This is a follow-up question on this answer (How to divide x number of players into 2 teams randomly multiple times, differently every time?).
So, I have x number of players, and for each I give 1 << n mask value. By using those masks I can easily form a match with 2 players in each team. Now, if total number of players is 5, one possible match could be like this:
01100 team a
00011 team b
------------
10000 player resting
or with 6 players it could look like this:
100010 team a
001001 team b
-------------
000100 player resting
010000 player resting
Question
How can I get those resting players by comparing team a and team b masks together? (I'm a total bitwise noob so code examples are well appreciated)
Thanks
Do XOR on value of team A and B:
var resting = a ^ b;
Then resting players will be marked by 0, i.e:
100010 team a
001001 team b
-------------
101011 players resting
Finally, iterate through each bit of the result:
var totalPlayers = 6;
for (var i = 1; i <= totalPlayers; i++) {
if ((resting & 1) === 0) {
console.log("Player #" + i + " is resting.");
}
resting >>>= 1;
}
Here's live example: http://ideone.com/Kb3XJ (in Java, not JavaScript, but that's not the issue)
You can bitwise OR them together then NOT it to get all the resting players. You would then have to go bit by bit to get the separate resting players.
100010
001001
------OR
101011 #all players playing
------NOT
010100 #all players not playing

Categories