I have no idea why this code doesn't work, could anyone help:
toDecimal: function () {
var counter = 0;
var decimalValue = 0;
for (var i = 7; i > 0; i--){
var binaryValue = self.binaryArray[i];
decimalValue += binaryValue * Math.pow(2, counter);
counter++;
}
return decimalValue;
}
the code self.binaryArray is just an array of numbers (contains only 8, a byte, that's all i need to work with) something like this [0,0,0,0,1,1,1,1]
2nd'ly
Can you provide a slicker way of doing the counter, for the life of me I can't figure out how to calculate the counter from the i value, which shouldn't be too difficult, simple maths really.
Thanks
Your original loop never processes binaryArray[0]. As to a "slicker" way of doing things, assuming that binaryArray[0] is the most significant bit, I'd write your loop like this:
toDecimal: function () {
var decimalValue = 0;
for (var i = 0; i < 8; i++){
decimalValue = (decimalValue << 1) + self.binaryArray[i];
}
return decimalValue;
}
(The left shift is just a quick way of multiplying by 2.)
However, I like StephenH's suggestion:
toDecimal: function () {
return parseInt(self.binaryArray.join(''), 2);
}
Why not just use JavaScript's built in parseInt function?
Syntax: parseInt(string, radix);
var n = parseInt("10001",2);
n = 17
Related
I am trying to run a program that, upon receiving a positive integer, splits it into its separate digits like so. Number is 652, output is 2, 5, 6. There is supposed to no arrays and I can't make the number a string. I've written most of the code but it's missing something that I can't figure out. The issue is really that I don't know how to store the numbers to be output during iterations. Would appreciate any help. I am using a while loop but for loop could be used as well.
function problem_09() {
var outputObj=document.getElementById("output");
var a = parseInt(prompt("Please enter a number: ", ""));
var i = 0;
var digits = ;
outputObj.innerHTML="number: "+a+"<br><br>its digits: ";
while (a>0) {
digits[i]= a%10;
a = Math.floor(a/10);
i++;
}
outputObj.innerHTML=digits;
outputObj.innerHTML=outputObj.innerHTML+"<br><br>"+"program ended";
document.getElementsByTagName("button")[0].setAttribute("disabled","true");
}
I know the issue lies with the digits and the i but I don't know how to fix it.
You could take a place value and multiply by 10 for each iteration.
function getDigits(value) {
var place = 1;
while (value >= place) {
console.log(Math.floor(value / place) % 10);
place *= 10;
}
}
getDigits(652);
getDigits(100);
A solution without using Math.floor(...)
function getDigits(n) {
var res = [];
while (n > 0) {
var r = n % 10,
d = n - r,
curr = d / 10;
n = curr;
res.push(r);
}
return res;
}
var n = prompt("Enter a number: "),
output = document.getElementById("output");
output.textContent = getDigits(+n);
<div id="output"></div>
then just to replace
var i = 0;
var digits = [];
while (a > 0) {
digits.push(a % 10);
a = Math.floor(a/10);
i++;
}
the question does not make really sense.. without arrays, but he is actually expecting the result to be an array...
I would like to sum the given factorials numbers in javascript
'1! + 2! + 3! + ... + n!'
You may use factorial function :
Iterative function:
function sFact(num)
{
var rval=1;
for (var i = 2; i <= num; i++)
rval = rval * i;
return rval;
}
Recursive
function rFact(num)
{
if (num === 0)
{ return 1; }
else
{ return num * rFact( num - 1 ); }
}
I copied these function from this link.
Now what can you do is.
Suppose n value is 6.
var n = 6;
var sum = 0;
for(var i=1;i<=n;i++)
{
sum = sum + rFact(i);//Here you can use one of factorial funciton. I am using recursive function
}
document.print("The answer is "+ sum );
The naïve solution would be to actually calculate every factorial and add them together, which has a complexity of O(n²). However, if you're clever, you can design an algorithm that solves the same problem with a complexity of O(n). Take a look at the pattern of the following example that calculates the sum of the factorials of 1 through 4.
1!+2!+3!+4! =
1+1*2+1*2*3+1*2*3*4
Notice how you're reusing results from previous calculations multiple times? This can be taken advantage of. You can calculate the sum of all the factorials up to n with a program something like this.
function sumFactorials(n) {
var sum = 0;
var prod = 1;
for(var i=1; i<=n; i++) {
prod *= i;
sum += prod;
}
return sum;
}
What is the most efficient way to write a javascript loop to calculate the number of occurrences of 7's (as an example number) that will be encountered in counting from 1 to 100?
Example:
function numberOccurences(targetNumber, minNumber, maxNumber) {
var count = 0;
for (i = minNumber; i < maxNumber; i++) {
count = count + (i.toString().split(targetNumber).length - 1);
}
return count;
}
var result = numberOccurences(7,1,100);
This will do it without looking at the actual numbers. Sorry, no loop, but you did ask for effeciency. If you really want to use a loop, make the recursion an iteration.
function digitOccurences(digit, min, max, base) {
if (typeof base != "number") base = 10;
return digitOccurencesPlus(digit, max, base, 1, 0) - digitOccurencesPlus(digit, min, base, 1, 0);
function digitOccurencesPlus(digit, N, base, pow, rest) {
if (N == 0) return 0;
var lastDigit = N%base,
prevDigits = (N-lastDigit)/base;
var occsInLastDigit = pow*(prevDigits+(lastDigit>digit));
var occsOfLastInRest = rest * (lastDigit==digit);
// console.log(prevDigits+" "+lastDigit, rest, occsInLastDigit, occsOfLastInRest);
return occsInLastDigit + occsOfLastInRest + digitOccurencesPlus(digit, prevDigits, base, pow*base, pow*lastDigit+rest);
}
}
This is an interesting problem, and already has similar answers for other languages. Maybe you could try to make this one in javascript: Count the number of Ks between 0 and N
That solution is for occurences from 0 to n, but you could easily use it to calculate from a to b this way:
occurences(a,b)= occurences(0,b)-occurences(0,a)
This is much faster (x6) than my original function...JSPERF
function numberOccurences2(targetNumber, minNumber, maxNumber) {
var strMe = "";
for (i = minNumber; i < maxNumber; i++) {
strMe = strMe.concat(i);
}
var re = new RegExp(targetNumber,"g");
var num1 = strMe.length;
var num2 = strMe.replace(re, "").length;
num2 = num1- num2;
return (num2);
}
There has to be a faster way still...
I'm currently working on coderbyte's medium challenge entitled "Permutation Step."
The goal is to take user input, num, and to return the next number greater than num using the same digits So, for example, if user input is 123, then the number 132 should be returned. If user input is 12453, then 12534 should be returned...
Anywho, I have a correct model answer created by someone (probably a genius, cuz this stuff is pretty hard) and I'm trying to figure out how the answer works, line for line by having an example play out (I'm keeping it simple and playing out the function with user input 123).
The answer has 2 functions, but the 1st function used is what I'm currently trying to work out...
The relevant code is:
var PermutationStep1 = function(num) {
var num1 = num.toString();
var ar = [];
//return num1;
if (num1.length < 2) {
return num;
} else {
for(var i = 0; i < num1.length; i++) {
var num2 = num1[i];
var num3 = num1.substr(0,i) + num1.substr(i+1, num1.length -1);
var numAr = PermutationStep1(num3);
for(var j = 0; j < numAr.length; j++) {
ar.push(numAr[j] + num2);
}
}
ar.sort(function(a,b) {return a-b});
return ar;
}
}
Again, I'm trying to work thru this function with the inputted num as 123 (num = 123).
I'm pretty sure that this function should output an array with multiple elements, because the 2nd function merely compares those array elements with the original user input (in our case, 123), and returns the next greatest value.
So in our case, we should probably get an array, named 'ar', returned with a host of 3 digit values. But for some reason, I'm getting an array of 2 digit values. I can't seem to isolate my mistake and where I'm going wrong. Any help with where, specifically, I'm going wrong (whether it be the recursion, the use of substring-method, or the concating of strings together, whatever my problem may be) would be appreciated...
Here's some of my work so far:
PS1(123) / num1 = 123
i = 0;
num2 = (num1[i]) = '1';
num3 = (num1.substr(0, 0) + num1.substr(1, 2)) = ('0' + '23') = '23'
PS1(23)
i = 0;
num2 = '2';
num3 = '3'
PS1(3) -> numAr = 3 (since num1 is less than 2 digits, which is the recursion base case?)
(So take 3 into the 2nd for loop)...
ar.push(numAr[j] + num2) = ar.push('3' + '1') = 31
ar = [31] at this point
And then I go through the initial for-loop a couple more times, where i = 1 and then i = 2, and I eventually get....
ar = [31, 32, 33]...
But I'm thinking I should have something like ar = [131, 132, 133]? I'm not sure where I'm going wrong so please help. Because the answer is correctly spit out by this function, the correct answer being 132.
Note: if you need the 2nd part of the model answer (i.e. the 2nd function), here it is:
var arr = [];
function PermutationStep(num1) {
arr.push(PermutationStep1(num1));
var arrStr = arr.toString();
var arrStrSpl = arrStr.split(",");
//return arrStrSpl;
for(var p = 0; p < arrStrSpl.length; p++) {
if(arrStrSpl[p] > num1) {
return arrStrSpl[p];
}
}
return -1;
}
I'm sorry the first function i posted was under a mathematical logical mistake and i was to overhasty
I thought about it again and now i have the following function which definitley works
function getNextNumber (num)
{
var numberStr=num.toString (), l=numberStr.length, i;
var digits=new Array (), lighterDigits, digitAtWeight;
var weight,lightWeight, lighterDigits_l, value=0;
for (i=l-1;i>-1;i--)
digits.push (parseInt(numberStr.charAt(i)));
lighterDigits=new Array ();
lighterDigits.push (digits[0]);
for (weight=1;weight<l;weight++)
{
digitAtWeight=digits[weight];
lighterDigits_l=lighterDigits.length;
for (lightWeight=0;lightWeight<lighterDigits_l;lightWeight++)
{
if (digitAtWeight<lighterDigits[lightWeight])
{
lighterDigits.unshift (lighterDigits.splice (lightWeight,1,digitAtWeight)[0]);
lighterDigits.reverse ();
digits=lighterDigits.concat (digits.slice (weight+1,l));
for (weight=0;weight>l;weight++)
value+=Math.pow (10,weight)*digits[weight];
return value;
}
}
lighterDigits.push (digitAtWeight);
}
return NaN;
}
okay here is my solution i found it in 20 minutes ;)
//---- num should be a Number Object and not a String
function getNextNumber (num)
{
var numberStr=num.toString (), l=numberStr.length, i;
var digits=new Array (), digitA, digitB;
var weight,lightWeight;
var valueDifference,biggerValue;
for (i=l-1;i>-1;i--)
digits.push (parseInt(numberStr.charAt(i))); // 345 becomes a0=5 a1=4 a2=3 and we can say that num= a0*10^0+ a1*10^1+ a2*10^2, so the index becomes the decimal weight
for (weight=1;weight<l;weight++)
{
digitA=digits[weight];
biggerValue=new Array ();
for (lightWeight=weight-1;lightWeight>-1;lightWeight--)
{
digitB=digits[lightWeight];
if (digitB==digitA) continue;
valueDifference=(digitA-digitB)*(-Math.pow(10,weight)+Math.pow (10,lightWeight));
if (valueDifference>0) biggerValue.push(valueDifference);
}
if (biggerValue.length>0)
{
biggerValue.sort();
return (biggerValue[0]+num);
}
}
}
this is the solution I figured out for the problem without using a recursive function. It's passed all the tests on coderbyte. I am still new to this so using recursion is not the first thing I look for. hope this can help anyone else looking for a solution.
function PermutationStep(num) {
var numArr = (num + '').split('').sort().reverse();
var numJoin = numArr.join('');
for (var i = (num + 1); i <= parseInt(numJoin); i++){
var aaa = (i + '').split('').sort().reverse();
if (aaa.join('') == numJoin){
return i;
}
}
return -1;
}
function averageCalculator (numvalues) {
for(i=0, i <= numvalues, i++>) {
var score = prompt("input the score")
result1 += score;
}
alert(result1 / 3);
}
this function is later triggered by a button with onclick="averageCalculator (2)
<input type="button" value="Click for the average" onclick="averageCalculator (2)">
any ideas why its not working? it should prompt you for 2 values and then alert you with the average. not sure whats wrong.
Your code has multiple issues. The for loop is not well formatted and you need to terminate statements with a semi-colon. Also you need to declare variables. And your loop will run numvalues+1 times which is why i removed the = in your loop. Also if you want to calculate an average you want to divide by numvalues.
function averageCalculator (numvalues) {
var result1 = 0;
for(i=0; i < numvalues; i++) {
var score = prompt("input the score");
result1 += score;
}
alert(result1 / numvalues);
}
On top of the invalid syntax you will run into a common "problem" with javascript here. The inputs are treated as strings and instead of being added they will be concatenated. Providing 2 and 2 as scores will result in 11. 2 concatenated with 2 = 22 / 2 = 11. You need to cast the value to a number explicitly before adding them together:
function averageCalculator (numvalues) {
var result1 = 0;
for(i=0; i < numvalues; i++) {
var score = prompt("input the score");
result1 += Number(score);
}
alert(result1 / numvalues);
}
Above code will correctly return 2
The syntax of your for-loop is wrong:
for(i=0, i <= numvalues, i++>) {
should be
for(i=0; i <= numvalues; i++) {
Tip: Also, it's better to use
for(var i=0; i <= numvalues; i++) {
since then i will be a local variable instead of a global one.
Try like this
for(var i=0; i <= numvalues; i++){}
An alternative solution (using a functional programming libary, like Underscore.js):
function averageCalculator(numValues) {
var numbers = _.map(_.range(numValues), function(element) {
return +prompt('input the score');
});
var result = _.reduce(numbers, function(memo, number) {
return memo + number;
}, memo);
alert(result / 3);
}
While a little bit more complicated (and less efficient), you'll get rid of loops altogether.
EDIT
The +prompt('input the score') does effectivly the same as Number(prompt('input the score')).