breaking an integer into parts - javascript

I'm trying to add all the digits in an integer value until i get a value below 9 using Javascript.
for an example, if i have 198, I want to add these together like 1 + 9 + 8 = 18, and since 18 is higher than 9 add 1 +8 again = 9.

Rather than giving you full code I would just explain how to do it.
You can do modulo math by number%10 and subsequent int divide by 10 (number/10) until you get 0 to get all the digits of a number. Sum the individual digits and until sum > 9 repeat the above process in a loop.
Edit: okay here is the code for you:
<script>
var num=198;
n = num;
var sum;
do {
sum = 0;
while (n>0) {
rem = (n % 10);
sum += rem;
n = (n - rem)/10;
}
n = sum;
} while(sum>9);
alert("sum is: " + sum);
</script>

function foo(var x)
{
while(x > 9)
{
var y = 0;
while(x!=0)
{
y += x%10;
x = Math.floor(x/10);
}
x = y;
}
return x;
}

Here are two hints: (i % 10) gives the least significant decimal digit of i, while i /= 10 removes the least significant digit from i. The rest is left as an exercise for the reader.

Related

javascript function edge cases solving

function doNf(num, left, right) {
let numStr = num.toString();
const numArray = numStr.split('.');
let leftPart = numArray[0]; // Grab the left part of numStr
// Determine how many times to loop based on left and leftPart
const timesToLoop = left - leftPart.length;
if (typeof right === 'undefined') {
for (let i = 0; i < timesToLoop; i++) {
numStr = '0' + numStr; // Add a 0 to the beginning of numStr
}
return numStr;
} else {
let rightRounded = num.toFixed(right); // Round num to right decimals
numStr = rightRounded.toString();
for (let i = 0; i < timesToLoop; i++) {
numStr = '0' + numStr; // Add a 0 to the beginning of numStr
}
}
return numStr;
}
This Function is basically a modified rounding-off function. It works correctly but there are few edge cases that i am unable to handle, need help with that.
for (let i = 0; i < 10; i++) {
const n = Math.pow(10, -i);
console.log(i, n, doNf(n, 4, 2));
}
This gives output like:
0 1 0001.00
1 0.1 0000.10
2 0.01 0000.01
3 0.001 0000.00
4 0.0001 0000.00
5 0.00001 0000.00
6 0.000001 0000.00
7 1e-7 0.00
8 1e-8 0.00
9 1e-9 0.00
case 7,8,9 are behaving incorrectly.
there should be exactly 4 zeros before decimal since left = 4. I even checked that the typeof those 0.00 is string, but i am unable to figure out why the concatanation is not happening??
You should avoid using toString() as that will produce scientific notation. In that case no . is found in the string, which breaks the algorithm.
Instead, use toFixed immediately and pad the result at the left so it has the required digits before the decimal point.
There are maybe some boundary cases to deal with:
When right is 0, there will be no decimal point in the result; the padding should take this into account
When left is 0, you maybe want the results to start with a decimal point. toFixed always produces at least one digit before the decimal point.
When the given number has an absolute value is too great to be represented in the given format, the left restriction is ignored (as padLeft will do).
function doNf(num, left, right) {
let s = num.toFixed(right).padStart(left+right+!!right, "0");
return left ? s : s.replace(/^0/, "");
}
for (let i = 0; i < 10; i++) {
let n = 1 / 10 ** i;
console.log(i, n, doNf(n, 4, 2));
}

How to generate random numbers in the same line with Js?

I have an algorithm that simulates a lottery generating numbers from 1 to 50 and numbers from 1 to 10. For this, I'm using a Math function and a for loop to code this lottery.
My problem is to find a way for my result to come out in one line instead of new lines. I'll explain with some code:
for (let rand_num = 1; rand_num <= 5; rand_num++) {
console.log("Numbers")
console.log(Math.floor(Math.random() * 50) + 1);
}
for (let rand_star = 1; rand_star <= 2; rand_star++) {
console.log("Stars")
console.log(Math.floor(Math.random() * 10) + 1);
}
Output:
Numbers
10
Numbers
8...
Stars
2
Stars
7...
As this output takes up too much space I would like another alternative that leaves random values in the same line like this output example:
Output:
Numbers: 10 - 8 - 50 - 44 - 21
Stars: 2 - 7
You can always create a reusable function to generate the random numbers and place them into an array. Then return those numbers separated by your seperator.
function lotteryNumbers(max, total) {
let nums = [];
for (let x = 1; x <= total; x++) {
nums.push(Math.floor(Math.random() * max) + 1);
}
return nums.join(" - ");
}
console.log("Numbers: " + lotteryNumbers(50, 5));
console.log("Stars: " + lotteryNumbers(10, 2));

Determine number of leading zeros in a floating point number

