Javascript Smallest Multiple Keeps Crashing - javascript

I am currently going through project euler trying to get better at javascript. I am stuck on one problem that i can't seem to figure out.
The question is:
2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder. What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?
So I searched stack and found a few similar topics when i got stuck but everyones code seems to be a bit more complex than what I came up with. My problem is i was able to create the correct program to find the smallest multiple from 1-10 which i was able to get 2520 with.
However, when i adjust my program to work for numbers 1-20 it crashes. I can get 1-19 but once i do 20 i keep crashing. Here is my code. If you change it to count != 10 and i <= 10 you can get the answer 2520 but 20 just doesn't seem to work. Any help would be appreciated.
<script>
var num = 0;
var count = 0;
while (count != 20) {
num++;
count = 0;
for (var i = 1; i <= 20; i++) {
if (num % i == 0) {
count++;
}
}
}
console.log(num);
console.log(count);
</script>

It doesn't crash, just takes long time, since your script is inefficient.
<script>
var num = 0;
var count = 0;
var numbers=20;
while (count != numbers) {
num+=numbers;
count = 0;
for (var i = 1; i <= numbers; i++) {
if (num % i == 0) {
count++;
}
else {break;}
}
}
console.log(num);
console.log(count);
</script>

Yeah, not breaking, just taking a REALLY long time. This should be a much more efficient approach:
var num = 1;
var isDivisible = false;
var startTime = (new Date().getTime());
while (!isDivisible) {
for (var i = 20; i > 1; i--) {
if (num % i !== 0) {
isDivisible = false;
num = num + (i + 1);
break;
}
else {
isDivisible = true;
}
}
}
console.log(num);
console.log("Finished in " + (((new Date().getTime()) - startTime) / 1000) + " seconds");
Results:
232792560
Finished in 0.166 seconds
Note: above results from JSFiddle . . . finished in 26.57 seconds in Firebug. :)

Related

Determine an Odd/even Number, And Use While Loop To Add From Counter in Javascript

I do not know why it stops looping after satisfying the condition sometime(eg.getting the sum of number from where it precedes). I believe that there's something wrong with the code. Where is it?
var init = parseInt(prompt('enter an odd or even no.'));
var sec = init%2;
if (sec != 0) {
var loop = 5;
while (loop < 10) {
var num = 1;
loop += loop;
num += 2
}
document.write(num);
} else {
document.write('None');
}
Is this what you are trying to do? Variables declared with var don't have block scope, so it can be clearer to declare them all at the top of your code.
var init = parseInt(prompt('enter an odd or even no.'));
var sec = init % 2;
var loop = 5;
var num = 1;
if(sec != 0) {
while(loop < 10) {
num+=2;
loop++;
document.write(num);
}
} else {
document.write('None');
}
The looping is happening, but you're just not seeing it because you don't print anything when it loops.
Your code should be like this instead:
var init = parseInt(prompt('enter an odd or even no.'));
var sec = init%2;
if (sec != 0) {
var loop = 5;
while (loop < 10) {
var num = 1;
loop += loop;
num += 2
document.write(num);
}
} else {
document.write('None');
}
See that document.write(num) now is INSIDE your loop, so it will print every time it loops through.
Previously, it was set outside, so essentially what was happening is that you were only seeing the result AFTER the last iteration.
You need to initialize num with 1 outside of the while statement, because you assign this value for every loop.
The I suggest to declare all variable in advane at top of the code. You may assign here known values, too.
var init = parseInt(prompt('enter an odd or even no.'), 10),
sec = init % 2,
loop = 5,
num = 1;
if (sec != 0) {
while (loop < 10) {
loop += loop;
num += 2;
}
document.write(num);
} else {
document.write('None');
}

The for loop in this program isn't working as expected

