C++ to javascript conversion - javascript

The question I'm doing is:
Write a JavaScript program to create a function which returns the number of times required to replace a given number with the sum of its digits until it converts to a single digit number. Like if given number is 123, number of times required to convert it into a single digit number is 1 (1+2+3=6). Your output code should be in the format console.log("Result is ", variableName)
I could not find the solution to this problem so I googled it and found this page.
The code on this page is in C/C++ ,Java etc...I took the C++ code and tried to convert it to javascript myself and this is the result:
var num=prompt("Enter a number");
var a= num.toString();
function test(x)
{var temporary_sum = 0, count = 0;
while (x.length() > 1)
{
temporary_sum = 0;
// computing sum of its digits
for (var i = 0; i < x.length(); i++)
temporary_sum += ( x[ i ] - '0' ) ;
// converting temporary_sum into string
// x again .
x = temporary_sum.toString() ;
// increase the count
count++;
}
return count;
}
var output = test(a) ;
console.log("Result is: ", output);
This code does not give any output at all. How can I fix this? Is there a better way to do this question?

Here is a better way to do that using recursion. And reduce
function test(x,count=0){
if(String(x).length === 1) return count;
let sum = String(x).split('').reduce((ac,a) => Number(a) + ac,0);
return test(sum,++count);
}
console.log(test(123)) //1
console.log(test(456)) //2
console.log(test(99999999999)) //3

I'll answer your last question - yes, there is a better way to do this question. You want to use recursion. You can also split the string on '' to convert its digits into an array, and you want to use parseInt to turn it back into a number.