How can I calculate how many zeros come after the decimal point but before the first non-zero in a floating point number. Examples:
0 -> 0
1 -> 0
1.0 -> 0
1.1 -> 0
1.01 -> 1
1.00003456 ->4
Intuitively I assume there is a math function that provides this, or at least does the main part. But I can neither recall nor figure out which one.
I know it can be done by first converting the number to a string, as long as the number isn't in scientific notation, but I want a pure math solution.
In my case I don't need something that works for negative numbers if that's a complication.
I'd like to know what the general ways to do it are, irrespective of language.
But if there is a pretty standard math function for this, I would also like to know if JavaScript has this function.
As a sidenote, I wonder if this calculation is related to the method for determining how many digits are required for the decimal representation of an integer.
Let x be a non-whole number that can be written as n digits of the whole part, then the decimal point, then m zeroes, then the rest of the fractional part.
x = [a1a2...an] . [0102...0m][b1b2...bm]
This means that the fractional part of x is larger than or equal to 10–m, and smaller than 10–m+1.
In other words, the decimal logarithm of the fractional part of x is larger than or equal to –m, and smaller than –m+1.
Which, in turn, means that the whole part of the decimal logarithm of the fractional part of x equals –m.
function numZeroesAfterPoint(x) {
if (x % 1 == 0) {
return 0;
} else {
return -1 - Math.floor(Math.log10(x % 1));
}
}
console.log(numZeroesAfterPoint(0));
console.log(numZeroesAfterPoint(1));
console.log(numZeroesAfterPoint(1.0));
console.log(numZeroesAfterPoint(1.1));
console.log(numZeroesAfterPoint(1.01));
console.log(numZeroesAfterPoint(1.00003456));
As a sidenote, I wonder if this calculation is related to the method for determining how many digits are required for the decimal representation of an integer.
In the same manner, a positive integer x takes n decimal digits to represent it if and only if n - 1 <= log10(x) < n.
So the number of digits in the decimal representation of x is floor(log10(x)) + 1.
That said, I wouldn't recommend using this method of determining the number of digits in practice. log10 is not guaranteed to give the exact value of the logarithm (not even as exact as IEEE 754 permits), which may lead to incorrect results in some edge cases.
You can do it with a simple while loop:
function CountZeros(Num) {
var Dec = Num % 1;
var Counter = -1;
while ((Dec < 1) && (Dec > 0)) {
Dec = Dec * 10;
Counter++;
}
Counter = Math.max(0, Counter); // In case there were no numbers at all after the decimal point.
console.log("There is: " + Counter + " zeros");
}
Then just pass the number you want to check into the function:
CountZeros(1.0034);
My approach is using a while() loop that compares the .floor(n) value with the n.toFixed(x) value of it while incrementing x until the two are not equal:
console.log(getZeros(0)); //0
console.log(getZeros(1)); //0
console.log(getZeros(1.0)); //0
console.log(getZeros(1.1)); //0
console.log(getZeros(1.01)); //1
console.log(getZeros(1.00003456)); //4
function getZeros(num) {
var x = 0;
if(num % 1 === 0) return x;
while(Math.floor(num)==num.toFixed(x)) {x++;}
return(x-1);
}
You can do it with toFixed() method, but there is only one flaw in my code, you need to specify the length of the numbers that comes after the point . It is because of the way the method is used.
NOTE:
The max length for toFixed() method is 20, so don't enter more than 20 numbers after . as said in the docs
var num = 12.0003400;
var lengthAfterThePoint = 7;
var l = num.toFixed(lengthAfterThePoint);
var pointFound = false;
var totalZeros = 0;
for(var i = 0; i < l.length; i++){
if(pointFound == false){
if(l[i] == '.'){
pointFound = true;
}
}else{
if(l[i] != 0){
break;
}else{
totalZeros++;
}
}
}
console.log(totalZeros);
Extra Answer
This is my extra answer, in this function, the program counts all the zeros until the last non-zero. So it ignores all the zeros at the end.
var num = 12.034000005608000;
var lengthAfterThePoint = 15;
var l = num.toFixed(lengthAfterThePoint);
var pointFound = false;
var theArr = [];
for(var i = 0; i < l.length; i++){
if(pointFound == false){
if(l[i] == '.'){
pointFound = true;
}
}else{
theArr.push(l[i]);
}
}
var firstNumFound = false;
var totalZeros = 0;
for(var j = 0; j < theArr.length; j++){
if(firstNumFound == false){
if(theArr[j] != 0){
firstNumFound = true;
totalZeros = totalZeros + j;
}
}else{
if(theArr[j] == 0){
totalZeros++;
}
}
}
var totalZerosLeft = 0;
for (var k = theArr.length; k > 0; k--) {
if(theArr[k -1] == 0){
totalZerosLeft++;
}else{
break;
}
}
console.log(totalZeros - totalZerosLeft);

Optimising Javascript

