Howto program Hanoi statefree
[from a pattern-based perspective]
We can do a version of Towers of Hanoi with state
We can do a statefree mathemathical solution.
Well it would be convinient with a function
f(
nActual) that would tell us the move
as a function of
nActual
We observe some wellknown facts.
N is the number of rings
n is a counter for the total moves that is (2^
N) -1
nActual = current position in the sequence
0............
nActual..........
n = (2^
N)-1.
We always step 1 step forward and the game's start-position is represented by 0.
As the start position is represented by the number 0.
we let
nActual represent the moves, let it start with 1'st move
and let it continue forward until
nActual
becomes
n = ( 2^
N)-1.
So Lets get to work and look for some patterns.
Look at the image above. Here start with 4 rings. Moves the stack from A -> B.
As nActual starts being 1 and progressively increase with 1 at the time, we observe a pattern of repititious movements
the 2 [x]'s under each colorblock suggests witch 2 poles
that are involved in moving a ring between them.
We observe an ever repeating AC, AB, BC pattern.
But how can you predict the direction of the next move ?.
Notice! The first 4 [from -> to ] movements describes a pattern.
From A->C, A->B, C->B, A->C . But the 5. move B->A breaks it ! Reverse the direction !
So Although there always are 2 colorblocks involved in a fixed pattern AC,AB,BC interactive movement
the direction [from -> to] isn't. So we can't still calculate it! Only observe!.
But the AC, AB, BC between patterns is fixed and will still help us. Even In a very impressive way too!
But for now lets consider numbers to represent nActual.
We know Base10 number system, but lets move down
to examine Base3 since there are 3 poles
Base2 since we move between 2 poles
Base1 to tell us if we get more information the lower the Base is.
But now!.Look at the depiction above. Here we have 4 different base number systems.
The * arragement represent the rings and their current pole-position.
We can see the Base 1 ( tally marks ) describing the rings distribution.
But how does tally marks increase with 1 ? Here They do not !
Well! The way the tally marks are arraged here actualy depicts every position of the game
And it would provide us with the direction. It give us the [from -> to] direction simply by observing the actual tally mark
with the previous. Try it out yourself!
So now, we can conclude that whatever value nActual hold in the range 1 to (2^N)-1
we likely can use as argument to f(nActual) and have f return the move between.
the previous position [ nActual -1 ] and
[ nActual ] itself.
So far so good.
But the way we arrange the tally marks contradicts the intent to investigate for lower complexity with lower base.
Can you see why ?.
It is because the tally marks in this configuration actually ia a Base 16 number.
Base 16 in this tally mark form hold the solution in itself for N = 4.
But not for another N. This way of finding a pattern is quickly
becoming impossible with increasing N
If N were 18 we would have to know a numbersystem with (262.144 -1) different signs reperesenting 1 ... (262.144 - 1).
numbers that all by the way were the solution itself !. Impossible.
In short!, Tally marks or Base 1's number progression miss positional counting and is unsuitable for f(nActual)
Base 10 have a positional forward counting pattern. 001,002,003,...009,010,011,013...100...etc. etc. we all know
But give us not enough translatable information on positions.
Base 3 have- just like base 10 - a progressive positional forward moving pattern 0000,0001,0002,0010,0011 .. etc.
But the 0's in base 3 do not accurately mirror the number of rings on the initial A pole
as Base 2 does.
Base 2 is like the others and goes 000,001,010,011 .. etc.
And indicate positions that possibly can be translated .
the initial 0, 0, 0, 0 would then have to indicate 4 *'s on the A position.
Wait a minute ! The Base 2 leftmost 0's have a pattern of precisely counting the number of rings on A.
That is enough for us to look
further into Base 2.
Here in this arrow diagram we look closer at base 2 movements arranged with C moved to the leftmost position.
The arrows marked with red indicate where the pattern break.
The 2. A->B and 5. B->A have opposite directions and breaks it.
Notice the ODD and EVEN indications?. It is an attempt to see if the number
nActual
in itself hold any info on the direction. It is Possible
Let's elaborate. I look at this from the future where i know a mathematical solution
You would have to construct a pointer to witch arrow to mirror witch size ring is up for movement 1.2.1.3.1.2.1. ..etc.
And althought that actually can be done it adds a layer off complexity.
See sequence A001511 in the
OEIS
We have marked a F for the arrow to be moved. Counting even or uneven amount of either 0 or 1 ABOVE F
That shoud give us the circular movement for the F arrow.
It also breaks in the 5. move!. Remember KISS, keep it simple stupid !.
But remember the observation from the base 1 tally marks established that f(
nActual) will have to look at
[
nActual] compared to the previous [
nActual-1].
So lets move on
and compare those up against eatchother.
Here we see how perfect the binary numbers 0 and 1 count the number of rings
on the default and the destination pole. The
* marked with red in the left A column and right B column.
In the state solution ( see
here ) we already established the
eternal repeating from pattern AAC ? BBA ? CCB ? AAC ? BBA..... etc
notice the ? was named a pivot that has to be to calculated.
It run simultanous with the AC, AB, BC pattern of invovlved poles.
The arrows point to the elements to be compared to decide where to move from and to.
The 3 ? ? ? is known to become
A A C and are marked with red background.
So do they reflect a general pattern?.
That can be testet. Let us compare the 3 ? in
N = 4 with a different
N. .
0 0 2 For
N = 4. If You know programming you can produce the numbers for
N= 6 yourself. Eventually with the c++ program in this
a link to solution in c++
0 0 2 [0] 1 1 0 [0] 2 2 1 [2] 0 0 2 But no worries, here are the numbers For
N = 6.
We see 0 0 2 appear in the beginning and end of, and in the [] between the groups of 3.
We will look closer at this later under the
mathemathical solution.
But first we anotate- with yellow color - the known [ from ] number pattern from the previous image
and search for patterns between [nActual-1] and nActual.
As impossible it has been to extract any useful pattern from anything, it
is now amazing to observe, that not only do this image give us the answers
for the ? in AAC ? BBA ? CCB ? AAC, but in abundance give us the correct from
pattern for all values of [nActual].
When we logic AND all the 1's in opposite posision and use modolus 3. A perfect pattern.
So for now f(nActual)
= (nActual [BitwizeAnd] (nActual-1) ) [Modulus] 3
Give us would give us where to move from for all nActual
So let's move on and see if this amazing strike of luck also stand for ODD N's.
So we look at an ODD amount of rings. 3 rings. And wee add a perspective so it includes both possible moves starting from A
We observe both the game where you move A->C and A->B.
It is not hard to see the A->C move
When we need to calculate the difference of moving between
either A - > C or A -> B
We are helped by looking at the colors in the image above.
We just swap ALL B and C values.
But first we add [ * (1 + N % 2)) ] to adjust for EVEN or ODD N
the same as demanding to factor with 2 for every ODD start condition.
And do nothing when it is EVEN
v handles the swap's of every B and C if a to c [atoc] is set
Now we get 4 lines essential to solve all ODD,EVEN A->B A->C solutions.
Notice & is a bitwise AND . Where as | is a bitwise OR. And && is a logic AND
v = frompole = ((nActual & (nActual - 1)) * (1 + N % 2)) % 3;
if (atoc && frompole > 0)v = (1 + frompole % 2);frompole = v;
v = topole = (((nActual | (nActual - 1) )+1) * (1 + N % 2) ) % 3;
if (atoc && topole > 0)v = (1 + topole % 2);topole = v;
a link to solution in c++