SitePoint Sponsor 

User Tag List
Results 1 to 17 of 17
Thread: Code advice for a neat math q.

Oct 8, 2010, 17:53 #1
 Join Date
 Oct 2010
 Posts
 5
 Mentioned
 0 Post(s)
 Tagged
 0 Thread(s)
Code advice for a neat math q.
Gentlemen; I started learning javascript a week ago or so and wanted to tackle this math question that I remembered from many many moons back:
There is a math contest held in a city and 1 to 10 people are joining from 67 cities. So a min of 67 and a max of 670 people. Each contestant was given a number in order of their entrance into the contest hall. After the results are announced, they ask the champion what his entrance number to the hall was, and he replies: "The sum of the people entering before me and the sum of the people entering after me are equal. See if you can find my number?"
Really neat question, for me anyways.
It took me a while to write this code and it worked. But I'm sure it could be written in a much nicer/tidier fashion.
Pls advise. Thank you kindly.
for (i=40; i<=500; i++)
{
var p = ((i1)*i)/2
for (x=1; x<=100; x++)
{
if ((((i+x)*(i+(x+1))/2)ip)==p)
alert(i)
if ((((i+x)*(i+(x+1))/2)ip)>p)
break;
}
}
p.s. I chose to start from 40 and end at 500 after a quick calculation (rounded the numbers) cause less than 40 and more than 500 would not be possible. Or so me thinks.

Oct 8, 2010, 18:14 #2
 Join Date
 Aug 2010
 Location
 At my computer
 Posts
 2,012
 Mentioned
 0 Post(s)
 Tagged
 0 Thread(s)
By "the sum of the people" I assume you mean the sum of the number of people.
In that case for the champion to have had the same number entering before him/her as the number entering afterwards then the total number of people entering must be an odd number.
Therefore isn't the champion's entrance number simply
Code:((number of total people  1) / 2) + 1
Or have I misunderstood something?

Oct 8, 2010, 19:32 #3
 Join Date
 Oct 2010
 Posts
 5
 Mentioned
 0 Post(s)
 Tagged
 0 Thread(s)
sorry I wasn't very clear maybe but the sum in this case is: 1+2+3+4+5. For ex. if he was the 100th person to go into the hall then that would mean 1+2+3+4+5+......99 has to equal 101+102+103+104+....n.

Oct 8, 2010, 21:27 #4
 Join Date
 Aug 2010
 Location
 At my computer
 Posts
 2,012
 Mentioned
 0 Post(s)
 Tagged
 0 Thread(s)
ok, nice brain teaser
I did it this way and both your code and mine give the same answer.
The champion's number is 204 and the before and after sums = 20706
Your code is less lines though.
Code:<!DOCTYPE html PUBLIC "//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <script type="text/javascript"> window.onload=function() { var sumBefore = 0; var sumAfter = 0; for (var totPpl=67; totPpl <= 670; totPpl++) { for(var i=1; i <= totPpl; i++) { sumBefore = 0; sumAfter = 0; //add up all the before numbers for(var j=0; j < i; j++) { sumBefore += j; } //add up all the after numbers for(var j=i+1; j <= totPpl; j++) { sumAfter += j; } if(sumBefore == sumAfter) { alert('i = '+i+"\n\nsumBefore and sumAfter = "+sumBefore); totPpl = 671; //end processing i = totPpl; } } } //end of main for loop alert('end'); } </script> </head> <body> </body> </html>

Oct 9, 2010, 16:44 #5
 Join Date
 Oct 2010
 Posts
 5
 Mentioned
 0 Post(s)
 Tagged
 0 Thread(s)
Hi Kalon; I seem to be getting an error: "Stop running Javascript?" message when I copy/pasted all your code. I wonder if I'm doing sth wrong? Does it run fine for you?

Oct 9, 2010, 16:49 #6
 Join Date
 Apr 2006
 Posts
 802
 Mentioned
 0 Post(s)
 Tagged
 0 Thread(s)