I was given a quiz and I had gotten the answer wrong and It's been bugging me ever since so I thought I'd ask for your thoughts
I needed to optimise the following function
function sumOfEvenNumbers(n) {
var sum = 0;
for(let i = 2; i < n;i++){
if(i % 2 == 0) sum += i;
}
return sum;
}
console.log(sumOfEvenNumbers(5));
I came up with
function sumOfEvenNumbers(n) {
var sum = 0;
while(--n >= 2) sum += n % 2 == 0? n : 0
return sum;
}
console.log(sumOfEvenNumbers(5));
What other ways were there?
It's a bit of a math question. The sum appears to be the sum of an arithmitic sequence with a common difference of 2. The sum is:
sum = N * (last + first) / 2;
where N is the number of the numbers in the sequence, last is the last number of those numbers, and first is the first.
Translated to javascript as:
function sumOfEvenNumbers(n) {
return Math.floor(n / 2) * (n - n % 2 + 2) / 2;
}
Because the number of even numbers between 2 and n is Math.floor(n / 2) and the last even number is n - n % 2 (7 would be 7 - 7 % 2 === 6 and 8 would be 8 - 8 % 2 === 8). and the first is 2.
Sum of n numbers:
var sum = (n * (n+1)) / 2;
Sum of n even numbers:
var m = Math.floor(n/2);
var sum = 2 * (m * (m+1) /2);
You can compute these sums using an arithmetic sum formula in constant time:
// Return sum of positive even numbers < n:
function sumOfEvenNumbers(n) {
n = (n - 1) >> 1;
return n * (n + 1);
}
// Example:
console.log(sumOfEvenNumbers(5));
Above computation avoids modulo and division operators which consume more CPU cycles than multiplication, addition and bit-shifting. Pay attention to the limited range of the bit-shifting operator >> though.
See e.g. http://oeis.org/A002378 for this and other formulas leading to the same result.
First thing is to eliminate the test in the loop:
function sumOfEvenNumbers(n) {
var sum = 0;
var halfN= Math.floor(n/2);
for(let i = 1; i < n/2;i++) {
sum += i;
}
return sum * 2;
}
Then we can observe that is just calculating the sum of all the integers less than a limit - and there is a formula for that (but actually formula is for less-equal a limit).
function sumOfEvenNumbers(n) {
var halfNm1= Math.floor(n/2)-1;
var sum = halfNm1 * (halfNm1+1) / 2;
return sum * 2;
}
And then eliminate the division and multiplication and the unnecessary addition and subtraction:
function sumOfEvenNumbers(n) {
var halfN= Math.floor(n/2);
return (halfN-1) * halfN;
}
Your solution computes in linear (O(N)) time.
If you use a mathematical solution, you can compute it in O(1) time:
function sum(n) {
let half = Math.ceil(n/2)
return half * (half + 1)
}
Because the question is tagged ecmascript-6 :)
const sumEven = x => [...Array(x + 1).keys()].reduce((a, b) => b % 2 === 0 ? a + b : a, 0);
// set max number
console.log(sumEven(10));

Why isn't my attempted solution working?

When I run the code in the console, the browser just stops working (am assuming stack overflow).
I've come up with several different algorithms for solving this problem, but I thought this one would not cause any SOs.
The problem:
The sequence of triangle numbers is generated by adding the natural numbers. So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. The first ten terms would be:
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
Let us list the factors of the first seven triangle numbers:
1: 1
3: 1 3
6: 1,2,3,6
10: 1,2,5,10
15: 1,3,5,15
21: 1,3,7,21
28: 1,2,4,7,14,28
We can see that 28 is the first triangle number to have over five divisors.
What is the value of the first triangle number to have over five hundred divisors?
Failing solution:
function divisors(n){
var counter = 0;
var triangle = 3;
var triangle_add = 2;
while (counter < n){
for (var i = 1; i = triangle; i++){
if (triangle % i === 0){
counter++;
}
};
if (counter < n){
triangle_add++;
triangle = triangle + triangle_add;
counter = 0;
};
};
return triangle;
};
console.log(divisors(501));
Your solution is not working because, most probably, it is very slow. This problem can be solved much faster by the following method:
Find all the prime numbers smaller than some N (put, for example, N=100'000) using Sieve of Eratosthenes. It is quite fast.
As we know from elementary math each number can be written in the form X=p1^i1*p2^i2*...*pn^in where pj is prime number and ij is the power of corresponding prime number. The number of divisors of X is equal to (i1+1)*(i2+1)*...*(in+1) since that many different ways we can form a number which will be divisor of X. Having an array of prime numbers the number of divisors for X can be calculated quite fast (the code still has place to be optimized):
int divisorCount(long long X)
{
int c = 1;
for (int i = 0; PRIMES[i] <= X; ++i)
{
int pr = PRIMES[i];
if (X % pr == 0)
{
int p = 1;
long long r = X;
while (r % pr == 0)
{
r = r / pr;
++p;
}
c *= p;
}
}
return c;
}
Iterate through all triangle numbers and count divisor numbers for them using the above function. The i-th triangle number is i * (i + 1) / 2, so no need to keep a variable, increment it and add it each time.

Categories