Why isn't my attempted solution working? - javascript

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.

Related

Alternate numbers into two rows

I think I'm having a brain fart, because I can't figure out a simple formula to be able sort a sequence of number into specific order so it can be printed 2 numbers per sheet of paper (one number on one half and second number on second half), so when the printed stack of paper cut in half, separating the numbers, and then these halves put together, the numbers would be in sequence.
So, let's say I have 5 numbers: 3,4,5,6,7, the expected result would be 3,6,4,7,5 or
0,1,2,3,4,5,6,7 would become 0,4,1,5,2,6,3,7
My thought process is:
create a loop from 0 to total number of numbers
if current step is even, then add to it total numbers divided in 2
Obviously, I'm missing a step or two here, or there is a simple mathematical formula for this and hopefully someone could nudge me in a right direction.
This is what I have so far, it doesn't work properly if start number set to 1 or 3
function show()
{
console.clear();
for(let i = 0, count = end.value - start.value, half = Math.round(count/2); i <= count; i++)
{
let result = Math.round((+start.value + i) / 2);
if (i && i % 2)
result = result + half -1;
console.log(i, "result:", result);
}
}
//ignore below
for(let i = 0; i < 16; i++)
{
const o = document.createElement("option");
o.value = i;
o.label = i;
start.add(o);
end.add(o.cloneNode(true));
}
start.value = 0;
end.value = 7;
function change(el)
{
if (+start.value > +end.value)
{
if (el === start)
end.value = start.value;
else
start.value = end.value;
}
}
<select id="start" oninput="change(this)"></select> -
<select id="end" oninput="change(this)"></select>
<button onclick="show()">print</button>
P.S. Sorry, about the title, couldn't come up with anything better to summarize this.
You could get the value form the index
if odd by using the length and index shifted by one to rigth (like division by two and get the integer value), or
if even by the index divided by two.
function order(array) {
return array.map((_, i, a) => a[(i % 2 * a.length + i) >> 1]);
}
console.log(...order([3, 4, 5, 6, 7]));
console.log(...order([0, 1, 2, 3, 4, 5, 6, 7]));

Codility Ladder javascript - not understanding a detail that jumps the answer from 37 to 100%

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;
}

Project Euler Q#2 in "javascript"

the sum of even Fibonacci numbers below 4 mill : i am trying to do it using JavaScript, but i am getting infinity as an answer
but if i use small number such as 10, i am getting console.log() output with the result, is it possible to do that in JavaScript??
var fib = [1, 2];
for(var i =fib.length; i<4000000; i++)
{
fib[i] = fib[i-2] + fib[i-1];
}
//console.log(fib);
var arr_sum = 0;
for(var i = 0; i < fib.length; i++){
if(fib[i] % 2 === 0){
arr_sum += fib[i] ;
}
}
console.log(arr_sum);
So this is the problem:
Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
The correct answer is 4613732.
On the script below, the answer would be from variable "sum". I assigned it an initial value of 2 since that is the first even number on our sequence. I used 3 more variables to traverse through this sequence. The loop runs normal Fibonacci sequence and the if statement filters even numbers and adds it to the sum.
I think this is the simplest and most intuitive code implementation.
var sum = 2;
var x = 1, y = 2, fib;
while(x < 4000000) {
fib = x + y;
x = y;
y = fib;
if(fib%2===0) sum += fib;
}
console.log(sum);
Two things before I get to coding:
You need to sum the even fibonacci numbers which VALUE below 4 Million (#Alnitak)
There is an "even fibonacci series" which can be calculated in a different manner, see here.
Alright here we go:
let fib = [0, 2];
for(let i = 2; fib[i-1] < 4000000; i++) {
fib[i] = 4 * fib[i - 1] + fib[i - 2];
}
fib.pop()
let sum = fib.reduce((a, c) => a + c, 0);
console.log(sum);
Edit
Without the fib.pop() I just added, the last element of the array would be a number > 4000000. Now you should be able to get the right result.

Google Code Jam 2016 : How Can I optimize the Code?

Problem:
Bleatrix Trotter the sheep has devised a strategy that helps her fall asleep faster. First, she picks a number N. Then she starts
naming N, 2 × N, 3 × N, and so on. Whenever she names a number, she
thinks about all of the digits in that number. She keeps track of
which digits (0, 1, 2, 3, 4, 5, 6, 7, 8, and 9) she has seen at least
once so far as part of any number she has named. Once she has seen
each of the ten digits at least once, she will fall asleep.
Bleatrix must start with N and must always name (i + 1) × N directly after i × N. For example, suppose that Bleatrix picks N =
1692. She would count as follows:
N = 1692. Now she has seen the digits 1, 2, 6, and 9.
2N = 3384. Now she has seen the digits 1, 2, 3, 4, 6, 8, and 9.
3N = 5076. Now she has seen all ten digits, and falls asleep.
What is the last number that she will name before falling asleep? If she will count forever, print INSOMNIA instead.
https://code.google.com/codejam/contest/6254486/dashboard
Array.prototype.unique = function () {
return this.filter(function (value, index, self) {
return self.indexOf(value) === index;
});
}
var uniqueArr = [];
var Number = 1692;//Any number
for (i = 1; ; i++) {
var x = Number * i;
while (x > 0) {
uniqueArr.push(x % 10); //Converting number to Digits and pushing them into an array.
x = Math.floor(x / 10);
}
var ar = uniqueArr.unique();
if (ar.length == 10) {
console.log(uniqueArr.unique(), Number * i);
break;
}
}
As long as x is always a positive number* (which is the case here) you could use
x = ~~(x / 10)
instead of
x = Math.floor(x / 10)
Which does the same job but is ~5 times faster. Its more an obvious improvement but it optimize the code anyway.
* ~~ is a bitwise operator, which just cuts off everything after the comma. So ~~-6.6 will result -6, but Math.floor(-6.6) gives you a -7. Be carefull here.

breaking an integer into parts

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.

Categories