The next year, each of the 67 cities sent between 10 to 100 athletes,
and the same champion gave the same answer.
This time, he was number 1189 of 1681 contestants.
But the next year, when the number of entries increased tenfold again,
they could not tell if he was number 6930 of 9800 or 40391 of 57121,
so they gave the prize to the first runner up,
and the old champion swore off addition forever.
Yet another method, this one quits calculating as soon as the followers total less than the preceders:
Code:function whichEntrant(max, min){ min= min  1; var B= [], before= 0, after, next, n= 1; while(n< max){ before+= n++; after= next= n+1; if(n>= min){ while(after<before && next< max){ after+= ++next; } if(after== before){ B.push('Number '+n+' of '+next+' entrants'); } if(after<before) break; } } if(B.length)return 'The entrant is '+ B.join(' or\n'); else return 'You need more entrants to solve this.'; }
// The entrant is Number 204 of 288 entrants.Last edited by mrhoo; Oct 9, 2010 at 16:59. Reason: formatting

Oct 9, 2010, 18:01 #7
 Join Date
 Aug 2010
 Location
 At my computer
 Posts
 2,012
 Mentioned
 0 Post(s)
 Tagged
 0 Thread(s)
I only get that pop up prompt in IE and not in any of the other browsers (FF, Opera, Chrome and Safari)
I think IE senses you're doing a lot of "number crunching" and so asks if you want to continue or not. I just keep clicking 'No" (to the question to stop running the script) 34 times and eventually the 204 answer pops up.

Oct 12, 2010, 14:08 #8
 Join Date
 Oct 2010
 Posts
 5
 Mentioned
 0 Post(s)
 Tagged
 0 Thread(s)
Kalon and mrhoo; thank you so much for the effort. I can run both codes with success. By changing the min max values or totPpl value can arrive at 6, 35, 204 and 1189 which are all similar type of numbers.
mrhoo, I cannot get at the higher numbers you mentioned as I get a javascript terminate alert.
However I am not at a level to follow the logic in the code through.
Is there a way to see what the code is doing step by step; that might help me understand what the code is doing on each line on every loop etc.
I am presently using the free HTML Kit on Windows platform and can't seem to find such a feature in it.
Any suggestions?

Oct 12, 2010, 14:21 #9
 Join Date
 Oct 2010
 Posts
 5
 Mentioned
 0 Post(s)
 Tagged
 0 Thread(s)
I just realized the relationship between those numbers:
1, 6, 35, 204, 1189, 6930, 40391
(x 6  the previous number) as in
(6 x 6 1) = 35
(35 x 6  6) = 204
(204 x 6  35) = 1189
(1189 x 6  204) = 6930
(6930 x 6  1189) = 40391
so the next number should be:
(40391 x 6  6930) = 235416
WOW! This would also make an interesting number pattern question.

Oct 12, 2010, 22:11 #10
 Join Date
 Apr 2006
 Posts
 802
 Mentioned
 0 Post(s)
 Tagged
 0 Thread(s)
You can do something similar to get the total number of entrants
that satisfies the problem
next total= current total*6  previous total+2;
The first ten results match with bruteforce
testing each number, but I haven't got a proof to rely on the pattern holding up forever.
Nice puzzle!
Code:function guesswho(){ var A= [1, 6], B= [1, 8], C= ['1. 6 of 8'], y= 8, x= 6, limit= Math.pow(2, 51), i=2; while(x && y){ x= A[A.length1]*6 A[A.length2]; if(x<limit) A.push(x); else x= null; y= B[B.length1]*6 B[B.length2]+2; if(y<limit){ B.push(y); C.push((i++)+'. '+x+' of '+y); } else y= null; } return C; }
/* returned value: (String)
1. 6 of 8
2. 35 of 49
3. 204 of 288
4. 1189 of 1681
5. 6930 of 9800
6. 40391 of 57121
7. 235416 of 332928
8. 1372105 of 1940449
9. 7997214 of 11309768
10. 46611179 of 65918161
11. 271669860 of 384199200
12. 1583407981 of 2239277041
13. 9228778026 of 13051463048
14. 53789260175 of 76069501249
15. 313506783024 of 443365544448
16. 1827251437969 of 2584123765441
17. 10650001844790 of 15061377048200
18. 62072759630771 of 87784138523761
19. 361786555939836 of 511643454094368
*/
You should also be able to check the first 710 results from this, depending on the browser:
Code:function whichEntrant(max, min){ min= min  5; var out= [], after, next, before= 0, n= 1; while(n+1< min) before+= n++; after= next= n+1; while(n< max){ before+= n++; after= n; while(after< before && next< max){ after+= ++next; } if(after== before){ out[out.length]= n+' of '+next; } if(after< before  n>46611179) n= max; } return out; }
Beyond 10 you need to use a repeating method that does a bite at a time,
and you need BigIntegers
the sums get beyond javascript's integer precision at 2^51,which is the sum of something
less than the first ninety million digits..
So lets find the proof instead...Last edited by mrhoo; Oct 12, 2010 at 22:38. Reason: added brute force method

