The integers 1 through 12345 (inclusive) are written in a row in ascending order. You and your friend take turns removing numbers according to the following rules:
- Step 1: You remove numbers from all odd positions (i.e. 1, 3, 5, ..., 12345).
- Step 2: Your friend removes numbers from all even positions (i.e. 4, 8, ... because 2 is now in position #1 and 6 is in position #3, and so on).
- Step 3: If there is more than one number remaining on the list, repeat the steps above.
What is the last number remaining after completing these steps?
Note:
The diagram to the right illustrates the case for a list of numbers 1 to 8.
This section requires Javascript.
You are seeing this because something didn't load right. We suggest you, (a) try
refreshing the page, (b) enabling javascript if it is disabled on your browser and,
finally, (c)
loading the
non-javascript version of this page
. We're sorry about the hassle.
Excellent approach ....
Please check out my solution... regards
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
I used Dev C++ to solve this ^-^
impressive
And that's why I love pyhon:
1 2 3 4 5 6 |
|
Log in to reply
As I read the instruction, steps 1 & 2 will always occur together, with the only decision in step 3. Fortunately, step 2 always leaves the 1st element of the array anyway. So the code in my loop was simply a=(a[1::2])[0::2].
Interestingly, Python3 is smart enough to see that each such iteration simply filters the original range. If you print out the range variable at each step, it will return this sequence:
range(1, 12346)
range(2, 12346, 4)
range(6, 12350, 16)
range(22, 12374, 64)
range(86, 12374, 256)
range(342, 12630, 1024)
range(1366, 13654, 4096)
range(5462, 13654, 16384)
range(21846, 21846, 65536)
…
Log in to reply
Yep, I later saw you solution, no need for if. The smart behaviour of range is really impressing, wow!
Can I get the solution in C language??!!
Log in to reply
Sorry, I haven't understood your question.
In the C language, change the first line to
#include<stdio.h>
and remove the
using namespac std;
line. Then it should work.
THOUGHTS ABOUT SOLUTION WITH CODE
There is such a thing as getting the answer without solving the problem. Emulating the described steps as a brute force "solution" in code is an example.
Applying the mathematical result and some programming technique produces code that uses minimal resources in both time and space (without arrays or recursion stack) that are fixed regardless of list length, and can be optimized by replacing floating point calculations with pure fixed point operations. This lends some depth to the programming side of the solution. The brute force step emulation examples regardless of number of lines of code used all negate the value of the problem both as a math exercise and a programming exercise. That is the objection to most if not all of the program code "solutions".
The starting number (head) of the 1st list is 1, where the list The starting number (head) of the 2nd list is 2, where the list The starting number (head) of the 3rd list is 6, where the list = [ 1 , 2 , 3 , 4 , . . . , 1 2 3 4 5 ] = [ 2 , 4 , 6 , 8 , . . . , 1 2 3 4 4 ] = [ 6 , 1 0 , 1 4 , . . . , 1 2 3 4 4 ] or in genral the value of head of the list after K iterations will be h e a d ( K ) = 3 ( 4 K + 2 ) . . . . . . . ( 1 )
A list with h e a d ( n ) > 1 2 3 4 5 will be empty this ⟹ that the answer is max ( h e a d ( n ) ) where h e a d ( n ) ≤ 1 2 3 4 5
Let N be the value of n that satisfies equation, Let S to be the upper bound of the range s = 1 2 3 4 5 in this case
Solving equation (1) gives N = ⌊ l o g 4 ( 3 S − 2 ) ⌋
the general answer is h e a d = ⌊ 3 ( 4 N + 2 ) ⌋
In this problem S = 1 2 3 4 5 ⟹ N = 7
h ( N ) = 3 ( 4 N + 2 ) = 3 ( 4 7 + 2 ) = 3 ( 1 6 3 8 4 + 2 ) = 3 1 6 3 8 6 = 5 4 6 2
This solution is fine-- one thing is missing, and that is the derivation of the equation head ( K ) = 3 4 K + 2 .
Log in to reply
Just geometric sum and some algebra. It is fully derived over at my solution.
Log in to reply
I don't see where your eqn. (1) comes from.
Log in to reply
@Arjen Vreugdenhil – Not sure which you mean, as there is not "(1)" type reference used in my solution. . Are you still referring to this Ismail solution. I was referring to my posted solution elsewhere that I think explains Ismail's (1) adequately, and uses a somewhat simpler explanation for it without the "head' business. You are quite right, Ismail just throws that it there, as if the fact that it fits the first three entries shown insures that late entries must follow the pattern (and in this case, they do) without proof.
Log in to reply
@Robert DeLisle – I see what you mean. Yes, I thought that you were talking about this post. You are right that it is "just geometric sum and some algebra". But that is precisely the interesting part of the problem: how do you know what sum it is, and how do you do the algebra in a clever way? Your solution gives a detailed account of it, but Ossama Ismail's doesn't.
Log in to reply
@Arjen Vreugdenhil – Thank you. Couldn't spare me an upvote while you were there?
Not sure why the this list starts with 6 not two.
Log in to reply
Actually it starts at 1 with 3 4 0 + 2 = 1 . The solution is fully general and works even with a list with one number.
you say that head(N) is the maximum solution it means that the solution cannot be bigger than this particular value but why then you concluded it is the right one , you should know that the upper bound also get smaller with iterations , right ? So it is possible that we end up having a smaller number than head(N) in case the upper bound gets actually smaller than this particular value(S gets smaller and head(n) gets bigger ) , what i want to say is that the S which you plugged(12345) depend also on K the number of iterations so you cannot just fix it and then apply your formula , you should take on consideration that it is changing with iterations .Can you justify the affirmation you said after the implication symbol ? for me it should be (head(n) < S(n) ) where S(n) is the upper bound at an iteration n ) Thank you ,please correct me if i'm wrong .(Ohh and btw not sure the the list is fine )
Write the numbers in base 4. Initially: 1, 2, 3, 10, 11, 12, 13, 20,...
After removing the numbers in odd position: 2, 10, 12, 20, 22, 30, 32, 100,...
After removing the numbers now in even position: 2, 12, 22, 32, 102, 112, 122, 132,...
We have left the numbers ending with 2.
After removing the numbers now in odd position: 12, 32, 112, 132, 212, 232, 312, 332,...
After removing the numbers now in even position: 12, 112, 212, 312, 1012, 1112, 1212, 1312,...
All numbers ending with 12.
Continuing in this way, it's obvious that the smallest remaining number at each cycle follows the pattern 2, 12, 112, 1112,....
The answer is thus the largest number in this sequence not greater than 12345 decimal, namely 1 1 1 1 1 1 2 4 = 5 4 6 2 1 0 .
Nice approach. Excellent observation !!
That's excellent. better math than I used. I did it the hard way starting from the observation that each new position is given by CEILING(p/2), leading to a summation of powers of 4 and a formula, but this clearly shows the powers of four at the core of the problem.
It is annoying how many brute force programs have been posted, some crude,some very clever near one liners, all missing the point, from people who don't care to actually solve the problem.
A recursive Python solution (a bit simpler than the others), which uses Extended Slicing :
1 2 |
|
Prints the correct result, 5462 . Test it online!
Yep, the functional style is the best.
1 2 3 4 |
|
Log in to reply
Actually using math to solve the problem is the best.
For example, (In Excel VBA, for convenience not preference, the input 12345, and output 5462 appear in textboxes on a form.)
Private Function LastNumber(n As Long) As Long
LastNumber = ( 4 ^ ( Int( Log(3 * CDbl(n) - 2 ) / Log(4) )) + 2) / 3
End Function
THOUGHTS ABOUT SOLUTION WITH CODE
There is such a thing as getting the answer without solving the problem. Emulating the described steps as a brute force "solution" in code is an example.
Applying the mathematical result and some programming technique produces code that uses minimal resources in both time and space (without arrays or recursion stack) that are fixed regardless of list length, and can be optimized by replacing floating point calculations with pure fixed point operations. This lends some depth to the programming side of the solution. The brute force step emulation examples regardless of number of lines of code used all negate the value of the problem both as a math exercise and a programming exercise. That is the objection to most if not all of the program code "solutions".
Each step the count of the numbers is halved (rounding down on odd turns and up on even turns.) On even turns, the lowest number remains the same (because it isn't removed.) On odd turns, the lowest number becomes the next number (the lowest number + the step.) On each turn the step between the consecutive values doubles.
turn | count | lowest | step |
- | 12345 | 1 | 1 |
1 | 6172 | 2 | 2 |
2 | 3086 | 2 | 4 |
3 | 1543 | 6 | 8 |
4 | 772 | 6 | 16 |
5 | 386 | 22 | 32 |
6 | 193 | 22 | 64 |
7 | 96 | 86 | 128 |
8 | 48 | 86 | 256 |
9 | 24 | 342 | 512 |
10 | 12 | 342 | 1024 |
11 | 6 | 1366 | 2048 |
12 | 3 | 1366 | 4096 |
13 | 1 | 5462 | - |
If you don't want to do math, make a computer do it for you.
1 2 3 4 5 6 7 |
|
Haha, this is a surprisingly short code. This is one of my favorite things about python.
Log in to reply
Here is my program:
Private Sub cmdDoIt_Click()
txtLastNumber = (4 ^ (Int(Log(3 * CDbl(txtListLength) - 2) / Log(4))) + 2) / 3
End Sub
surprisingly short code, and it doesn't use more time and memory as the list gets longer either. That's one of the things I like about mathematics.
THOUGHTS ABOUT SOLUTION WITH CODE
There is such a thing as getting the answer without solving the problem. Emulating the described steps as a brute force "solution" in code is an example.
Applying the mathematical result and some programming technique produces code that uses minimal resources in both time and space (without arrays or recursion stack) that are fixed regardless of list length, and can be optimized by replacing floating point calculations with pure fixed point operations. This lends some depth to the programming side of the solution. The brute force step emulation examples regardless of number of lines of code used all negate the value of the problem both as a math exercise and a programming exercise. That is the objection to most if not all of the program code "solutions".
After the first 2 steps, the remaining numbers are:
2, 6, 10, 14, 18, 22, 26, 30, ... ( the difference between the numbers is 4)
After 2 more steps the numbers remaining are:
6, 22, 38, 50, ... ( the difference between these numbers is 4x4= 16)
After the next 2 steps, we get:
22, 86, 150,...( the difference is 16x4= 64)
After 2 more steps, we get:
86, 342, 598,... ( difference of 64x4=256)
342, 1366, 2390,... (difference is 256x4= 1024)
1366, 5462, 9558 (difference 1024x4=4096)
The number after 9558 exceeds 12345. ( 9558+4096=13654)
In the next step, the numbers in the odd positions have to be removed. Hence, the answer is 5462
I am not good in mathematics so this is my approach programmatically:
Array starts as [ i ] where i spans from 1 to 12345 First Value: F=1 Spacing: S=1 [1,2,3,......]
Removing odd index causes second value to get to index of first and spacing doubled
F=2, S=2, array=[2,4,6,8......]
Removing even numbers doesn't change First Value while doubling the spacing
F=2, S=4, array=[2,6,10,14......]
Combining the 2 operations above, we know that after each round of taking away odd then even indexes:
F=F+S as value from second index replaces the first
S=S*4 as each operation to remove odd and even index doubles the spaces between the numbers in the array
Starting from F=1,S=1:
F=1,S=1
F=2, S=4
F=6, S=16
F=22, S=64
F=86, S=256
F=342, S=1024
F=1366, S=4096
F=5462, S=8192 <--- Answer
F=13654,S=32768
A short Python3 program that executes the algorithm :
1 2 3 4 5 |
|
THOUGHTS ABOUT SOLUTION WITH CODE
There is such a thing as getting the answer without solving the problem. Emulating the described steps as a brute force "solution" in code is an example.
Applying the mathematical result and some programming technique produces code that uses minimal resources in both time and space (without arrays or recursion stack) that are fixed regardless of list length, and can be optimized by replacing floating point calculations with pure fixed point operations. This lends some depth to the programming side of the solution. The brute force step emulation examples regardless of number of lines of code used all negate the value of the problem both as a math exercise and a programming exercise. That is the objection to most if not all of the program code "solutions".
Even shorter and much faster code can be seen in my posted solution.
Here is my solution, with basic Python 3 functions. The following code could be written in a more pythonic way, but I will keep it simple for all the begginers out there.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
Can I get the solution in C language??!!
Log in to reply
Try getting the solution in mathematics first.
Then you can get a really short program, that doesn't take more effort and memory as the list gets longer as well.
For example, (In Excel VBA, for convenience not preference, the input 12345, and output 5462 appear in textboxes on a form.)
Private Function LastNumber(n As Long) As Long
LastNumber = ( 4 ^ ( Int( Log(3 * CDbl(n) - 2 ) / Log(4) )) + 2) / 3
End Function
THOUGHTS ABOUT SOLUTION WITH CODE
There is such a thing as getting the answer without solving the problem. Emulating the described steps as a brute force "solution" in code is an example.
Applying the mathematical result and some programming technique produces code that uses minimal resources in both time and space (without arrays or recursion stack) that are fixed regardless of list length, and can be optimized by replacing floating point calculations with pure fixed point operations. This lends some depth to the programming side of the solution. The brute force step emulation examples regardless of number of lines of code used all negate the value of the problem both as a math exercise and a programming exercise. That is the objection to most if not all of the program code "solutions".
I cheated a little lol. I used c++. Try it here (https://www.onlinegdb.com/online c++ compiler), replace everything already in the box:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
|
Can i get the solution in C languauge??!!
If one doesn't cheat the result can be a short brutally efficient subroutine that does not need more cycles and memory as the list gets longer. with the list length as a parameter not hard-coded.
For example, (In Excel VBA, for convenience not preference, the input 12345, and output 5462 appear in textboxes on a form.)
Private Function LastNumber(n As Long) As Long
LastNumber = ( 4 ^ ( Int( Log(3 * CDbl(n) - 2 ) / Log(4) )) + 2) / 3
End Function
THOUGHTS ABOUT SOLUTION WITH CODE
There is such a thing as getting the answer without solving the problem. Emulating the described steps as a brute force "solution" in code is an example.
Applying the mathematical result and some programming technique produces code that uses minimal resources in both time and space (without arrays or recursion stack) that are fixed regardless of list length, and can be optimized by replacing floating point calculations with pure fixed point operations. This lends some depth to the programming side of the solution. The brute force step emulation examples regardless of number of lines of code used all negate the value of the problem both as a math exercise and a programming exercise. That is the objection to most if not all of the program code "solutions".
after 2 turns (that is step1 and step2), a sort of compression is performed: m ( x ) = x / 4 + 1 / 2 we can ignore the decimal results, for example after the first 2 turns m maps 2+4q into q
compounding m, I can write m ( k ) ( x ) = m ( . . . m ( x ) ) (k-times)
I found m ( k ) ( x ) = i / 4 k + 3 ∗ 2 2 k − 1 4 k − 1
l o g 4 ( 1 2 3 4 5 ) = 6 . 7 . . . so I expect after applying m 6 to find at most 3 integer remaining values, solution of m ( 6 ) ( x ) = 1 , 2 , 3
because step 1 has to be performed the solution has to be the second (unless the second value is bigger than 12345)
m ( 6 ) ( x ) = 2
x = ( 2 − 3 ∗ 2 2 ∗ 6 − 1 4 6 − 1 ) ∗ 4 6 = 5 4 6 2 that is a valid solution being less then 12345
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
What language is this in? I am guessing R
THOUGHTS ABOUT SOLUTION WITH CODE
There is such a thing as getting the answer without solving the problem. Emulating the described steps as a brute force "solution" in code is an example.
Applying the mathematical result and some programming technique produces code that uses minimal resources in both time and space (without arrays or recursion stack) that are fixed regardless of list length, and can be optimized by replacing floating point calculations with pure fixed point operations. This lends some depth to the programming side of the solution. The brute force step emulation examples regardless of number of lines of code used all negate the value of the problem both as a math exercise and a programming exercise. That is the objection to most if not all of the program code "solutions".
My python solution:
1 2 3 4 5 6 7 8 9 10 11 |
|
THOUGHTS ABOUT SOLUTION WITH CODE
There is such a thing as getting the answer without solving the problem. Emulating the described steps as a brute force "solution" in code is an example.
Applying the mathematical result and some programming technique produces code that uses minimal resources in both time and space (without arrays or recursion stack) that are fixed regardless of list length, and can be optimized by replacing floating point calculations with pure fixed point operations. This lends some depth to the programming side of the solution. The brute force step emulation examples regardless of number of lines of code used all negate the value of the problem both as a math exercise and a programming exercise. That is the objection to most if not all of the program code "solutions".
in Javascript (ES6)
let arr = new Array(12345).fill(0).map((d,i) => i+1 );
while (arr.length > 1) {
arr = arr
.filter((d,i) => (i+1) % 2 === 0)
.filter((d,i) => (i+1) % 2 !== 0);
}
console.log(arr[0]);
Short and sweet. I could run it in my browser.
THOUGHTS ABOUT SOLUTION WITH CODE
There is such a thing as getting the answer without solving the problem. Emulating the described steps as a brute force "solution" in code is an example.
Applying the mathematical result and some programming technique produces code that uses minimal resources in both time and space (without arrays or recursion stack) that are fixed regardless of list length, and can be optimized by replacing floating point calculations with pure fixed point operations. This lends some depth to the programming side of the solution. The brute force step emulation examples regardless of number of lines of code used all negate the value of the problem both as a math exercise and a programming exercise. That is the objection to most if not all of the program code "solutions".
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
1 |
|
Good job. By the way, I think that there is a built in way to do remove indexed..
Log in to reply
There is also a way to make it a single expression. Mathematics.
THOUGHTS ABOUT SOLUTION WITH CODE
There is such a thing as getting the answer without solving the problem. Emulating the described steps as a brute force "solution" in code is an example.
Applying the mathematical result and some programming technique produces code that uses minimal resources in both time and space (without arrays or recursion stack) that are fixed regardless of list length, and can be optimized by replacing floating point calculations with pure fixed point operations. This lends some depth to the programming side of the solution. The brute force step emulation examples regardless of number of lines of code used all negate the value of the problem both as a math exercise and a programming exercise. That is the objection to most if not all of the program code "solutions".
At the beginning, it's clear that every number equals it's position.
After the first step, only even numbers remain, and it can easily be seen that now every number equals twice it's position, satisfying the equation x = 2 n , where x equals the number and n equals the new position.
After the second step, every number in an even position is eliminated. If we write a few of the numbers remaining: 2 , 6 , 1 0 , 1 4 , 1 8 , 2 2 , . . . , we can see they produce an arithmetic sequence with difference(d) 4, and that x ≡ 2 ≡ − 2 ( m o d 4 ) , such that now x = 4 n − 2 , where n is the new position.
If we do the first step (so that this is the third step) again, we'll eliminate numbers in odd positions, and as odd positions occur every two number, and before d = 4, now d will become 8, and the sequence will look like these: 6 , 1 4 , 2 2 , 3 0 , 3 8 , 4 6 , 5 4 , . . . and we can see that now, x = 8 n − 2 . We can continue doing this, and finding a formula for x after each step, and find a pattern in the formulas that will lead us to a generalization:
4^{th} step: 6 , 2 2 , 3 8 , 5 4 , 7 0 , . . . . Formula: x = 1 6 n − 1 0 5^{th} step: 2 2 , 5 4 , 8 6 , 1 1 8 , 1 5 0 , . . . . Formula: x = 3 2 n − 1 0 6^{th} step: 2 2 , 8 6 , 1 5 0 , 2 1 4 , 2 7 8 , . . . Formula: x = 6 4 n − 4 2
Now, I hope it'll be easy to verify, that the general formula is (for s ≥ 2 ): x = 2 s n − ∑ i = 1 ⌊ 2 s ⌋ 2 2 i − 1 , where s equals the step, and n the position.
If someone can find a better general formula, please write it in the comments.
Since the difference in an arithmetic sequence with the remaining numbers (in order) after step s equals 2 s , and 2 1 3 < 1 2 3 4 5 < 2 1 4 , we should check, with the general formula, n = 1 and s = 13 or s = 14. These give respectively 5462 and 5462, because in s = 14 we eliminate numbers in even positions, and 5462, at s = 13 , is in an odd position. If we plug in n = 2, for each of them, we get 13654 and 21846, both bigger than 12345, so we can be sure that the last "survivor" from 1 to 12345 is:
5 4 6 2
Footnote: I know this is far from being a rigorous solution, but actually i'm not very good at writing solutions, so that if I were to try and prove this way of solving the problem, the solution would become large and difficult to read. I will appreciate if you could give me advice on how to write good and clean solutions down here in the comments.
Consider that new position is always CEILING(position/2) and that the last number sitting alone in position 1 has a unique regression back to an even number in its original position on the initial list.
I finally completed my published solution that (at the moment) comes up immediately after this one.
The solution is L(n) = (4^m + 2 ) / 3 where m = FLOOR ( ln(3n-2) / ln(4) )
The accompanying proof is as simple as possible, and sufficiently rigorous, working entirely from the forced regression path from 1 back to 5462, or for that matter a list of any length whatever starting with 1. (It even works with the degenerate case of a list of just one number.)
I hope this solution is the kind of clean solution you were looking for.
Here is mathematical solution to the problem and an implementation in program code.
THOUGHTS ABOUT SOLUTION WITH CODE
There is such a thing as getting the answer without solving the problem. Emulating the described steps as a brute force "solution" in code is an example.
Applying the mathematical result and some programming technique produces code that uses minimal resources in both time and space (without arrays or recursion stack) that are fixed regardless of list length, and can be optimized by replacing floating point calculations with pure fixed point operations. This lends some depth to the programming side of the solution. The brute force step emulation examples regardless of number of lines of code used all negate the value of the problem both as a math exercise and a programming exercise. That is the objection to most if not all of the program code "solutions".
SOLUTION
There is a definite sequence of "last numbers". The solution is the greatest "last number" less than the greatest number on the list.
The last number for any list 1..n is given by:
This can be established as follows:
The key fact is that next position from any given position, p, is N ( p ) = ⌈ 2 p ⌉ (least integer greater than p/2)
The function N ( ) is strictly decreasing until N ( p ) = 1 when N ( 1 ) = 1 . Thus every number not eliminated by parity will eventually reach position 1 when it will be either the last number or be eliminated on the next odd eliminating step. While it is true that N ( 2 k ) = N ( 2 k − 1 ) it is not a problem because either 2 k or 2 k − 1 will have been eliminated on parity, to bring the surviving number uniquely to the new position.
What is of interest here is the inverse of N ( ) which is not a function. N ( ) . Any given position p can only come from one of two prior positions, 2p or 2p-1. The choice of precursor is entirely forced by the type of step, i.e. if the previous step eliminated odd positions, the precursor must be 2p, and if eliminating even positions must be 2p-1.
The last number will be in position 1, the only position remaining. If the current step is odd, then the previous position must have been 1 (not eliminated on an even eliminating step). If the current step is even, then the previous position must have been 2 (not eliminated on an odd eliminating step).
With that logic in hand, the full sequence of last numbers, L m can be generated uniquely starting from 1 on an odd eliminating step.
The difference between successive odd steps increases by a factor of 4 can be seen by examining the value of N ( p ) across successive odd eliminating steps as follows:
The solution to the problem is the greatest L m that is less than the highest position in the initial list (since the last number must be on the list in the first place). We can disregard the intermediate odd numbers in the sequence above because they are all eliminated on the first step.
The sums of powers of 4, can be calculated directly using the formula for geometric sums.
From that a general solution is expressed by
The value of m can be obtained directly as follows.
Taking the base 4 logarithm l o g 4 ( 3 3 n − 2 ) between two consecutive integers, and a change of base, it follows that
With the value of
Which completes the derivation of the function L ( n ) given at the top of the page.
The value marked in red 5462 is the value of L ( 1 2 3 4 5 ) and the solution to the given problem.
In the example given with the problem, we see that L ( 8 ) = 6 , since L 2 = 6 < 8 and L 3 = 22 > 8.
SOFTWARE IMPLEMENTATION
Using the math the resulting code uses fixed resources in both instructions executed and memory used (both minimal without any arrays nor recursion stack ) regardless of the length of the list This is an improvement over the brute force approach that literally performs the elimination step process, both as use of the problem as math exercise and as a programming exercise.
Below is the solution implemented as program code { In Excel VBA for convenience not preference ).
This subroutine implements the solution in the mathematical form derived above
These subroutines implement the solution optimized by the use of right shift pseudo-division to obtain the exponent of 4.
Using a User Form container with a command button.
The code above is executed
Curious how this method starts on the CEILING and ends up on the FLOOR.
My favorite solution so far from a pure math standpoint is the one from Stewart Gordon using base 4, Elegant and without all the mess.
There is a subtle difference between getting the answer and solving the problem.
This is a proof and it produces a direct computation of a solution for a list of any length (even 1) that can be readily incorporated into an efficient computer implementation.
It is not a program that uses the crudest possible brute force procedure (some very explicit, not to say tedious, others elegant near one liners) that increases in effort and memory consumption as n increases without out limit, and might even have a bug, but "hit the jackpot" on this particular case. Slick code, not so slick code, but it is still proof left to the reader.
The solution has now also been implemented in code. Solution first, implementation later.
This particular problem may not be of much inherent importance, but the approach, the rigor, and possibly gaining an improved insight into the underlying mathematics is important.
I thank Ossama Ismail for contributing it. It has been an interesting exercise in applying some mathematics and then using the result as a programming exercise. The more I looked at it the more interesting aspects of it I found The question itself may be inconsequential, but the value of the problem lies in those two things, and not merely getting an answer.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Another python code
a = list(range(1,12346))
b = []
c=[]
while len(a)>1:
i=0
j=0
for n in a:
if j%2==1:
b.append(n)
j+=1
for n in b:
if i%2==0:
c.append(n)
i+=1
a = c
b=[]
c=[]
print(a)
Nice, unlike the other solutions, you have actually spelt out the details.
THOUGHTS ABOUT SOLUTION WITH CODE
There is such a thing as getting the answer without solving the problem. Emulating the described steps as a brute force "solution" in code is an example.
Applying the mathematical result and some programming technique produces code that uses minimal resources in both time and space (without arrays or recursion stack) that are fixed regardless of list length, and can be optimized by replacing floating point calculations with pure fixed point operations. This lends some depth to the programming side of the solution. The brute force step emulation examples regardless of number of lines of code used all negate the value of the problem both as a math exercise and a programming exercise. That is the objection to most if not all of the program code "solutions".
Problem Loading...
Note Loading...
Set Loading...
Binary number approach
Subtract 1 from all numbers and positions, and write them in binary notation. (Thus, 000 is at position 0, 001 at position 1, and so on.)
After the first step, only the numbers ending in 1 survive, and their new position number is obtained by removing the 1. (Thus, 001 at position 0, 011 at position 1, etc.)
After the second step, only the positions ending in 0 survive, which are all numbers ending in 01, and their new position is obtained by removing 01. (Thus, 001 at position 0, 101 at position 1, 1001 at position 2, etc.) After the n th step, the surviving number in position a is a n digits … 0 1 0 1 0 1 .
Since 2 1 3 < 1 2 3 4 5 < 2 1 4 , we can perform 14 steps before we end up with 0 1 0 1 0 1 0 1 0 1 0 1 0 1 2 = 5 4 6 1 1 0 at position 0. Adding back in the 1 we subtracted, the answer is therefore 5 4 6 2 .
By way of generalization, any binary number following the patter x = 1 0 1 0 1 … 1 0 1 2 satisfies the equation 4 x + 1 − x = 4 n ∴ x = 3 4 n − 1 for some integer n . Thus, with n = 6 we obtain x = ( 4 6 − 1 ) / 3 = 1 3 6 5 , and with n = 7 we find x = 5 4 6 1 , etc.
Therefore the general solution to this problem is the largest available number that may be written in the form 3 1 ( 4 n − 1 ) + 1 , or 3 1 ( 4 n + 2 ) .
Alternative approach
Divide the sequence into blocks of four numbers. Thus, block # k consists of the numbers 4 k − 3 , … , 4 k .
Of each block, only the second number survives, i.e. 4 k − 2 .
After steps 1 and 2, the surviving number of the k th original block is now the k th number. Therefore, if a number has position k n after n steps, its position after n − 1 steps must satisfy k n − 1 = 4 k n − 2 . Definition x a : = k n − a , this becomes x a + 1 = 4 x a − 2 .
At the end of the process ( n repetitions) we have one number left, in the first position, i.e. k n = x 0 = 1 . Work backward to find the original position k 0 = x n : a x a 0 1 1 2 2 6 3 2 2 4 8 6 5 3 4 2 6 1 3 6 6 7 5 4 6 2 8 2 1 8 4 6
Since we started with numbers up to 1 2 3 4 5 , the process must end after seven steps at k 0 = k n − 7 = 5 4 6 2 .
Or , to generalize further, we can find an explicit expression for x a . The recursion x a + 1 = 4 x a − 2 clearly describes exponential growth, but we must account for the term − 2 . The trick is to rewrite it as x a + 1 − 3 2 = 4 ( x a − 3 2 ) . The solution of this recursion is x a − 3 2 = ( x 0 − 3 2 ) ⋅ 4 a , or x a = 3 4 a + 2 . Substituting a = 7 gives indeed x 7 = 3 4 7 + 2 = 3 1 6 3 8 4 + 2 = 5 4 6 2 .
In general, if the original series contains the numbers 1 , … , N , then the remaining number is 3 4 ⌊ lo g 4 ( 3 N − 2 ) ⌋ + 2 .