It is supposed to print prime n numbers. The for loop will run from 2 to x which will iterate each time. if i == x then it means that the number was not divisible and so it should be printed as prime
var n;
var x = 2;
var i;
function prime(n) {
while (n) {
for (i = 2; i < x; i++) {
if (x % i == 0) {
break;
}
if (i == x) {
document.write(i + " ");
n--;
}
x++;
}
}
}
prime(10);
When you try to execute this code, this will never get into the for loop and goes into an infinite while loop. You have got:
i = 2; i < x;
The i will never be less than x. And it doesn't enter the for loop and comes out. And n will always be 10, that goes on into an infinite loop.
You need to use the modulus operator to check if a number is divisible by them.
Maybe change your approach a bit and try to find the first X prime number using just for loops.
var n;
var x = 2;
var i;
function prime(n) {
if (n <= 0) return;
var i, j, p_no = 0, res = [];
for (i = 2; ; i++) {
var ifPrime = true;
for (j = 2; ifPrime && j <= Math.sqrt(i); j++) {
if (i % j === 0) ifPrime = false;
}
if (ifPrime) {
res.push(i);
console.log(i + ' ');
p_no++;
if (p_no === n) return res.toString();
}
}
}
document.getElementById('prime').innerHTML = prime(10);
<p id="prime"></p>
What's happening when the code runs is what Praveen describes. I want to address how you got to your algorithm in the first place.
It looks like you're trying to print all primes less than a specific number n. You've jumbled different aspects of your algorithm together. Specifically, you've combined a loop that exists to find whether a number is prime with a loop over all numbers less than n.
The first thing you can do to help manage this complexity is to use methods. If you had a method isPrime(k) that returns true or false if a given number is prime, then your function's main loop looks much simpler, and separates the two problems from each other:
function prime(n) {
for (var i = n; i > 1; i--) {
if (isPrime(i)) {
document.write(i + " ");
}
}
}
Then you can focus on defining the isPrime method separately, without getting its parts confused with the main loop:
function isPrime(k) {
for (var i = 2; i < k; i++) {
if (k % i == 0) {
return false;
}
}
return true;
}
Methods are a fantastic way of keeping algorithms simpler by isolating their components. They're building blocks one can use to make more complex systems without having to keep track of the whole. It lets you make smaller changes, each encapsulated from other concerns, meaning you have less to keep in your mind while you're making those changes. The less you have to keep in your mind, the easier it is to spot mistakes.

How can I stop my loop at number +/- 10 instead of stopping at the number 10?

As shown in the code below, my loop will carry on forever.
I want the program to take the users input and add or subtract 10 based on whether they say up or down by using increments and decrements.
Any hints or help would be amazing! Thank you in advance.
function runprogram() {
var thenumber=prompt('Give me a number to increment or decrement!')
var updown=prompt('Should I increment it up or down?')
var thenumberup= (thenumber + 10)
var thenumberdown=(thenumber - 10)
var i;
if(updown == 'up') {
for(i = thenumber; i < 10; i++) {
alert(i);
}
}
if(updown == 'down') {
for (i = thenumber; i > 10 ; i--) {
alert(i);
}
}
}
The result of the first prompt call is not a number, you must coerce it to a number with +prompt('...').
As #Adrián mentioned in the comments, the comparisons should also be <= and >= otherwise it will stop directly before the target number.
function runprogram() {
var thenumber = +prompt('Give me a number to increment or decrement!')
var updown = prompt('Should I increment it up or down?')
var thenumberup = (thenumber + 10)
var thenumberdown = (thenumber - 10)
var i;
if (updown == 'up') {
for (i = thenumber; i <= thenumberup; i++) {
alert(i);
}
}
if (updown == 'down') {
for (i = thenumber; i >= thenumberdown; i--) {
alert(i);
}
}
}
runprogram();
While you've got an answer that does what you need, I find it a little dissatisfying that you have two loops. Here's another way you could do this with a single loop (by storing a multiplier depending on the direction given):
function run() {
var number = +prompt('number', 0)
var direction = prompt('up or down?', 'up')
var multiplier = direction === 'up' ? 1 : -1
for (var i = 0; i < 10; i++) {
alert(number + (i * multiplier));
}
}
run();

My Solution to the Largest Palindrome of the product of two 3 digit numbers needs work