I will use a different approach (I don't say it would be better). First, I will skip the mapping from number to string and wraps the logic that sums the digits of some number into a function called sumDigits(). This way you have a resusable method you can use for other purposes later. The second step is to define your test function using the previously created sumDigits mainly using the while loop you already have but testing with another condition and generalized to accept also integer negative numbers:
const sumDigits = (num) =>
{
let sum = 0;
while (num)
{
sum += num % 10, num = Math.floor(num / 10);
}
return sum;
}
const test = (num) =>
{
let counter = 0;
num = Math.abs(num);
while (num >= 10)
{
num = sumDigits(num), counter++;
}
return counter;
}
console.log(test(123));
console.log(test(456));
console.log(test(-789));

Related

Why is my function sometimes squaring twice?

Writing a function to take a number, square each number and return them as a concatenated integer, ie. 3214 => 94116. For some reason, my code appears to occasionally square 2's and 3's twice making a 2 turn into 16 and 3 into 81. I can't figure it out. I'm not a super experienced debugger yet so any help would be appreciated.
function squareDigits(num){
let digits = (""+num).split("");
let intDigits = [];
for (x of digits) {
intDigits.push(parseInt(x));
}
for (x of intDigits) {
intDigits.splice(intDigits.indexOf(x), 1, x * x);
}
return parseInt(intDigits.join(""));
}
console.log(squareDigits(24));
Leaving aside the fact that you can do this more elegantly with something like map() the issue in your code is that it uses indexOf() while changing the values on each iteration. Since indexOf() returns the index of the first occurrence it is going to find digits that you have already replaced.
This is your original code with a few logs so you can understand what I mean:
function squareDigits(num){
let digits = (""+num).split("");
let intDigits = [];
for (x of digits) {
intDigits.push(parseInt(x));
}
for (x of intDigits) {
console.log('intDigits: ' + intDigits);
console.log(` index of ${x} = ${intDigits.indexOf(x)}`);
intDigits.splice(intDigits.indexOf(x), 1, x * x);
}
return parseInt(intDigits.join(""));
}
console.log('RESULT: ' + squareDigits(24));
Notice how in the second pass the index of 4 is 0 (the first position in the array) because you have replaced the original 2 by it's squared value 4.
A simple way to fix this is to not rely on indexOf() and iterate over the array the good old way, like this:
function squareDigits(num){
let digits = (""+num).split("");
let intDigits = [];
for (x of digits) {
intDigits.push(parseInt(x));
}
for (let i = 0; i < intDigits.length; i++) {
const x = intDigits[i];
console.log('intDigits: ' + intDigits);
console.log(` index of ${x} = ${i}`);
intDigits.splice(i, 1, x * x);
}
return parseInt(intDigits.join(""));
}
console.log('RESULT: ' + squareDigits(24));
A simplistic (and bug free) version of your function could be this:
const squareDigits = num => [...num.toString()].map(x => x ** 2).join('');
console.log(squareDigits(24));
Other variant:
const squareDigits = num => num.toString().replaceAll(/\d/g, x => x ** 2);
console.log(squareDigits(24));
Instead of looping twice use array methods .map() , .reduce() etc it will make your code effective .. wrote a simple function
See =>
function squareDigits(num){
let digits = String(num).split("");
digits = digits.reduce((final , digit)=> final += String( parseInt(digit) **2 ), "");
return digits
}
console.log(squareDigits(312));
As #Sebastian mentioned, intDigits.indexOf(x) will find the
first index. So after replacing the first one, there's a change you'll find the number you've just replaced.
We can simplify the function to :
function squareDigits(num){
return num.toString().split('').map(n => n ** 2).join('');
}
Where :
We convert the number to a string using toString()
We split the string into loose numbers using split('')
map() over each number
Return the square by using the Exponentiation (**) operator
join() the numbers to get the result
Example snippet:
function squareDigits(num){
return num.toString().split('').map(n => n ** 2).join('');
}
console.log(squareDigits(3214)); // 94116

Can't detect the cause of infinite loop in a 'while loop' in JS

I've got an infinite loop inside my while loop and I can't find the cause.
It's a simple function that returns the sum of the argument's digits. I use a while loop because it needs to add up the digits until it lands at a one digit number.
I made sure that I added a statement that would make sure that at a certain point the loop will break., But it obviously doesn't.
function digital_root(n) {
num = n;
sum = 0;
while (num.toString().length>1){
for (i=0; i<num.toString().length; i++) {
sum += parseInt(num.toString()[i])
}
num = sum;
}
return sum;
}
digital_root(456)
I get a warning that I have an infinity loop on line 4 (while loop).
I hoped that num=sumwould reassign the new integer (with reduced number of digits) to the numvariable and thus at some point break out of the loop. Is this wrong?
What further confuses me is that most of the JS editors I've used to debug the problem return an output, but it takes ages. So is it an infinite loop or is it not?
You have a nested loop structure where the first condition is always true.
For getting only a number below 10, you could call the function again as recursion.
function digital_root(n) {
var num = n.toString(), // declare and use the string value
sum = 0,
i;
for (i = 0; i < num.length; i++) {
sum += parseInt(num[i], 10)
}
return sum > 9
? digital_root(sum)
: sum;
}
console.log(digital_root(456));
After re-reading the question I noticed that you're trying to reduce an integer down to a single number. The issue with your code was that sum was set to 0, only before the while loop. Meaning that it didn't reset for the second, third, ... run.
Moving sum = 0 into the while loop resolves this issue. I've also added variable declarations at the top to avoid setting global variables.
function digital_root(n) {
var num, sum, i;
num = n;
while (num.toString().length > 1) {
sum = 0;
for (i = 0; i < num.toString().length; i++) {
sum += parseInt(num.toString()[i]);
}
num = sum;
}
return sum;
}
console.log(digital_root(456));
Here written in a recursive manner, a style that I personally more prefer:
function digital_root(integer) {
// guard against things that might result in an infinit loop, like floats
if (!Number.isInteger(integer) || integer < 0) return;
const chars = integer.toString().split("");
if (chars.length == 1) return integer;
return digital_root(
chars.map(char => parseInt(char))
.reduce((sum, digit) => sum + digit)
);
}
console.log(digital_root(456));
Since you already got the answer, here is another way to meet the result
function digital_root(n) {
// convert the number to string
// use split to create an array of number viz ['4','5','6']
// use reduce to sum the number after converting to number
// 0 is the initial value
return n.toString().split('').reduce((a, c) => a + parseInt(c, 10), 0)
}
console.log(digital_root(456))
Avoiding all the nested loops that lead to a situation such as that you're facing, I'd rather do it in a more readable way.
function digital_root(n) {
sum = n;
while(sum.toString().length > 1) {
sum = sum.toString()
.split('')
.map(digit => parseInt(digit, 10))
.reduce((acc, cur) => acc + cur);
}
return sum;
}
console.log(digital_root(456));

Need help writing code to convert decimal to binary without the use of the toString

I'm trying to create my own decimal to binary converter with the method of decrementing the inputted variable (decimal value), by dividing it by 2 and storing the remainder (like 2nd grade math remainder), which is always either 0 or 1. Each of the remainder values i thin should be stored in an array and I think maybe put in backwards so that the most significant digit is first in the array (this is because when decrementing the remainer values are filled in left to right). Soooo yea i dont really know how to store the remainder values in an array using a function
Thanks in advance and if something is confusing then feel free to ask because im not even sure if this is the best method of doing this its just what i came up with
function decimalToBinary(num) {
var bin = 0;
while (num > 0) {
bin = num % 2 + bin;
num >>= 1; // basically /= 2 without remainder if any
}
alert("That decimal in binary is " + bin);
}
Your code is almost correct. The main problem is that bin starts out as 0; when you add a digit, they are added numerically, so your code ends up just counting the binary 1s: in this manner, 10 is initial 0, and +1+0+1+0, resulting in 2. You want to handle it as a string: ""+1+0+1+0 results in 1010. So, the only needed change is:
var bin = "";
If you want to solve it using arrays, with minimal changes to your code, it would be:
function decimalToBinary(num) {
var bin = [];
while (num > 0) {
bin.unshift(num % 2);
num >>= 1; // basically /= 2 without remainder if any
}
alert("That decimal in binary is " + bin.join(''));
}
Here, I use .unshift to add an element to the head of the array (and renumbering the remaining elements); .join() to collect them all into a string.
Or this:
function decimalToBinary(num) {
var bin = [];
while (num > 0) {
bin[bin.length] = num % 2;
num >>= 1; // basically /= 2 without remainder if any
}
alert("That decimal in binary is " + bin.reverse().join(''));
}
This is not as good, but illustrates some more things you can do with arrays: taking their length, setting an arbitrary element, and flipping them around.
I have written a custom Decimal to Binary method:
function toBinary (input) {
let options = [1];
let max = 0;
let i = 1;
while(i) {
max = Math.pow(2, i);
if (max > input) break;
options.push(max);
i++;
}
let j = options.length;
let result = new Array(j);
result.fill("0");
while(j >= 0) {
if (options[j] <= input) {
result[j] = "1"
input = input - options[j];
}
j--;
}
return [...result].reverse().join("");
}
//Test the toBin method with built-in toString(2)
toBinary(100) === (100).toString(2) // true
toBinary(1) === (1).toString(2) // true
toBinary(128) === (128).toString(2) // true

Fibonacci Sequence - Find the number of digits - JavaScript

So, I have successfully written the Fibonacci sequence to create an array with the sequence of numbers, but I need to know the length (how many digits) the 500th number has.
I've tried the below code, but its finding the length of the scientific notation (22 digits), not the proper 105 it should be returning.
Any ideas how to convert a scientific notation number into an actual integer?
var fiblength = function fiblength(nth) {
var temparr = [0,1];
for(var i = 2; i<=nth; i++){
var prev = temparr[temparr.length-2],
cur = temparr[temparr.length-1],
next = prev + cur;
temparr.push(next);
}
var final = temparr[temparr.length-1].toString().length;
console.log(temparr[temparr.length-1]);
return final;
};
a = fiblength(500);
console.log(a);
Why not use the simple procedure of dividing the number by 10 until the number is less than 1.
Something as simple as this should work (a recursive def obv works as well)
function getDigits(n) {
var digits = 0;
while(n >= 1) {
n/=10;
digits += 1;
}
return digits;
}
getDigits(200);//3
getDigits(3.2 * 10e20);//=>22
Here's a solution in constant time:
function fiblength(n) {
return Math.floor((n>1)?n*.2089+.65051:1);
}
Let's explain how I arrived to it.
All previous solutions will probably not work for N>300 unless you have a BigNumber library in place. Also they're pretty inneficient.
There is a formula to get any Fibonacci number, which uses PHI (golden ratio number), it's very simple:
F(n) = ABS((PHI^n)/sqrt(5))
Where PHI=1.61803399 (golden ratio, found all over the fibonacci sequence)
If you want to know how many digits a number has, you calculate the log base 10 and add 1 to that. Let's call that function D(n) = log10(n) + 1
So what you want fiblength to be is in just the following function
fiblength(n) = D(F(n)) // number of digits of a fibonacci number...
Let's work it out, so you see what the one liner code will be like once you use math.
Substitute F(n)
fiblength(n) = D(ABS((PHI^n)/sqrt(5)))
Now apply D(n) on that:
fiblength(n) = log10(ABS((PHI^n)/sqrt(5))) + 1
So, since log(a/b) = log(a) - log(b)
fiblength(n) = log10(ABS((PHI^n))) - log10(sqrt(5))) + 1
and since log(a^n) = n * log(a)
fiblength(n) = n*log10(PHI) - log10(sqrt(5))) + 1
Then we evaluate those logarithms since they're all on constants
and add the special cases of n=0 and n=1 to return 1
function fiblength(n) {
return Math.floor((n>1)?n*.2089+.65051:1);
}
Enjoy :)
fiblength(500) => 105 //no iterations necessary.
Most of the javascript implementations, internally use 64 bit numbers. So, if the number we are trying to represent is very big, it uses scientific notation to represent those numbers. So, there is no pure "javascript numbers" based solution for this. You may have to look for other BigNum libraries.
As far as your code is concerned, you want only the 500th number, so you don't have to store the entire array of numbers in memory, just previous and current numbers are enough.
function fiblength(nth) {
var previous = 0, current = 1, temp;
for(var i = 2; i<=nth; i++){
temp = current;
current = previous + current;
previous = temp;
}
return current;
};
My Final Solution
function fiblength(nth) {
var a = 0, b = 1, c;
for(var i=2;i<=nth;i++){
c=b;
b=a+b;
a=c;
}
return Math.floor(Math.log(b)/Math.log(10))+1;
}
console.log(fiblength(500));
Thanks for the help!!!
The problem is because the resulting number was converted into a string before any meaningful calculations could be made. Here's how it could have been solved in the original code:
var fiblength = function fiblength(nth) {
var temparr = [0,1];
for(var i = 2; i<=nth; i++){
var prev = temparr[temparr.length-2],
cur = temparr[temparr.length-1],
next = prev + cur;
temparr.push(next);
}
var x = temparr[temparr.length-1];
console.log(x);
var length = 1;
while (x > 1) {
length = length + 1;
x = x/10;
}
return length;
};
console.log ( fiblength(500) );