Oct 13, 2010, 09:16 #11
 Join Date
 Apr 2006
 Posts
 802
 Mentioned
 0 Post(s)
 Tagged
 0 Thread(s)
I'd like to replace my last post I nearly forgot the original riddle.
I still haven't proved it, but this should work:
Code:function guesswho(min, max){ min= min  6; max= max  Math.pow(2, 51); var who= [1, 6], total= [1, 8], x= 6, y= 8, C= min> 6? []: ['6 of 8']; while(y){ y= total[1]*6 total[0]+2; if(y<max){ x= who[1]*6 who[0]; who= [who[1], x]; total= [total[1], y]; if(x>= min) C.push(x+' of '+y); } else y= null; } return C; }
test 1: 'The champion is number '+ guesswho(67, 670)+' entrants.'
return: The champion is number 204 of 288 entrants.
*/
/*
test 2:
'Solutions:\n'+
guesswho().map(function(itm, i){return i+1+'.\t'+itm}).join('\n');
return:
Solutions:
Code:1. 6 of 8 2. 35 of 49 3. 204 of 288 4. 1189 of 1681 5. 6930 of 9800 6. 40391 of 57121 7. 235416 of 332928 8. 1372105 of 1940449 9. 7997214 of 11309768 10. 46611179 of 65918161 11. 271669860 of 384199200 12. 1583407981 of 2239277041 13. 9228778026 of 13051463048 14. 53789260175 of 76069501249 15. 313506783024 of 443365544448 16. 1827251437969 of 2584123765441 17. 10650001844790 of 15061377048200 18. 62072759630771 of 87784138523761 19. 361786555939836 of 511643454094368
Last edited by mrhoo; Oct 13, 2010 at 09:20. Reason: formatting results

Oct 13, 2010, 17:17 #12
 Join Date
 Apr 2006
 Posts
 802
 Mentioned
 0 Post(s)
 Tagged
 0 Thread(s)
Another interesting pattern is that the sum of the last
champion's number and the total entrants added to the current champion's
number equals the current total entrants.
Code:function guesswho(min, max){ min= min  6; max= max  Math.pow(2, 51); var x= 6, y= 8, numbers= [1, x, y], solution= []; while(y<max){ if(x>= min) solution.push(x+' of '+y); x= numbers[1]*6 numbers[0]; y= x+numbers[1]+numbers[2]; numbers= [numbers[1], x, y]; } return solution; }

Oct 14, 2010, 12:07 #13
 Join Date
 Apr 2006
 Posts
 802
 Mentioned
 0 Post(s)
 Tagged
 0 Thread(s)
// Its hard to leave this alone.
Code:function runnersNumber(min, max){ var limit= Math.pow(2, 51); min= min && min> 0? min: 6; max= max && max<limit? max: limit; var runner= 1, total= 1, prev, numbers= [0, runner], solution= []; while(total< max){ if(runner>= min){ solution.push(runner+' of '+total); } prev=numbers[1]; runner= runner*6 numbers[0]; total+= runner+prev; numbers= [prev, runner]; } return solution; }
to return the first 19 (excluding a race with one runner,
which also satisfies the riddle)Code:if([].map){ runnersNumber().map(function(itm, i){ return i+1+'.\t'+itm }).join('\n'); } else runnersNumber().join('\n');

Nov 12, 2010, 18:09 #14
 Join Date
 Jan 2007
 Location
 Christchurch, New Zealand
 Posts
 14,729
 Mentioned
 104 Post(s)
 Tagged
 4 Thread(s)
Here's how I worked it out:
The sum from 1 to 10 can be calculated by adding successive terms from the end of the list
1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10
=
(1 + 10) + (2 + 9) + (3 + 8) + (4 + 7) + (5 + 6)
The formula for this is:
(1 + 10) * 5
Or more generalised:
(start + end) * (end  start + 1) / 2
Now for the question.
"The sum of the people entering before me and the sum of the people entering after me are equal. See if you can find my number?"
Where 67 >= total <= 670
c = champion's position
t = total people
The sum of people before
(start + end) * (end  start + 1) / 2
or
(1 + c  1) * (c  1  1 + 1) / 2
or
c * (c  1) / 2
The sum of people after
(start + end) * (end  start + 1) / 2
or
(c + 1 + t) * (t  (c + 1) + 1) / 2
or
(c + 1 + t) * (t  c) / 2
So now we have two unknowns, and two equations
c(c  1) / 2 = (c + 1 + t) * (t  c) / 2
or
t(t + c + 1)/2  c(c + 1 + t)/2  c(c  1) / 2 = 0
or
t(t + c + 1)  c(c + 1 /2
or
t(t + 1)  c(2c) = 0
or
t^2 + t  2c^2 = 0
So, we're looking for when
t^2 + t = 2c^2
c^2 = (t^2 + t) / 2
t^2 = 2c^2  t
So, we can check for when
sqrt(t^2 + t) / 2) is a whole number
Code javascript:var champ, i; for (i = 67; i <= 670; i += 1) { champ = Math.sqrt((i * i + i) / 2); if (champ === Math.floor(champ)) { alert('Champion: ' + champ + ', Total: ' + i); } }
Programming Group Advisor
Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
Car is to Carpet as Java is to JavaScript

Nov 12, 2010, 21:13 #15
 Join Date
 Apr 2006
 Posts
 802
 Mentioned
 0 Post(s)
 Tagged
 0 Thread(s)
I found you can go one magnitude higher than I was trying with normal javascript integers.
Code:function runnersNumber(min, max){ var limit= Math.pow(2, 53)1; min= min && min> 0? min: 6; max= max && max<limit? max: limit; var runner= 1, total= 1, prev, numbers= [0, runner], solution= []; while(total< max){ if(runner>= min){ solution.push(runner+' of '+total); } prev=numbers[1]; runner= runner*6 numbers[0]; total+= runner+prev; numbers= [prev, runner]; } return solution; } alert(runnersNumber().join('\n')) /* returned value: (String) 6 of 8 35 of 49 204 of 288 1189 of 1681 6930 of 9800 40391 of 57121 235416 of 332928 1372105 of 1940449 7997214 of 11309768 46611179 of 65918161 271669860 of 384199200 1583407981 of 2239277041 9228778026 of 13051463048 53789260175 of 76069501249 313506783024 of 443365544448 1827251437969 of 2584123765441 10650001844790 of 15061377048200 62072759630771 of 87784138523761 361786555939836 of 511643454094368 2108646576008245 of 2982076586042449 */

Nov 12, 2010, 21:18 #16
 Join Date
 Aug 2010
 Location
 At my computer
 Posts
 2,012
 Mentioned
 0 Post(s)
 Tagged
 0 Thread(s)
Off Topic:
hmmmmmmm....interesting
I wonder if the "powersthatbe" could set up a "Brain Teaser" forum where we could have a separate thread for each brain teaser someone would like to post.

Nov 13, 2010, 05:35 #17
 Join Date
 Jan 2007
 Location
 Christchurch, New Zealand
 Posts
 14,729
 Mentioned
 104 Post(s)
 Tagged
 4 Thread(s)
It appears that the sequence is one of triangular numbers that are also square.
A square with sides that are 1189, has the same area as a triangle with sides of 1681.
http://www.whatabeginning.com/BBooks...onLegacy/P.htm
They all relate to root 2
8/6 = 49/35 = 288/204 = 1189 / 1681Programming Group Advisor
Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
Car is to Carpet as Java is to JavaScript
Bookmarks