The answer I'm getting is not the correct one (correct answer is 906609). Please help me understand where I am going wrong. I want the while loop to go from 100 to 999 while multiplying itself against the current i value before the loop increments it.
// A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.
// Find the largest palindrome made from the product of two 3-digit numbers.
var pali = [];
function palindrome() {
for (var i = 100; i <= 999; i++) {
var counter = 100;
while (counter <= 999) {
var result = counter * i;
if (result.toString() === result.toString().split("").reverse().join("")) {
pali.push(result);
}
counter++;
}
}
return pali[pali.length - 1];
}
console.log(palindrome());
You're going to have to sort the array in ascending order if you want the last one to be the highest:
pali.sort(function(a, b){return a-b});
Using that, I get 906609.
Lengthier, but faster. Starting at the max values and working down, short circuiting when we won't find higher values:
function largestPalindromeProduct(lower, upper) {
var palindrome = 0;
var outerLow = lower;
var outer = upper;
while (outer > outerLow) {
var inner = upper;
var innerLow = lower;
while (inner > innerLow) {
var result = inner * outer;
if (result + "" === (result + "").split("").reverse().join("")) {
if (result > palindrome) {
palindrome = result;
outerLow = inner; // Don't go lower than this value in the outer, no need!
}
inner = innerLow; // short-circuit this loop
}
inner--;
}
outer--;
}
return palindrome;
}
console.log(largestPalindromeProduct(100, 999))
I think the easiest way will be to add a If statement.
function palindrome()
{
var max = 0;
for (var i = 999; i >= 100; i--)
{
var counter = 999;
while (counter >= 100)
{
var result = counter * i;
if (result.toString() === result.toString().split("").reverse().join(""))
{
if(result>max)
{
max = result;
}
}
counter++;
}
}
return max;
}

Print even numbers from 1-100 with 5 numbers per line

trying to brush up on some basic javascript and I'm wondering how you would solve this. I found a way but it's pretty ugly and I'd appreciate some more experienced eyes letting me know what they thing. Basically, just iterate over the numbers 1-100 and print all even numbers in groups of five on each line. So line one would be 2,4,5,8,10, line 2 is 12,14,16,18,20. Here is what I have so far:
var counter = 0;
var line=[];
for(var i = 0; i<=100; i++){
if(i%2==0){
if(line.length <5){
line[counter] = i;
counter++
}else{
console.log(line);
line=[];
counter=0;
line[counter] =i;
}
}
}
console.log(line);
Thanks so much!
console.log(2,4,6,8,10);
console.log(12,14,16,18,20);
console.log(22,24,26,28,30);
console.log(32,34,36,38,40);
console.log(42,44,46,48,50);
console.log(52,54,56,58,60);
console.log(62,64,66,68,70);
console.log(72,74,76,78,80);
console.log(82,84,86,88,90);
console.log(92,94,96,98,100);
With most hypothetical programming problems, it's most worthwhile to address their lack of rooting in reality and do what is simplest — reality is sure to prove to be much more complicated.
As for learning exercises, those typically work best when you solve them yourself.
The problems that I see with the code is that you are looping from 0 instead of 1, and that you are not increasing the counter in the else block.
Fixing that you get:
var counter = 0;
var line=[];
for (var i = 1; i <= 100; i++) {
if (i % 2 == 0){
if (line.length < 5) {
line[counter] = i;
counter++
} else {
console.log(line);
line=[];
counter = 0;
line[counter] = i;
counter++
}
}
}
console.log(line);
Instead of looping from 1 to 100 and checking if the number is even, just loop from 2 to 100 in steps of two. You don't need the counter at all, you can push the items into the array. Instead of repeating the code that adds an item to the array in the if and else blocks you can just do it once after.
With those simplifications you get:
var line=[];
for (var i = 2; i <= 100; i += 2) {
if (line.length == 5) {
console.log(line);
line=[];
}
line.push(i);
}
console.log(line);
var line = [];
//you are uninterested in odd numbers, so increment the counter by 2
for(var i = 0; i <= 1000; i = i + 2) {
line.push(i);
if((i + 2) % 5 === 0) { //every 5 lines print result
console.log(line);
line = []
}
}
<script>
var counter = 0;
var line = [];
for (var i = 2; i <= 100; i += 2) {
line[counter] = i;
counter++;
if (line.length == 5) {
console.log(line);
counter = 0;
line = [];
}
}
</script>
Same as yours, but use a loop incrementing by 2

Categories