How can I find the length of a number?

I'm looking to get the length of a number in JavaScript or jQuery?
I've tried value.length without any success, do I need to convert this to a string first?
var x = 1234567;
x.toString().length;
This process will also work forFloat Number and for Exponential number also.
Ok, so many answers, but this is a pure math one, just for the fun or for remembering that Math is Important:
var len = Math.ceil(Math.log(num + 1) / Math.LN10);
This actually gives the "length" of the number even if it's in exponential form. num is supposed to be a non negative integer here: if it's negative, take its absolute value and adjust the sign afterwards.
Update for ES2015
Now that Math.log10 is a thing, you can simply write
const len = Math.ceil(Math.log10(num + 1));
Could also use a template string:
const num = 123456
`${num}`.length // 6
You have to make the number to string in order to take length
var num = 123;
alert((num + "").length);
or
alert(num.toString().length);
I've been using this functionality in node.js, this is my fastest implementation so far:
var nLength = function(n) {
return (Math.log(Math.abs(n)+1) * 0.43429448190325176 | 0) + 1; 
}
It should handle positive and negative integers (also in exponential form) and should return the length of integer part in floats.
The following reference should provide some insight into the method:
Weisstein, Eric W. "Number Length." From MathWorld--A Wolfram Web Resource.
I believe that some bitwise operation can replace the Math.abs, but jsperf shows that Math.abs works just fine in the majority of js engines.
Update: As noted in the comments, this solution has some issues :(
Update2 (workaround) : I believe that at some point precision issues kick in and the Math.log(...)*0.434... just behaves unexpectedly. However, if Internet Explorer or Mobile devices are not your cup of tea, you can replace this operation with the Math.log10 function. In Node.js I wrote a quick basic test with the function nLength = (n) => 1 + Math.log10(Math.abs(n) + 1) | 0; and with Math.log10 it worked as expected. Please note that Math.log10 is not universally supported.
There are three way to do it.
var num = 123;
alert(num.toString().length);
better performance one (best performance in ie11)
var num = 123;
alert((num + '').length);
Math (best performance in Chrome, firefox but slowest in ie11)
var num = 123
alert(Math.floor( Math.log(num) / Math.LN10 ) + 1)
there is a jspref here
http://jsperf.com/fastest-way-to-get-the-first-in-a-number/2
You should go for the simplest one (stringLength), readability always beats speed. But if you care about speed here are some below.
Three different methods all with varying speed.
// 34ms
let weissteinLength = function(n) {
return (Math.log(Math.abs(n)+1) * 0.43429448190325176 | 0) + 1;
}
// 350ms
let stringLength = function(n) {
return n.toString().length;
}
// 58ms
let mathLength = function(n) {
return Math.ceil(Math.log(n + 1) / Math.LN10);
}
// Simple tests below if you care about performance.
let iterations = 1000000;
let maxSize = 10000;
// ------ Weisstein length.
console.log("Starting weissteinLength length.");
let startTime = Date.now();
for (let index = 0; index < iterations; index++) {
weissteinLength(Math.random() * maxSize);
}
console.log("Ended weissteinLength length. Took : " + (Date.now() - startTime ) + "ms");
// ------- String length slowest.
console.log("Starting string length.");
startTime = Date.now();
for (let index = 0; index < iterations; index++) {
stringLength(Math.random() * maxSize);
}
console.log("Ended string length. Took : " + (Date.now() - startTime ) + "ms");
// ------- Math length.
console.log("Starting math length.");
startTime = Date.now();
for (let index = 0; index < iterations; index++) {
mathLength(Math.random() * maxSize);
}
First convert it to a string:
var mynumber = 123;
alert((""+mynumber).length);
Adding an empty string to it will implicitly cause mynumber to turn into a string.
Well without converting the integer to a string you could make a funky loop:
var number = 20000;
var length = 0;
for(i = number; i > 1; ++i){
++length;
i = Math.floor(i/10);
}
alert(length);​
Demo: http://jsfiddle.net/maniator/G8tQE/
I got asked a similar question in a test.
Find a number's length without converting to string
const numbers = [1, 10, 100, 12, 123, -1, -10, -100, -12, -123, 0, -0]
const numberLength = number => {
let length = 0
let n = Math.abs(number)
do {
n /= 10
length++
} while (n >= 1)
return length
}
console.log(numbers.map(numberLength)) // [ 1, 2, 3, 2, 3, 1, 2, 3, 2, 3, 1, 1 ]
Negative numbers were added to complicate it a little more, hence the Math.abs().
I'm perplex about converting into a string the given number because such an algorithm won't be robust and will be prone to errors: it will show all its limitations especially in case it has to evaluate very long numbers. In fact before converting the long number into a string it will "collapse" into its exponential notation equivalent (example: 1.2345e4). This notation will be converted into a string and this resulting string will be evaluated for returning its length. All of this will give a wrong result. So I suggest not to use that approach.
Have a look at the following code and run the code snippet to compare the different behaviors:
let num = 116234567891011121415113441236542134465236441625344625344625623456723423523429798771121411511034412365421344652364416253446253446254461253446221314623879235441623683749283441136232514654296853446323214617456789101112141511344122354416236837492834411362325146542968534463232146172368374928344113623251465429685;
let lenFromMath;
let lenFromString;
// The suggested way:
lenFromMath = Math.ceil(Math.log10(num + 1)); // this works in fact returns 309
// The discouraged way:
lenFromString = String(num).split("").length; // this doesn't work in fact returns 23
/*It is also possible to modify the prototype of the primitive "Number" (but some programmer might suggest this is not a good practice). But this is will also work:*/
Number.prototype.lenght = () => {return Math.ceil(Math.log10(num + 1));}
lenFromPrototype = num.lenght();
console.log({lenFromMath, lenFromPrototype, lenFromString});
A way for integers or for length of the integer part without banal converting to string:
var num = 9999999999; // your number
if (num < 0) num = -num; // this string for negative numbers
var length = 1;
while (num >= 10) {
num /= 10;
length++;
}
alert(length);
I would like to correct the #Neal answer which was pretty good for integers, but the number 1 would return a length of 0 in the previous case.
function Longueur(numberlen)
{
var length = 0, i; //define `i` with `var` as not to clutter the global scope
numberlen = parseInt(numberlen);
for(i = numberlen; i >= 1; i)
{
++length;
i = Math.floor(i/10);
}
return length;
}
To get the number of relevant digits (if the leading decimal part is 0 then the whole part has a length of 0) of any number separated by whole part and decimal part I use:
function getNumberLength(x) {
let numberText = x.toString();
let exp = 0;
if (numberText.includes('e')) {
const [coefficient, base] = numberText.split('e');
exp = parseInt(base, 10);
numberText = coefficient;
}
const [whole, decimal] = numberText.split('.');
const wholeLength = whole === '0' ? 0 : whole.length;
const decimalLength = decimal ? decimal.length : 0;
return {
whole: wholeLength > -exp ? wholeLength + exp : 0,
decimal: decimalLength > exp ? decimalLength - exp : 0,
};
}
var x = 1234567;
String(x).length;
It is shorter than with .toString() (which in the accepted answer).
Try this:
$("#element").text().length;
Example of it in use
Yes you need to convert to string in order to find the length.For example
var x=100;// type of x is number
var x=100+"";// now the type of x is string
document.write(x.length);//which would output 3.

Categories

Resources