Experienced codefighters, i have just started using Codefight website to learn Javascript. I have solved their task but system does not accept it. The task is to sum all integers (inidividual digit) in a number. For example sumDigit(111) = 3. What is wrong with my code? Please help me.
Code
function digitSum(n) {
var emptyArray = [];
var total = 0;
var number = n.toString();
var res = number.split("");
for (var i=0; i<res.length; i++) {
var numberInd = Number(res[i]);
emptyArray.push(numberInd);
}
var finalSum = emptyArray.reduce(add,total);
function add(a,b) {
return a + b;
}
console.log(finalSum);
//console.log(emptyArray);
//console.log(res);
}
Here's a faster trick for summing the individual digits of a number using only arithmetic:
var digitSum = function(n) {
var sum = 0;
while (n > 0) {
sum += n % 10;
n = Math.floor(n / 10);
}
return sum;
};
n % 10 is the remainder when you divide n by 10. Effectively, this retrieves the ones-digit of a number. Math.floor(n / 10) is the integer division of n by 10. You can think of it as chopping off the ones-digit of a number. That means that this code adds the ones digit to sum, chops off the ones digit (moving the tens digit down to where the ones-digit was) and repeats this process until the number is equal to zero (i.e. there are no digits left).
The reason why this is more efficient than your method is that it doesn't require converting the integer to a string, which is a potentially costly operation. Since CodeFights is mainly a test of algorithmic ability, they are most likely looking for the more algorithmic answer, which is the one I explained above.
Related
I'm trying to solve all the lessons on codility but I failed to do so on the following problem: Ladder by codility
I've searched all over the internet and I'm not finding a answer that satisfies me because no one answers why the max variable impacts so much the result.
So, before posting the code, I'll explain the thinking.
By looking at it I didn't need much time to understand that the total number of combinations it's a Fibonacci number, and removing the 0 from the Fibonacci array, I'd find the answer really fast.
Now, afterwards, they told that we should return the number of combinations modulus 2^B[i].
So far so good, and I decided to submit it without the var max, then I got a score of 37%.. I searched all over the internet and the 100% result was similar to mine but they added that max = Math.pow(2,30).
Can anyone explain to me how and why that max influences so much the score?
My Code:
// Powers 2 to num
function pow(num){
return Math.pow(2,num);
}
// Returns a array with all fibonacci numbers except for 0
function fibArray(num){
// const max = pow(30); -> Adding this max to the fibonaccy array makes the answer be 100%
const arr = [0,1,1];
let current = 2;
while(current<=num){
current++;
// next = arr[current-1]+arr[current-2] % max;
next = arr[current-1]+arr[current-2]; // Without this max it's 30 %
arr.push(next);
}
arr.shift(); // remove 0
return arr;
}
function solution(A, B) {
let f = fibArray(A.length + 1);
let res = new Array(A.length);
for (let i = 0; i < A.length; ++i) {
res[i] = f[A[i]] % (pow(B[i]));
}
return res;
}
console.log(solution([4,4,5,5,1],[3,2,4,3,1])); //5,1,8,0,1
// Note that the console.log wont differ in this solution having max set or not.
// Running the exercise on Codility shows the full log with all details
// of where it passed and where it failed.
The limits for input parameters are:
Assume that:
L is an integer within the range [1..50,000];
each element of array A is an integer within the range [1..L];
each element of array B is an integer within the range [1..30].
So the array f in fibArray can be 50,001 long.
Fibonacci numbers grow exponentially; according to this page, the 50,000th Fib number has over 10,000 digits.
Javascript does not have built-in support for arbitrary precision integers, and even doubles only offer ~14 s.f. of precision. So with your modified code, you will get "garbage" values for any significant value of L. This is why you only got 30%.
But why is max necessary? Modulo math tells us that:
(a + b) % c = ([a % c] + [b % c]) % c
So by applying % max to the iterative calculation step arr[current-1] + arr[current-2], every element in fibArray becomes its corresponding Fib number mod max, without any variable exceeding the value of max (or built-in integer types) at any time:
fibArray[2] = (fibArray[1] + fibArray[0]) % max = (F1 + F0) % max = F2 % max
fibArray[3] = (F2 % max + F1) % max = (F2 + F1) % max = F3 % max
fibArray[4] = (F3 % max + F2 % max) = (F3 + F2) % max = F4 % max
and so on ...
(Fn is the n-th Fib number)
Note that as B[i] will never exceed 30, pow(2, B[i]) <= max; therefore, since max is always divisible by pow(2, B[i]), applying % max does not affect the final result.
Here is a python 100% answer that I hope offers an explanation :-)
In a nutshell; modulus % is similar to 'bitwise and' & for certain numbers.
eg any number % 10 is equivalent to the right most digit.
284%10 = 4
1994%10 = 4
FACTS OF LIFE:
for multiples of 2 -> X % Y is equivalent to X & ( Y - 1 )
precomputing (2**i)-1 for i in range(1, 31) is faster than computing everything in B when super large arrays are given as args for this particular lesson.
Thus fib(A[i]) & pb[B[i]] will be faster to compute than an X % Y style thingy.
https://app.codility.com/demo/results/trainingEXWWGY-UUR/
And for completeness the code is here.
https://github.com/niall-oc/things/blob/master/codility/ladder.py
Here is my explanation and solution in C++:
Compute the first L fibonacci numbers. Each calculation needs modulo 2^30 because the 50000th fibonacci number cannot be stored even in long double, it is so big. Since INT_MAX is 2^31, the summary of previously modulo'd numbers by 2^30 cannot exceed that. Therefore, we do not need to have bigger store and/or casting.
Go through the arrays executing the lookup and modulos. We can be sure this gives the correct result since modulo 2^30 does not take any information away. E.g. modulo 100 does not take away any information for subsequent modulo 10.
vector<int> solution(vector<int> &A, vector<int> &B)
{
const int L = A.size();
vector<int> fibonacci_numbers(L, 1);
fibonacci_numbers[1] = 2;
static const int pow_2_30 = pow(2, 30);
for (int i = 2; i < L; ++i) {
fibonacci_numbers[i] = (fibonacci_numbers[i - 1] + fibonacci_numbers[i - 2]) % pow_2_30;
}
vector<int> consecutive_answers(L, 0);
for (int i = 0; i < L; ++i) {
consecutive_answers[i] = fibonacci_numbers[A[i] - 1] % static_cast<int>(pow(2, B[i]));
}
return consecutive_answers;
}
I'm calculating the trailing zeros of a factorial. My solution is to calculate the factorial then determine how many trailing zeros it has. As you can imagine this isn't very scalable. How can I solve this without calculating the factorial?
I've found these pages on SO:
Trailing zeroes in a Factorial
Calculating the factorial without trailing zeros efficiently?
However, neither are in Javascript. If you downvote this question please let me know why. Thank-you for your time and feedback.
My solution:
function zeros(n) {
var result = [];
var count = 0;
for (var i = 1; i <= n; i++) {
result.push(i);
} //generating range for factorial function
var factorial = result.reduce(function(acc, el) {
return acc * el;
}, 1); //calculating factorial
factorial = factorial.toString().split('');
for (var j = factorial.length - 1; j > 0; j--) {
if (parseInt(factorial[j]) === 0) {
count += 1;
} else {
break;
}
} //counting trailing zeros
return count;
}
Knowing the number of trailing zeroes in a number comes down to knowing how many times it can be divided by 10, i.e. by both 5 and 2.
With factorial numbers that is quite easy to count:
f! = 1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16. ... .f
^ ^ ^
The places where a factor 5 gets into the final product are marked. It is clear that factors of 2 occur more often, so the count of factors of 5 are determining the number of trailing zeroes.
Now, when the factor 25 occurs, it should be counted for 2; likewise 125 should count for 3 factors of 5, etc.
You can cover for that with a loop like this:
function zeros(n) {
var result = 0;
while (n = Math.floor(n / 5)) result += n;
return result;
}
public static void main(String[] args) {
int n=23;
String fact= factorial(BigInteger.valueOf(23)).toString();
System.out.format("Factorial value of %d is %s\n", n,fact);
int len=fact.length();
//Check end with zeros
if(fact.matches(".*0*$")){
String[] su=fact.split("0*$");
//Split the pattern from whole string
System.out.println(Arrays.toString(fact.split("0*$")));
//Subtract from the total length
System.out.println("Count of trailing zeros "+(len-su[0].length()));
}
}
public static BigInteger factorial(BigInteger n) {
if (n.equals(BigInteger.ONE) || n.equals(BigInteger.ZERO)) {
return BigInteger.ONE;
}
return n.multiply(factorial(n.subtract(BigInteger.ONE)));
}
You don't really need to calculate the factorial product to count the trailing zeroes.
Here a sample to count the number of trailing zeroes in n!
temp = 5;
zeroes = 0;
//counting the sum of multiples of 5,5^2,5^3....present in n!
while(n>=temp){
fives = n/temp;
zeroes = zeroes + fives;
temp = temp*5;
}
printf("%d",zeroes);
Note that each multiple of 5 in the factorial product will contribute 1 to the number of trailing zeros. On top of this, each multiple of 25 will contribute an additional 1 to the number of trailing zeros. Then, each multiple of 125 will contribute another 1 to the number of trailing zeros, and so on.
Here's a great link to understand the concept behind this: https://brilliant.org/wiki/trailing-number-of-zeros/
I came across this algorithm somewhere on here can not remember now, but it looks like this,
def zeros(n)
return 0 if n.zero?
k = (Math.log(n)/Math.log(5)).to_i
m = 5**k
n*(m-1)/(4*m)
end
This very effiecient as it does not need a loop.
You can further optimize it to look like this.
def zeros(n)
return 0 if n.zero?
n*(n-1)/(4*n)
end
A javascript translation of this will be.
function zeros(n) {
if (n == 0) return 0;
return n * (n-1)/(4*n);
}
Note that this algorithm is correct till about n >= 1000000000, in which case the return value has an error margin of +1, and this error margin increases by +1 every n * 10000.
goal: take a number like 54321, add the numbers together (5+4+3+2+1 = 15), then take that number (15) add the digits (1+5 = 6), so return 6;
here is my code:
function digital_root(n) {
if (n >=10) {
var digits = n.toString().split('').map(function(item, index) {return parseInt(item)}).reduce(function(a,b){ return a+b});
console.log(digits);
}
}
digital_root(1632)
Can't figure out: How to get that function to repeat over and over until digits is just one number (i.e. less than 10). I have tried a variety of nested functions, but can't seem to get it right.
If possible please point me in the direction to the solution ("try a nesting in a while... or read up on..."), but don't give me the complete code solution ("Use this code chunk:...."). I've developed a bad habit of just reading and copying...
Thank you!
Try this: reference HERE
function digital_root(n) {
var singlesum = 0;
while (n >= 10 ) {
singlesum=0;
while (n > 0) {
var rem;
rem = n % 10;
singlesum = singlesum + rem;
n = parseInt(n / 10);
}
n = singlesum;
}
console.log(singlesum);
}
digital_root(1632)
You can use recursion to solve this.
Write a function makeSingleDigit, which argument will be your number.
You need a base condition with the base step, which in your case stops the recursion when received number is one-digit and returns the number.
If condition is not true, you just need to get another digit from the number by n%10 and sum it with the makeSingleDigit(Math.floor(n/10)). By this, you repeatedly sum digits of new numbers, until function receives one-digit number.
Mathematical solution just for your information: the number, which you want to find is n % 9 === 0 ? 9 : n % 9, thus it is the remainder of the division by 9 if it is not 0, otherwise it is 9.
Here is a very optimal solution to the problem:
function digital_root(n) {
return (n - 1) % 9 + 1;
}
const result = digital_root(1632);
console.log(result);
Well, not a very good solution but you can give a hit.
function digital_root(n) {
if (n >=10) {
var digits = n.toString().split('').map(function(item, index) {return parseInt(item)}).reduce(function(a,b){ return a+b});
console.log(digits);
return(digits);
}
}
var num = 1632;
do{
num = digital_root(num);
}while(num>10);
It's very close but just one number off. If you can change anything here to make it better it'd be appreciated. I'm comparing my number with Math.E to see if I'm close.
var e = (function() {
var factorial = function(n) {
var a = 1;
for (var i = 1; i <= n; i++) {
a = a * i;
}
return a;
};
for (var k = 0, b = []; k < 18; k++) {
b.push(b.length ? b[k - 1] + 1 / factorial(k) : 1 / factorial(k));
}
return b[b.length - 1];
})();
document.write(e);document.write('<br />'+ Math.E);
My number: 2.7182818284590455
Math.E: 2.718281828459045
Work from higher numbers to lower numbers to minimize cancellation:
var e = 1;
for(var k = 17; k > 0; --k) {
e = 1 + e/k;
}
return e;
Evaluating the Taylor polynomial by Horner's rule even avoids the factorial and allows you to use more terms (won't make a difference beyond 17, though).
As far as I can see your number is the same as Math.E and even has a better precision.
2.7182818284590455
2.718281828459045
What is the problem after all?
With javascript, you cannot calculate e this way due to the level of precision of javascript computations. See http://www.javascripter.net/faq/accuracy.htm for more info.
To demonstrate this problem please take a look at the following fiddle which calculates e with n starting at 50000000, incrementing n by 1 every 10 milliseconds:
http://jsfiddle.net/q8xRs/1/
I like using integer values to approximate real ones.
Possible approximations of e in order of increasing accuracy are:
11/4
87/32
23225/8544
3442297523731/1266350489376
That last one is fairly accurate, equating to:
2.7182818284590452213260834432
which doesn't diverge from wikipedia's value till the 18th:
2.71828182845904523536028747135266249775724709369995
So there's that, if you're interested.
I want to generate atleast 1000 unique random numbers with 10 digit using
javascript in a loop. Is this possible? Or is Javascript a wrong thing to do this?
UPDATE: How will you be sure that duplicates are not created?
Here's how I would do it:
var arr = [],
track = [],
min = 1000000000,
max = 9999999999,
qty = 1000,
ii = 0,
rnd;
while (ii < qty) {
rnd = Math.floor(Math.random() * (max - min + 1)) + min;
if (!track[rnd]) {
arr[ii] = track[rnd] = rnd;
ii += 1;
}
}
Here's a working example: http://jsfiddle.net/mTmEs/
Now, if something went awry with Math.random and for some reason it were to generate a lot of duplicates, this code could take a long time to complete. I don't think there is any way around this kind of potential problem though when you're talking about large quantities of unique random numbers.
Yes, it's possible.
Use Math.random to generate the pseudo-random numbers. Math.random returns a pseudo-random number greater than or equal to 0 and less than 1, so to get a 10-digit number (I'm assuming a whole number), you'd multiple that by 1,000,000,000 and round it off with Math.round or Math.floor. (If you need them all to be 10 digits, adjust accordingly — adding a base amount, multiplying by a higher number, etc.)
Use an object to keep track of them, so var obj = {}; to start with.
Store the numbers as keys in an object, e.g. obj[number] = true.
Test whether the object has the generated number using if (obj[number])
Loop until you have the correct number of unique numbers.
The reason I use an object for storing the numbers is that JavaScript objects are maps by their nature, and engines are optimized to retrieve properties from objects quickly. Under the covers, an implementation can do what it likes, but will probably use a hash table or similar.
Note that using an "array" for this is unnecessary; JavaScript arrays aren't really arrays, they're just objects with a couple of special features.
You could do this in JS, but you would have to check the array to see if it contains the currently generated random number. This would obviously degrade performance.
See if these answers help.
Random number generator that fills an interval
Generate unique random numbers between 1 and 100
A generic function for generating n random numbers of length l might be:
// Generate n unique random numbers of length l
// l should be less than 15
function genNRandLen(n, l) {
// Make sure l and n are numbers
n = Number(n);
l = Number(l);
// Protect against bad input
if (isNaN(l) || isNaN(n)) return;
var o = {}, a = [], num;
var min = l == 1? 0 : Math.pow(10, l-1);
var r = Math.pow(10, l) - min;
// Protect against endless loop
if (n >= (r)) return;
while (n--) {
do {
num = Math.floor(min + (Math.random()*r));
} while (o[num])
o[num] = true;
a[n] = num;
}
return a.sort();
}
Sorting is just to make it easy to see duplicates when testing, remove if not necessary or random order is preferred.
If numbers longer than 15 digits are required, they can be created by concatenating strings of shorter random numbers and trimming to the required length. The following will generate a random number of any length:
// Generate random number of length l
function randLen(l) {
var n = '';
while (n.length < l) {
n += String(Math.random()).replace(/^0\.0*/,'');
}
return n.substring(0, l);
}
It must return a string since converting to number will mess with the results. Oh, and all numbers are integers.
Why not? Here is the code:
var a=[];
for (var i=1000; i--;)
a.push(Math.random()*10000000000)