There are two players that alternate playing.

Each player HAS to take A LEAST ONE object up to AS MANY AS they like including ALL objects BUT ONLY FROM ONE OF THE ROWS. Which row this should be is up to the player to decide.

The two players decide in advance who wins and who loses. Either they decide that the player who picks the last object wins or that the player who picks the last object loses.

I will now present an analysis of the game.

I will start by giving an example configuration.

Suppose we have the following 4 rows of objects (coins, paperclips, cards, it doesn’t matter):

object

object object object

object object object object object

object object object object object object object

Let me transform the above to an equivalent representation that depicts the number of objects in each row:

1

3

5

7

Let me transform the above to an equivalent representation that depicts the number of objects in each row in binary number format:

001

011

101

111

We are interested in the 1’s. In the above configuration, the 1’s are balanced.

What does it mean that the 1’s are balanced? It means that each column contains an even number of 1’s.

So, we call this configuration balanced.

Well, the state of the game is completely determined at this point. Completely determined.

Not only is the state of the game completely determined at this point, but it is completely determined at any point, even if we begin with more or less rows and/or more or less objects.

The state of this game is completely determined if we have five rows of 363, 356, 5467, 4674, 254 objects, or six rows of 2, 4, 5, 35, 1000 objects or whatever else we can think of.

I will explain why I am saying this, but first I would like to explain what I mean by completely determined. I mean that both players know the ultimate winning strategy and no player plays in a naive manner.

If these conditions are met, the state of the game is completely determined before it even begins, if we are given the following:

1) The number of rows and how many objects each row has (the whole configuration).

2) Who is going to play first and who is going to play second.

3) Who wins: the player that takes the last card or the player who does not.

Given the above, the state of the game is always predetermined. (Actually, as we will see, number 3 is irrelevant. The first two conditions fully determine the outcome of the game.)

Given conditions 1 and 2, the state of the game is always predetermined and this is because a configuration can always be transformed to an equivalent representation that depicts the number of objects in each row in binary number format.

And from that representation we can find if the configuration is balanced or unbalanced.

If a player has a balanced configuration in front of her and she has to play, she will create an unbalanced configuation. Always. Even if she wants to or not.

If a player has a unbalanced configuration in front of her and she has to play AND SHE KNOWS THE ULTIMATE WINNING STRATEGY, she will create a balanced configuration if she wants to. Always. If she wants to.

So, between two players that know the ultimate winning strategy, the game will be predetermined.

So, who will win? I will tell you who will lose. The player that first is in front of a balanced configuration and is her turn to play, she will definetely lose.

So, if we begin with an unbalanced configuration, the first player will choose to create a balanced configuration. So the second player will have in front of her a balanced configuration, thus she will definitely lose. I will explain why later on.

And if we begin with a balanced configuration, the first player will definitely lose. For the same reason as before, which I will explain later on.

Before I give you an example of the ultimate winning strategy, I would like to give you an example of unbalancing and balancing.

Suppose we are at the beginning:

1 001

3 011

5 101

7 111

The above is balanced, because each column has an even number of 1’s.

Player1 will have to play because she is the first player.

No mattter what she does, she will leave an unbalanced configuation for Player2.

Suppose Player1 takes the whole last row. Player2 is left with an unbalanced configuration:

1 001

3 011

5 101

Wow! This is hugely unbalanced. All three columns have an odd number of 1’s. This is as unbalanced as it can be!

Player2 can, if she wants to, go back to a balanced configuaration. How? Here is how: She can take 3 objects from the last row, thus creating the following balanced configuration:

1 001

3 011

2 010

Ok, now let us see who wins and who loses.

I will consider the configuration given at the start of this analysis.

I assume that both players are knowledgeable and do not play in a naive manner.

The state of the game is always and completely determined when it is the turn of a player to play and this player is in front of a balanced configuration.

When a player is in front of a balanced configuration and it is her turn to play, then she will definitely lose the game. Definitely. Always. Assuming of course that the other player is knowledgeable. So she will always lose the game, even if she is knowledgeable, too.

When a player is in front of a balanced configuration and it is her turn to play, the fate of the game is completely determined and she will definitely lose, always, no matter if the player who takes the last object wins or loses. No matter what was decided beforehand, concerning who wins and who loses, the player that comes in front of balanced configuration and its her turn to play, will always lose.

Let me say this one more time: It does not matter if it was decided that the player who takes the last object wins or that the player that takes the last object loses. Either way, if a player is in front of a balanced configuration and it is her turn to play, she will always lose the game.

Crazy, huh? Crazy, but correct. Let me explain why the above statements are correct.

I will study the two cases individually. The first case concerns the games where the player that takes the last object wins. The second case concerns the games where the player that takes the last object loses.

But before I do that, I have to stress the following points:

When a player is in front of a balanced configuration, and it is her turn to play, she will definitely create an unbalanced configuration. There is no other way, no matter how knowledgeable she is.

The mathematical reason for this is because she draws from only one line. Thus, something that was even among all lines, will stop being even.

When a player is in front of an unbalanced configuration, she has a choice. She can make the configuration balanced if she wants to, or she can produce a configuration that remains unbalanced.

Thus, when a player is in front of a balanced configuration, she is forced to make it unbalanced. But when a player is in front of an unbalanced configuration she has a choice of whether to balance it or to make it to remain unbalanced.

To be completely without choice when a player is in front of a balanced configuration is what creates the advantage for the other player. The other player can, with mathematical precision, literaly, win.

OK. Let me study the first case, the easy case, where the player that takes the last object wins.

This is the easy case.

So, the first player is front of a balanced configuration. From this, I know that the first player will definitely lose. Let us see why.

The first player will play and will make the configuration unbalanced. There is no other way. Even if she wants to, event is she does not want to, there is no other way for the first player but to leave the configuration unbalanced.

Then the second player will play and she will choose to balance the configuration.

Then the first player will play and she will make the configuration unbalanced again. Whether she wants to or not.

Then the second player will choose to balance the configuration, again.

And so on, until we reach the end of the game and the second player takes the last object, thus making the configuration balanced (zero objects is balanced, since zero is an even number).

So the first player is pushed around and guided unwillingly to the end of the game by the second player.

OK, the same thing happens with the second case. In the second case, too, the first player is pushed around and guided unwillingly to the end of the game by the second player.

But the analysis is way trickier in the second case.

OK. Let me study the second case, which is the case where the player that takes the last object loses.

So, the first player is front of a balanced configuration. From this, I know that the first player will definitely lose. Let us see why.

The first player will play and will make the configuration unbalanced. There is no other way.

Then the second player will play and she will choose to balance the configuration.

And so on, until we reach a very specific point in the game, where the second player will choose to reverse her strategy and leave the configuration unbalanced.

The reason why the second player will need to reverse her strategy should be obvious. If she doesn’t, we have the first case where she will end up taking the last object.

So, at a point in the game, the second player will need to reverse her strategy and leave the configuration unbalanced.

But this point in the game is very specific.

The second player must not choose to reverse her strategy at any point. No. In order to win, the second player must reverse her strategy, but at a very specific point and in a very specific way.

Which is this point and why?

Well, this point is the point where all remaining lines have only one object, with the exception of only one line which can have more than one object.

And why this is so? This is because only from this point onwards, the unbalanced configuration cannot be left unbalanced a second time by the first player.

If the second player would choose to leave the configuration unblanaced at a premature point, then the first player would balance it, bringing the second player at a disadvantage.

But if the second player leaves the configuration unbalanced at the specific point that I am talking about, from then on the configuration has to alternate between balanced and unbalanced.

Let me analyze this very subtle point: I described how from balanced we always go to unbalanced, but from unbalanced we go to balanced if we want to.

Well, yes, this is so, but from this specific point in the game onwards, from balanced we always go to unbalanced AND from unbalanced we always go to balanced.

So, from this specific point in the game onwards, if the second player reverses her strategy and leaves the configuration unbalanced, the first player cannot continue this trend but is instead forced to provide a balanced configuration.

Which the second player will make unbalanced and at last, the first player will make balanced by taking the last object, thus losing.

Do not be fooled that this very specific point (where the second player changes her strategy) is somewhere in the middle of the game. No. This specific point is at the very end of the game.

So, let us study this specific point.

As I said, this specific point is when all remaining lines (except one) contain only one object.

From this point onwards, from balanced we always go to unbalanced AND from unbalanced we always go to balanced.

And this is the point where the second player must reverse her strategy and leave the configuration unbalanced, for the first player to balance it (the first player has no other choice, whereas usually she would have a choice to let it remain unbalanced). And so on. From there we can only alternate between balanced and unbalanced, but not for long. We are already at the end of the game.

An example of this point is the following, The second player has to play to the following unbalanced configuration:

object

object

object

object object object

The second player will produce the following configuration, which remains unbalanced, and since it remains unbalanced, this is the change in her strategy that we were talking about:

object

object

object

From then on, it is the first player’s turn and the game is certainly in favor of the second player, as it was all along.

Another example of the point to change the strategy is the following:

object

object

object object object

Here, the second player will choose to produce the following configuration which remains unbalanced, and since it remains unbalanced, this is the change in her strategy that we were talking about:

object

object

object

Let me give you another example of this point where the second player has to change her strategy. We already said that this point is where all but one line have only one object.

So, let us suppose that the second player has in front of her the following configuration and is her turn to play:

object

object object

object object

We are near the end of the game. What must she do? She must change her strategy, yes? No, no yet. Remember, we said that the point where she needs to change her strategy is when only one line has more than one object. Here, two lines have more than one object.

So, she will need to continue with her initial strategy some more. So, she will still choose to balance the configuration:

object object

object object

Now, the first player will play, and unbalance the configuration.

Let us suppose that the first player produces the following unblanced configuration:

object

object object

Now this is the point where the second player will reverse her strategy and provide an unbalanced (instead of a balanced) configuration:

object

And the first player will play and take the last object, thus losing.

So, the second player had to change her strategy at the very end.

And this concludes my analysis.

The result of this analysis is that whenever a player has in front of her a balanced configuration, the other player has total control of the game from this point onwards and until the completion of the game.

So, this is a pointless game, just like tic-tac-toe.

In tic-tac-toe, if BOTH players know the ultimate playing strategy, the game will always end in a draw.

In NIM, if BOTH players know the ultimate winning strategy, the game will always end in favor not for the player that first comes in front of a balanced configuration to play, but in favor of the other player.

So, this game is pointless. But there is a way that this gane can be “saved” from being pointless. We can add chance to it, by using a dice, and one may, for example, take the number of objects denoted by the number which she rolls.

OK, so I have described how the game works and what the ultimate winning strategy is, but why does it work this way? Why do we need to use binary representations? (Equivalently we could have also used powers of two, and mentally consider the objects in groups of 1, 2, 4, 8, 16, 32, and so on, in each row, it is the same thing.) So, why do we need to transcend to the binary realm or to the powers of two to generate and use the ultimate winning strategy?

This is because we have 2 players. We have 2 players and they alternate playing. Player1 plays, then player2, then player1, then player2 and so on. One time we go from a balanced to an unbalanced configuration and the next time we may go from an unbalanced to a balanced configuration, if the current player wants to.

This means that we need to mind the binary representation’s 1’s as pairs. When a player plays, at least one of these 1’s is destroyed. The other player then has to aknowledge this fact and play accordingly.

And the ultimate winning strategy of the game is that since 2 players play, they need to consider these 1’s as pairs in each column for the configuration to be balanced.

]]>The purpose of the puzzle is to decode a number sequence in order to find the underlying word.

Let me explain.

First of all, this puzzle is meant to be case insensitive.

We begin with the most obvious correspondence: the 26 letters of the alphabet and the numbers from 01 to 26. So, the letter A corresponds to the number 01, the letter B corresponds to the number 02, and so on up until the letter Z which corresponds to the number 26.

Now we choose a word, whatever word we want. It would be best if it is a word with many letters. Why this is so, will become apparent later.

Then we substitute each letter of the original word with its corresponding number.

If we stop here, then it would be the easiest task in the world to decode the word from the number sequence.

But we do not.

What we do next is to change each number, advancing its value in a cyclical way. The change is as much as the value of the previous number in the sequence. And the first letter of the word, well, we change that according to the value of the last number. This is depicted in the following image.

What does advancing in a cyclical way means? It means that if we have the number 24, then advancing it by 01 will give us the number 25. Advancing it by 02 will give us the number 26. Advancing it by 03 will give us the number 01. Advancing it by 4 will give us the number 02. And so on. We go from 01 up to 26 and then we wrap back and continue from 01 onwards again.

Let me give you an example.

First of all, it will help if I write down the correspondence between letters and numbers.

01 A

02 B

03 C

04 D

05 E

06 F

07 G

08 H

09 I

10 J

11 K

12 L

13 M

14 N

15 O

16 P

17 Q

18 R

19 S

20 T

21 U

22 V

23 W

24 X

25 Y

26 Z

Suppose we want to code the word “JUSTICE”.

We begin with the letter sequence:

J U S T I C E

Then we create the initial number sequence:

10 21 19 20 09 03 05

This is easy to do. The letter J corresponds to 10, the letter U corresponds to 21, and so on.

Now we begin the difficult part. We will change the value of each number according to the number that precedes it. And for the first number, we will change its value according to the last number.

Let’s begin.

It is important to keep the initial number sequence intact and create a new one to be the result of our operations.

So let us begin by changing the second number.

The second number is 21. The number that precedes it is 10. So we will advance 21 by 10. Normally, this would give us 31. But we will not perform a regular addition. We will perform a circular addition where we wrap at 26. Thus 21 will become 05. So we will substitute 21 with 05.

The third number is 19. The number that precedes it is 21. So we will advance 19 by 21. Normally, this would give us 40. But since we are doing a circular advancement, 19 will become 14. So we will substitute 19 with 14.

The fourth number is 20. The number that precedes it is 19. So we will advance 20 by 19. Normally, this would give us 39. But since we are doing a circular advancement, 20 will become 13. So we will substitute 20 with 13.

The fifth number is 09. The number that precedes it is 20. So we will advance 09 by 20. Normally, this would give us 29. But since we are doing a circular advancement, 09 will become 03. So we will substitute 09 with 03.

The sixth number is 03. The number that precedes it is 09. So we will advance 03 by 09. Normally, this would give us 12. And since 12 is less than or equal to 26, we will accept this result as is. So we will substitute 03 with 12.

The seventh and final number is 05. The number that precedes it is 03. So we will advance 05 by 03. Normally, this would give us 08. And since 08 is less than or equal to 26, we will accept this result as is. So we will substitute 05 with 08.

Now let us change the first number. There is no number that precedes it, but we do everything circularly here, so we might as well continue in this path. We will use the value of the last number to advance the first number. So the first number is 10. And the last number is 05. So we will advance 10 by 05. Normally, this would give us 15. And since 15 is less than or equal to 26, we will accept this result as is. So we will substitute 10 with 15.

Please note that we could have done any of these operations in any order. We need to keep the initial number sequence intact. Then we can substitute each number with its advancement in any order. In the example above, I calculated the substitution of the first letter as the final operation, but I could have done it in the beginning or at any other time.

So let us see the final number sequence that we created:

15 05 14 13 03 12 08

Let us see the corresponding word:

O E N M C L H

So, if we give this word (that we calculated as our result) to someone, could they decode it? Could they derive the original word it came from, if the algorithm that we used is known to them?

It is important to keep the algorithm public and everyone should know the algorithm, meaning the procedure we used to derive the result word.

So, can someone derive the original word from the coded word? If someone knows our algorithm, and we give them the word OENMCLH, can they find out that the word it came from is JUSTICE?

Well, the result word does not resemble the original one, except for the fact that in this puzzle the initial word and the final word will always have the same number of letters. But even if the result word looks completely scrambled, we can reconstruct the original word it came from as follows:

We take the result word and we substitute the corresponding numbers.

So from

O E N M C L H

we come to

15 05 14 13 03 12 08

This is straightforward.

Next we can begin with any number and move in a cycle. So we might as well begin the first number.

The first number is 15. We know that we arrived at this number by augmenting the number that was there initially, using the last number in the sequence which is now 08. Yes, the last number is now 08, but we do not know what it was when we used it to augment the first number.

No number in this sequence is the original number that existed in the initial sequence. All numbers have been changed.

So what are we to do?

What we can do is suppose that the first number was originally 01. And see where this takes us.

Next we will suppose that the first number was originally 02. And see where this takes us.

And so on, until we check for all 26 possibilities for the first number.

Each time we suppose that the first number was something (from 01 to 26), we will come up with a number sequence. Then we will gather the 26 resulting number sequences and see which one corresponds to a valid word. The 25 other number sequences will be discarded. But it gets easier. Most, if not all, of the 25 number sequences, will not even be completed, since there will be an inconsistency when we wrap around the final to the first letter. So, most if not all of the 25 number sequences will be completely invalid. This is not because they will result in a meaningless bunch of letters, but because they will not result in a valid sequence that wraps validly around itself. This is because by supposing that the first letter was something, we will finally end up calculating the last letter, but when we derive this last letter, it should produce the assumption we made for the first letter. Usually, the only case that this will happen is when our original assumption for the first letter was correct.

Anyway, what we should do is assume each of the 26 possible numbers for the first number and calculate the original sequence that corresponds to this assumption. If we are able to finish the calculation and get a valid result, this is a strong hint that this result may correspond to the word we are looking for.

In the end, we will collect all the valid resulting sequences (theoretically their number will be from 1 to 16, but usually there will only be 1) and see to what words they correspond. The word we are looking for should be straightforward to find.

OK, let us see how we will proceed to find the original number sequence from the final number sequence

15 05 14 13 03 12 08

We will have to make 26 assumptions and then the calculations that correspond to each one of these assumptions.

So we will first assume that the original first number was 01.

So the corresponding calculated assumed original initial sequence is

01 …

If the original first number was 01 and now it is 15, this means that it was shifted by 14. So this means that the last letter was originally 14. We will keep that in mind. When we arrive at the end of our resulting original sequence and the last number is 14, this sequence will be a strong candidate for our final check. If not, this means that this sequence is definitely invalid, the assumption that the original first number was 01 is definitely invalid and we can safely discard this assumption and this resulting initial sequence.

By assuming that the first number was originally 01, we can deduce that the second letter was originally 04. This is because it is now 05 and its preceding letter was 01, so from 04 it was shifted to 05.

So the corresponding calculated assumed original initial sequence is

01 04 …

Now that we found the second number, we can find the third number. The third number is now 14, but since its preceding number was 04, then it means that it was originally 10 and it was shifted by 04 to become 14.

So the corresponding calculated assumed original initial sequence is

01 04 10 …

Now that we found the third number, we can find the fourth number. The fourth number is now 13, but since its preceding number was 10, then it means that it was originally 03 and it was shifted by 10 to become 13.

So the corresponding calculated assumed original initial sequence is

01 04 10 03 …

Now that we found the fourth number, we can find the fifth number. The fifth number is now 03, but since its preceding number was 03, then it means that it was originally 03 and it was shifted by 26 to become 03. In this circular addition, there is no zero as a number. We do not have any zeros. But if we add 26 to a number, we get the original number.

So the corresponding calculated assumed original initial sequence is

01 04 10 03 26 …

Now that we found the fifth number, we can find the sixth number. The sixth number is now 12, but since its preceding number was 26, then it means that it was originally 12 and it was shifted by 26 to become 12. I repeat from the previous paragraph: In this circular addition, there is no zero as a number. We do not have any zeros. But if we add 26 to a number, we get the original number.

So the corresponding calculated assumed original initial sequence is

01 04 10 03 26 12 …

Now that we found the sixth number, we can find the seventh number. The seventh number is now 08, but since its preceding number was 12, then it means that it was originally 22 and it was shifted by 12 to become 08. I repeat from the previous paragraph: In this circular addition, there is no zero as a number. We do not have any zeros. But if we add 26 to a number, we get the original number.

So the corresponding calculated assumed original initial sequence is

01 04 10 03 26 12 22

We finished, but… we found that the last number of the original sequence is 22. And we assumed that the first number was 01. Thus, in the final sequence it would have been shifted by 22 to become 23. But in the final sequence we have at hand, the first number is 15. Thus we arrived at an invalid resulting initial sequence. Thus, we can safely assume that 01 was not the first letter of the original initial sequence.

We can then assume that the first number of the original initial sequence was 02 and do all the calculations. And so on. Each time, we will keep the resulting initial sequence if it is valid, I,e, if the last number calculated validates the assumption of the first letter. And we will see which of the valid resulting initial sequences correspond to a legitimate word. But, usually, there will only be one valid resulting initial sequence.

So let us do the calculations for the correct assumption, to see how this goes.

The initial word was

J U S T I C E

and the initial number sequence was

10 21 19 20 09 03 05

But the solver does know that. All the solver knows is the final number sequence

15 05 14 13 03 12 08

Now let us suppose that the solver has tried all possible cases up from 01 up to 09 for the first number of the original sequence and now the solver is about to try the case for the first number of the original sequence being 10. We know that this is the correct assumption, but the solver does not. Let us see how this goes for the solver.

So the solver assumes that the original first number was 10.

So the corresponding calculated assumed original initial sequence is

10 …

The second number in the final sequence is 05. This means that the second number of the initial sequence was 21. This is because 10+21=05 in our circular addition.

So the corresponding calculated assumed original initial sequence is

10 21 …

The third number in the final sequence is 14. This means that the third number of the initial sequence was 19. This is because 21+19=14 in our circular addition.

So the corresponding calculated assumed original initial sequence is

10 21 19 …

The fourth number in the final sequence is 13. This means that the fourth number of the initial sequence was 20. This is because 19+20=13 in our circular addition.

So the corresponding calculated assumed original initial sequence is

10 21 19 20 …

The fifth number in the final sequence is 03. This means that the fifth number of the initial sequence was 09. This is because 20+09=03 in our circular addition.

So the corresponding calculated assumed original initial sequence is

10 21 19 20 09 …

The sixth number in the final sequence is 12. This means that the fifth number of the initial sequence was 03. This is because 09+03=12 in our circular addition.

So the corresponding calculated assumed original initial sequence is

10 21 19 20 09 03 …

The seventh number in the final sequence is 08. This means that the fifth number of the initial sequence was 05. This is because 03+05=08 in our circular addition.

So the corresponding calculated assumed original initial sequence is

10 21 19 20 09 03 05

And we finished. Now we must check the validity of the sequence. The last number produced is 05 and the first number is 10. Does 10+05 produce the first number of the final sequence? Yes, it does. 10+05=15, which is the first number of the final sequence.

Thus, the sequence we produced with the assumption that the first number is 10 is a strong valid candidate. And chances are slim to none that another valid sequence will emerge. But I suggest that the solver tries all 26 assumptions for the first letter of the initial sequence just in case.

So the corresponding calculated assumed original initial sequence is

10 21 19 20 09 03 05

And if we substitute the letters, we get the original initial word

J U S T I C E

Now this game can be played by choosing a word, encoding it using the circular algorithm I described and letting the solver deduce the way to decode the word. The solver should be able to deduce that she needs to try 26 possible assumptions for any letter position she chooses and move circularly calculating the resulting sequences. Of course, the solver can make the initial assumptions not for the first number but for any number in the sequence that she chooses. But there is no benefit or loss in what position she chooses to make the initial assumptions. But the solver has to deduce that she will have to make 26 assumptions and then perform the corresponding calculations for each assumption.

The word to be decoded should be long, in order to avoid letting the solver do the calculations by hand. This puzzle is meant to train aspiring cryptographers, so it would be best if it is designed such that it would persuade them to use a computer and create a program to do the calculations.

A student may create a program that decodes such a puzzle word and also a program that encodes (creates) such a puzzle word. And students can play against each other. One student can encode a word and the others could try and decode it.

Also, this puzzle can be made more difficult. For example, the symbols may be increased. As is, this puzzle deals with 26 symbols, the uppercase letters of the alphabet. Of course, a space, other symbols, the lowercase letters, numbers, etc. may be added. If we add, say, only a space, so the students can create an elementary sentence (just a space, no point, comma, etc) then the number symbols will be 27 and the addition will need to wrap at 27.

The difficulty of the puzzle can also be increased by circularly adding the previous, say, two letters to the current letter. And, in such a case, for the first letter, we would add the last and second before last letters. (Remember, we do things circularly here; not only the addition is circular, but also the way each letter is produced from the previous one – or more). So, if we choose to add the previous two letters to the current letter in order to shift it, we would have to make 26 *26 = 676 assumptions. So, to solve the puzzle we would need to calculate each assumption: each permutation of the first two letters, assuming we choose to work from the beginning of the number sequence. (Because, again, I am stressing that we can choose to begin to work from any number position in the sequence. And we can choose to proceed from left to right or from right to left.) Anyway, in such a case, we would assume that the first and second numbers in the initial sequence were 01 and 01. And we would find the third number, based on the third number of the final number sequence. And based on that, we would find the fourth number and so on until we calculated the whole sequence. And then we will try the assumption of the first number being 01 and the second number being 02. And so on, until we try all 676 assumptions.

So how may this puzzle appear? How can we pose the question to solve the puzzle? Here is an example:

**A word is encoded using the following algorithm. Each letter corresponds to a 2-digit number. The letter A corresponds to 01, the letter B to 02, all the way to the letter Z which corresponds to 26. By substituting each letter with its corresponding 2-digit number, an initial number sequence is produced.**

**Then, this initial number sequence is transformed as follows to produce a final number sequence. We take each 2-digit number and we add the previous (position-wise) 2-digit number. The resulting 2-digit number will be used in its place in the resulting number sequence. As far as the first 2-digit number is concerned, we will add the last 2-digit number to it to produce the first 2-digit number of the resulting number sequence. This concept is depicted in the accompanying image, where a six letter word is encoded.**

**In order for the resulting 2-digit number to always be from 01 to 26, we always perform a circular addition (instead of a normal one), where we wrap our results at 26. Thus, a few examples of this circular addition are 01+01=02, 01+25=26, 01+26=01, 10+22=06, 26+26=26, etc. So, 00 does not exist and adding with 26 equals the number that is added to 26.**

**Finally, in the resulting number sequence each 2-digit number is substituted with its corresponding letter. Given this resulting word, your task is to decode it, thus finding the original word.**

**So, given the following word, what was the original word that was used to produce it?**

**R X W W S R M Y Y C S**

And this is the mentality that science teaches us to have.

Richard Feynman said “Religion is a culture of faith. Science is a culture of doubt”. This means that in science, we welcome the doubters. Actually, we favor the doubters. Whenever something comes up from a person/scientist/whatever, the person invites universities, labs and everyone around the world to look into her findings and try to duplicate her experiment or validate her thinking to see if she was right. This is how science works.

So, if someone says to me that the Earth is flat or round, I should say, let me reproduce your claim. I should not say “all right”. I should say “fine, let me verify it.” This is how we teach Physics. We put students in the Lab. We do not say things to them and hope they remember them. We put them in the Lab. We give them microscopes, telescopes, timers, paper and blackboards to do calculations. All these in order for them to verify or dismiss theories.

So, if someone says to me the Earth is round and I take it for granted, then I am not a good scientist.

And if someone says to me the Earth is flat and I take it for granted, then I am not a good scientist.

Also, and this is very important, if someone says to me the Earth is flat and I laugh at her, then I am not a good scientist either. Good scientists do not mock others. Good scientists present their findings. Good scientists educate and inform others.

Mainstream scientists ask: “How can there be people who believe the Earth is flat after all the findings we present, like photo’s from outer space of the moon landing?”

Good question. I am not laughing at these mainstream scientists and I am not mocking them, even though I know the answer to their question.

The answer is that they have to be careful to understand what the flat-Earth-conspiracy-theorists are really saying.

What the flat-Earth-conspiracy-theorists are saying is: “Forget all the findings you presented. Forget them. I do not believe them. All these findings are conspiracy theories made exactly in order to fool us and to make us believe that the Earth is round.”

Mainstream scientists may ask: “Why would someone fabricate such a lie? Why would someone conspire to persuade others that the Earth is round?”

To the last question, the flat-Earth-conspiracy-theorists might provide very interesting and/or irrefutable answers, but our discussion is not about if and why they might be correct or incorrect in their suspicions.

Our discussion does not concern whether there is a conspiracy or not and why they would believe such a thing. Our discussion is not whether they are correct or incorrect that a conspiracy exists.

Our discussion has to do with what these people are saying. And these people are saying that the Earth is flat.

But mainstream scientists have to understand that the flat-Earth-conspiracy-theorists are basing their claim by disregarding all the facts that mainstream science presents as facts. And by doing this, they act as any real scientist would act.

So, I and anyone in the scientific community should welcome these people. Because they are not doing anything that science forbids us to do. Instead they are doing what science welcomes us to do: doubt.

So, these people doubt what we present as fact. And they say: “Forget about what they taught you. If you were to forget everything you were taught and start your reasoning from scratch, what would be your claims?”

So these people argue that if we observe and reason, we will come to the conclusion that the Earth is flat. But if we watch the news or get information from others, we will come to the conclusion that the Earth is round.

I know many of their arguments and observations and reasoning. And I know many of the arguments and observations and reasoning of mainstream science.

And I will tell you my opinion: the Earth is round, but it is extremely difficult, even for a Physicist, to prove it, when they are up against an informed and well educated flat-Earth-conspiracy-theory-supporter. (For example, one cannot say “here is photo from outer space”, because they will tell you that you did not personally take it, so it may as well be fabricated.)

Which makes these people worthy adversaries, people who deserve our respect and honor and whose claims are extremely difficult to falsify. But it can be done, flat-Earth-conspiracy-theory-supporters can be proven incorrect, and this is one of the reasons why we need to educate ourselves as much as possible in science.

In “The Art of War”, Sun Tzu writes about the mistake of underestimating your opponent.

I, for one, do not underestimate the flat-Earth-conspiracy-theory-supporters. Quite the opposite. But there are indeed some mainstream scientists that underestimate the flat-Earth-conspiracy-theory-supporters. I do not think highly of these mainstream scientists.

]]>Say you want to create a full screen popup when you click at a particular web page element, or at any other event you wish. And you wish for the popup to appear and to cover the browser’s full client area. And you also wish for the popup to disappear when you click anywhere on it.

Fear no more, your old pal Dimitrios (Actually, were we ever pals? Really, I mean, have I even met you?) is here to help you.

I will show you how to create a full screen overlay in JavaScript and I will give you the full html code for the whole html page. And I will show you how to do it by including support of the browser’s resize event. And I will show you how to do it using two methods.

The first method will be by dynamically creating a div. The second method will be by dynamically creating a canvas. The dynamic div or canvas will have some text and an image displayed on them, to enhancd the educational value of this post and to better showcase the value of these methods.

But which of these two methods should you use? Well, it depends. If you want to include html elements in the popup, then you should definitely use the dynamic div. This is because the hmtl canvas cannot display html elements. You have to draw everything yourself. You have to reinvent the wheel, so to speak. But if you do want to draw everything yourself, then you may use the dynamic canvas method.

Here are both methods, in all their glory, again, by your friend (Honestly, have we ever even just met?) Dimitrios:

Creation of a fully dynamic full screen overlay using an html div element

Creation of a fully dynamic full screen overlay using an html canvas element

Actually, when I began creating these methods, I would use a naive implementation where I did not account for the browser’s resize event. So I had all the code in one function. Thankfully, the implementations I gave above, account for the browser’s resize and scroll events.

I would also use an empty static element (div or canvas) with zero width. But the browsers would account for it ever so slighlty, even if it was empty and of zero length. This had as consequence that the underlying page would be slightly different when the popup disappeared than it was before its apperance. So, I decided to make everything completely dynamic. And, this way, I achieved perfect results.

Another point I would like to draw attention to is the use of “return false;” in the click event in the undelying page. At first I did not include “return false;” and I could not get the popup to appear for more than what it seemed to me like a millisecond or so. Thus, without the “return false;” the popup would appear and disappear immediately. It would not stay at its place and it certainly would not wait for you to click in order for it to disappear. After a lot of thought, I realized that it was because I was directed to a new page (the same underlying page, that was actually reloaded) and to stop this from happening I had to include “return false;” to stop the redirection from happening. “return false;” lets us stay in the same page and it does not reload the page.

The last point I would like to make is for you to notice that I use canvas.width and canvas.height, whereas I use div.style.* and canvas.style.* for everything else, where “*” in this sentence means “any attribute”. But canvas.style.width and canvas.style.height are invalid ways to address these attributes (the width and the height of the canvas). At first, I made this mistake and, again, the canvas would disappear immediately. This time, it was not because the page was reloading, like it happened with the click event. This time, the script would encounter this error and would stop executing.

So, there you have it. I hope we are friends now!

]]>Visual Studio is very demanding when it comes to resources like CPU, Memory, Hard Disk, Operating System version. You need to have the best and latest hardware and Windows version. I cannot keep up. I can never keep up. And even if I could, I feel that using such an IDE deprives me of functioning as a programmer. Whereas Notepad is the exact opposite.

I know it may sound crazy, but here is how I see it:

When AIDS first reared its ugly head, the news started advising everyone to use a condom during sex. All over the news and anyone you would talk to, would advise you to use a condom during sex. Of course, this is excellent advice that saves lifes.

At one point, CNN showed a discussion about this very matter. An expert was advising a group of men to use condoms during sex. At one point, one of the men said the following:

“We feel we are not functioning as men, if there is something in between.”

This is why I love CNN. They are the only ones that always show both sides of an argument. No one else had ever or ever again raised an argument against protection during sex.

Although I would urge everyone to use protection during sex, I will paraphrase the words of that man. And I will say:

I feel I am not functioning as a programmer if there is something (like an IDE) in between.

I want to have control over the code I write.

To me, my idea of programming is using Notepad.

To me, my idea of programming is to take a binary editor and construct the executable byte by byte.

Actually, I want to make choosing the programming language and the IDE one uses a human right.

Of course, a company would be correct to insist that all employees use a particular programming language and IDE or a particular set of them. But an individual should always have to right to resign because she feels she would like to use another programming language or IDE.

Again, the choice of programming language and way of programming should be a human right.

]]>Although this is the way kids should learn how to program, the doodle is incredibly difficult and should address only seasoned programmers.

The way kids should learn how to program is exactly like that, though. You can create a floor with square tiles and stand in one. Then let the kids give you orders to guide you where they want you to go.

But Google should have never produced such a difficult puzzle meant for kids programming. This puzzle should have been addressed to adults.

**Anyway, here are the questions:**

Question 1:

Question 2:

Question 3:

Question 4:

Question 5:

Question 6:

**And here are the answers:**

Answer 1:

Answer 2:

Answer 3:

Answer 4:

Answer 5:

Answer 6:

**Note:**

By the way, the answer for question 5 can also be used to solve question 4.

**Additional information:**

Obviously, the goal is for the bunny to eat all the carrots.

The puzzle does not make it clear what considers as optimal solutions. From the image below, we can understand that optimal solutions are those which use the least amount of components. The number in each question denotes the minimum mumber of components needed to solve it.

Of course, since question number 4 can also be solved using the solution from question 5, one could argue that question 4 should have the number 6 (instead of 7) for denoting the components needed. But using the solution from question 5 to solve question 4 is far fetched, so I believe that denoting 7 as the compenent number for question 4 is better as it stands.

It is interesting to see what the optimal solution for question 6 is, if we consider as optimal solutions not those with the least number of components but those with the least number of bunny steps.

Then the answer to question 6 could be the following:

– – ) [ – ) – ( – ) – ]

where – means move one step, ) means turn clockwise, ( means turn counter-clockwise, and [ ] means repeat 4 times what is inside the square brackets. I depict this answer below, using two images, since it does not fit in one.

**Final note:**

Of course, the algorithms that the puzzle expects as optimal are unacceptable to me. If I would see someone creating these algorithms, I would tell them that they are far from safe.

You should be able to look at an algorithm and immediatelly deduce its validity, correctness, function, purpose, etc. You should be able to look at an algorithm and immediately understand what its results will be.

Programming is not about which programmer is more clever than the other. It is not an exercise in obfuscation. It is, or it should be, an exercise in clarity.

]]>You write the code online and that’s it! The deployment is instantaneous!

And yes, you can also use Express (the famous Node.js web application framework).

In the free tier, your code is public, so you can use this tier for open source projects and as a learning tool.

With Glitch.com, you do not have to install Node.js on your computer to serve a Node.js application. You only need your web browser to go to Glitch.com, write code and view the results.

Glitch.com‘s landing page has a lot of great ideas and examples for Node.js applications you can create and host on Glitch.com.

Glitch.com pricing is at the following link: https://glitch.com/forplatforms/.

A great article that uses Glitch.com to host and run the article’s featured code is the following: How to set up a database if you’re a front-end developer.

]]>We, humans, are designed to be racist. I do not like this, though, and this is one of the reasons that made me reach the conclusion that the human kind should not exist anymore. I do not think racism, discrimination, differentiation are just or moral. I want all people to be equal. All people are different, but that should not stop them from being equal.

I find it absurd to judge someone based on their skin color, sexual orientation, beauty, health, age, and so on.

But, as I previously wrote, we are designed to be racist. That is how we evolve. Again, I do not like it. But our designer is to blame, not us. What a bad, unjust, racist creation did she make: us. Yes, we should vanish from the face of the Universe.

I walk on the street and I see cafés. This is what I ALWAYS observe concerning cafés: If a woman is young and/or beautiful, she will be a waitress. If she is old and/or ugly, she will be a cleaning lady. ALWAYS. Let me make a mental experiment: Suppose I go to a café owner and confront her about this discrimination. Do you know what she will say? Well, let me guess. She will probably say that if she did otherwise, hiring the beautiful as cleaning persons and the ugly as waitresses, customers would not prefer going to this café. She would lose customers and end up going out of business.

And I am the racist.

Our creator programmed us to seek our sexual partner, our spouse, our companion, our friends, based on discrimination. As far as our spouse is concerned, we are programmed to pick and choose. If not for that, the human race would degenerate, instead of evolve. We choose good looking sexual partners to produce healthy children. This is our genetic predisposition. This is how humanity is programmed. Actually, this is how all species are programmed. And this is how nature works. Survival of the fittest and all that. Totally immoral.

Change is the only constant, as a wise man once said. And I take it from there: Those who adapt, survive. Those who do not, perish.

And I am the racist.

Anyone who ever had a friend, a spouse, a sexual partner is a racist. If you are married or have fallen in love, you are being racist. Only monks cannot be considered to be racist. All others pick and choose, discriminating people based on their looks, height, age, wealth and so on, in order to mate with them.

And I am the racist.

Or not. The point of this blog post is to prove that all of us are racists. Except monks. And monks are the only humans I respect.

]]>As far as I know, you should buy a copy of the game in order to play it. It is not free. The following assumes that you own a copy of the game.

If you want to learn more about the game and you want to download it for various reasons (for example any one of the CD-ROMs is scratched and no longer working), you can visit any of the following two links.

- http://www.theisozone.com/downloads/pc/dos-games/lands-of-lore-ii/
- http://www.oldpcgaming.net/lands-of-lore-guardians-of-destiny-review/

If you download the game from any one of the two links above, I will show you what to do next in order to install it in a modern version of Windows.

Any of the two links above will allow you to download the following two files:

- Lands_of_Lore_II-THEiSOZONE.7z.001
- Lands_of_Lore_II-THEiSOZONE.7z.002

These are zipped files in the 7z (7-Zip) format and you should already have a file archiver utility in your PC (like 7-Zip or WinRAR) in order to unzip them. Right-click on the first file, choose the file archiver utility you want from the context menu and it will unzip both files, on after the other, without you having to point the second file to it.

After unzipping the two files, a folder structure will emerge, comprised of the following folders:

- CD1
- CD2
- CD3
- CD4
- Manual
- Patch
- Scans

Each of the first four folders contains one of the CD-ROMs of the game, in an mdf/mds format. This format is used in order to contain the content of one CD-ROM disc. The .mdf file has a large size and the .mds file has a small size.

You can use a utility like Alcohol 52%, Alcohol 120%, or PowerISO (or any other utility like them) to create virtual drive letters and drives, then mount these .mdf/.mds files and then install and run the game from the virtual drives.

In a modern Windows OS, the game may have trouble running, becuse it was developed for older Windows OS’s. To overcome any problems and to be able to run it on newer Windows OS’s, I recommend downloading an installing DOSBox, which is an x86 emulator with DOS. I recommend installing the game in DOSBox and running it from there. Not only that, but I also recommend to extract the content of the CD-ROMs (using Alcohol or PowerISO by mounting them first or simply extracting the contents, depending on the utility) and then use DOSBox’s ability to mount them as virtual drives.

In the rest of this blog post, I will show you how you can use DOSBox as a utility, like Alcohol or PowerISO, in order to mount a folder hierarchy as a virtual drive and then install and run the program contained in the folder/virtual drive. And, of course, you may mount more than one folder/virtual drive at once. In our case, since we have four CD-ROMs, we will want to mount all of them at the same time, so as not to be bothered with mounting and unmounting CD-ROMs during our game play.

Actually, this is a good practice, when you have to use applications that need one or more CD-ROMs or DVD-ROMs. Suppose you need to install and use many applications and each one of those needs from 1 to 15 CD-ROMs in order to function. What would you do? Well, I will provide a method in the appendix at the end of this blog post, but you will understand the concepts and one way of proceeding just below.

The way of proceeding I am referring to is the use of DOSBox. Well, this method is valid only if we have DOS applications, whereas the methods I will show you in the appendix cover Windows applications. Since Lands of Lore Guardians of Destiny can run in DOS, we can use the DOSBox method I will now describe. DOSBox is not only an emulator that you can use to run DOS applications, but it also provides you with the ability to create virtual drives, just as Alcohol or PowerISO do. Thus, not only will we be able to run the game in a modern version of Windows (but inside DOSBox), but DOSBox will also allow us to mount the CD-ROMs of the game. So, we have a double win.

But, as far as I know, DOSBox does not support .mdf or .mds fiels, whereas it supports mounting folders with regular files. So, before mounting the CD-ROMs, we first have to extract each CD-ROM’s content to a different folder, using Alcohol or PowerISO (or any other similar utility).

Please note that we can skip this step and use Alcohol or PowerISO to mount the virtual drives. This way, DOSBox will reference these drives and we will only use DOSBox to install and run the game. We will not use DOSBox’s ability to mount the drives, since this function will be provided by Alcohol or PowerISO. But I find that it is better to avoid having yet another utility running and serving the CD-ROM content to DOSBox, when DOSBox is perfectly capable of doing this on its own.

So, let us begin.

Install Alcohol or PowerISO and extract the contents of each CD, either by mounting it and then copying it the contents, or just by extracting the contents from the .mdf of .mds file, depending on the utility you are using. Please note the volume label, because some games may check for it to find if it is available on the virtual volume you will create. The volume labels are LOLG_CD1, LOLG_CD2, LOLG_CD3, LOLG_CD4 fro the four CD_ROMs respectively. So, let us keep use these names to create four folders in the root of drive C: (bad practice by the way, since we are “polluting” the root namespace) and let us put in each folder the contents of the respective CD-ROM.

So we now have the following four folders, containing the contents of the four CD-ROMs:

- C:\LOLG_CD1
- C:\LOLG_CD2
- C:\LOLG_CD3
- C:\LOLG_CD4

We may now download and install DOSBox. The current version as of now is 0.74.

There are three main folders pertaining to DOSBox installation. First, we have the folder DOSBox-0.74 where the program is installed in the Program Files folder. Then we have the folder C:\dosbox\ which the program creates and considers its root, file system wise. When the program (DOSBox) starts, it sets the current directory there and you cannot go higher by “CD ..”. Lastly, there is the folder DOSBox in your user profile folder and under AppData\Local\. This folder is important because inside it you will find the dosbox-0.74.conf file, which stores the settings for the DOSBox configuration. Actually, you may need to change the following settings and set them as follows, in order for the game to function properly:

output=ddraw fullresolution=1920 X 1080 scaler=normal3x aspect=true

Please note that the fullresolution value is provided an example (and is the resolution of the screen that I am currently using). Please substitute the value “1920 X 1080” with the resolution of your screen.

The file dosbox-0.74.conf has a section at the end where you can put DOS and DOSBox commands and they will be executed each time DOSBox starts. We will not need to put any commands there. Whatever commands we may need, we will put them in batch files and execute them (by typing the name of each batch file) after DOSBox starts. To create mount the necessary drives and to run the gane, we will need only one batch file.

Let us create the following batch file, named LOLG.BAT, in the C:\dosbox folder:

ECHO ON MOUNT -U D MOUNT -U E MOUNT -U F MOUNT -U G MOUNT D C:\LOLG_CD1 -T cdrom -LABEL LOLG_CD1 MOUNT E C:\LOLG_CD2 -T cdrom -LABEL LOLG_CD2 MOUNT F C:\LOLG_CD3 -T cdrom -LABEL LOLG_CD3 MOUNT G C:\LOLG_CD4 -T cdrom -LABEL LOLG_CD4

Please note that the batch file and I assume that the drive letters from D onwards are available.

We can run this batch file by typing its name in the DOSBox console. This batch files loads all four CD-ROMs. Actually, to install the game, we only needed to mount only the first CD-ROM. We can change the current drive to D and run setup.exe from there:

D: SETUP

SETUP will create a folder named WESTWOOD in C:\DOSBOX\ (our root) and it will then install the game there.

Let me explain the commands in LOLG.BAT.

ECHO ON is for displaying the command that is executed.

UMOUNT is for unmounting the drive letter that follows the command. When you first run the batch file, after each time DOSBox starts, there is no need to run UMOUNT, because no drive letters will be mounted, (other than C:\DOSBOX as C:). But it is a good practice to unmount any drive letters that you are planning to mount, in case you may need to run the batch file more than once in a session, especially if there has been some other drive mounting in between.

MOUNT is for mounting the drive letter that follows the command. The contents of the folder that follows are the contents of the drive. -T specifies the mode that will be emulated. -LABEL specifies the volume label that will assigned to the drive volume. Please note that although DOSBox considers the file system root to be at C:\DOSBox, the DOSBox MOUNT command sees all your PC’s file system and disks, so the C:\DOSBox root does not apply to the MOUNT command.

After installation of the game is complete, you can change the LOLG.BAT as follows, in order to run the game:

ECHO ON MOUNT -U D MOUNT -U E MOUNT -U F MOUNT -U G MOUNT D C:\LOLG_CD1 -T cdrom -LABEL LOLG_CD1 MOUNT E C:\LOLG_CD2 -T cdrom -LABEL LOLG_CD2 MOUNT F C:\LOLG_CD3 -T cdrom -LABEL LOLG_CD3 MOUNT G C:\LOLG_CD4 -T cdrom -LABEL LOLG_CD4 C: CD \WESTWOOD\LOLG\ LOLG.EXE

So, by typing LOLG (you can always omit the .BAT extension for batch files) in the root of the DOSBox console, the game will run, having all CD-ROMs fully loaded – no need to change CD-ROMs during game play.

Please note that you can change DOSBox and the application that it runs from full screen to a window and vice versa by simultaneously pressing ALT and ENTER (holding ALT and pressing ENTER).

**Appendix**

So you have seen how you can install and run a DOS application that uses one or more CD-ROMs. DOSBox is a great solution, because it is not only an emulator, but it also provides virtual drive creation and mounting capability.

So, if you have one or more DOS applications that you need to run, you can create a batch file for each of these applications. Each batch file will unmount the drive letters it needs to use for the application and then mount them using the folders that contain the contents of the respective CD-ROMs for the application.

Let us suppose that we have one DOS application that needs four drive letters, and another that needs six drive letters. To run any application, only one at a time, in any order, each batch file only needs to unmount and mount the drive letters the application needs. Say for example that we run the application that needs six drive letters. Its batch file will unmount and then mount the drive letters D, E, F, G, H, I. We exit this application and then we run the application that needs four drive letters. If its batch file unmounts all six drive letters and then mounts the four drive letters that it needs, then this is excellent. But even idf its batch file unmounts only the four drive letters that the applications needs, it is fine. The drive letters H, I will remain mounted in the other applications contents, but they will be ignored by the current application.

Actually, the perfect way to do this is to create a file with the drive letters that you want to have available for mounting and unmounting. Then each batch file will read this file and unmount each and every one of these drive letters, before mounting any drive letters that the respective application needs. This way, you can adjust the available drive letters from time to time and from PC to PC. But you do not have to go to such extremes, since I already explained that it is perfectly file for each batch file to unmount and mount only the amount of drive letters that the application needs, leaving any (higher) drive letters as they were from any previous use of other applications that needed more drive letters. Another idea. is to create a batch file that only unmounts all drive letters you may want. You may run it whenever you want and each application batch file can call it at its beginning.

What you cannot do with this method, is run both applications simultaneously. Actually, if you need to run two or more such applications simultaneously, you should create a batch files that loads all CD-ROMs for these applications. There is a limit to this practice, thought, since only 26 drive letters can exist (the English alphabet has this limit) and also, some of these drive letters are used, like C: for the actual hard disk of the PC.

DOSBox can be used for DOS applications. What can we do if we want to accomplish the same results for Windows applications? What can we do if we want to run lots of applications, one at a time (that is the restriction), when each application needs one or more CD-ROMs or DVD-ROMs to be mounted?

In this case, we will again use batch files to unmount and mount the contents of the respective CR-ROMs or DVD-ROMs, but we will not use DOSBox, since DOSBox can only run DOS applications.

One method we can use is the command line SUBST command. Just like DOSBox’s MOUNT command, SUBST mounts a drive letter with the contents of the folder you specify. And this command line command comes with the operating system – no need to install anything extra. The following batch file prepares the PC to run RIVEN, using the drive letters P through T, after I copied the contents of the five RIVEN CD-ROMs in five respective folders:

SUBST P: /D > NUL SUBST Q: /D > NUL SUBST R: /D > NUL SUBST S: /D > NUL SUBST T: /D > NUL SUBST P: "C:\RIVEN1" SUBST Q: "C:\RIVEN2" SUBST R: "C:\RIVEN3" SUBST S: "C:\RIVEN4" SUBST T: "C:\RIVEN5"

Another method is to use Alcohol to create .mdf/.mds files from the contents of your CD-ROMs. Then specify how many virtual drives you want to have. Lastly, you can use batch files to unmount and mount these files, using Alcohol’s command line program AxCmd, that Alcohol provides exactly for this kind of automation.

The following batch file assumes that I used Alcohol 52% to specify that my PC will have (at least) 5 virtual drives. The 5 .mds files that correspond to the 5 RIVEN CD-ROMs are in the folder C:\Games\Alcohol\. The batch file will prepare the PC to run RIVEN and will load the five .mds files, each one at the next available virtual drive.

C: CD "C:\Program Files\Alcohol Soft\Alcohol 52" AxCmd 1: /U AxCmd 2: /U AxCmd 3: /U AxCmd 4: /U AxCmd 5: /U AxCmd 1: /M:C:\Games\Alcohol\Riven1.mds AxCmd 2: /M:C:\Games\Alcohol\Riven2.mds AxCmd 3: /M:C:\Games\Alcohol\Riven3.mds AxCmd 4: /M:C:\Games\Alcohol\Riven4.mds AxCmd 5: /M:C:\Games\Alcohol\Riven5.mds

Thus, in this blog post you learnt what to do if you have lots of applications that each requires lots of CD-ROMs or DVD-ROMs and you want to run each application, (one application at a time), without having to physically insert and remove disks. The obvious downside is that you need an amount of disk space roughly equal to the size of the contents of all the disks of all the applications.

]]>I have a shared folder pertaining to this blog post that you are free to visit and download its contents. You may visit the shared folder at the following link: Count in any numbering system. In this folder, you will find:

- An Excel spreadsheet with two tabs, that may help you in your learning.
- A text file that contains the source code of the program (in C# with .NET framework version 2.0) that counts in any numbering system.
- A zip file that contains the complete Visual Studio Windows Forms C# project (that also contains the source code of the program that counts in any numbering system.)
- An executable file, which is the Windows program that counts in any numbering system. You can copy the executable file in any folder of your Windows OS and run it. It needs no installation, but you need to have the Windows .NET framework (version 2.0 at least) in order to execute the program.

**OK. First things first: How to count in any numbering system.**

We (humans) use the base-10 numbering system. Why? Well, all numbering systems are equivalent, but we chose the base-10 numbering system because we have ten fingers, and we find counting in tens to be more intuitive and convenient. We are used to counting in tens, so we chose a numbering system that corresponds to this counting manner.

If we were a species with three fingers (three fingers altogether, and to keep the symmetry we might have had three hands, each hand having only finger, or only one hand with three fingers, or even two hands, one with two fingers and the other hand with only one finger, but then these two hands might be in opposite directions in order to keep the symmetry of our body) we might have chosen to use the base-3 numbering system for counting, because we would want to count in threes.

The smallest base that can exist is base-2. In base-2, we have two digits: 0, 1.

In base-3, we have three digits: 0, 1, 2.

And so on.

In base-10, we have 10 digits: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.

In base-11, we have 11 digits: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A. (We use letters because we run out of number symbols. Actually we may use any symbol for any number. So, if, for example, we replace 0 with &, and 1 with *, and 2 with %, etc, we will have an equivalent representation).

In base-16, we have 16 digits: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F.

And so on.

Here is how to count in any-numbering system:

**Example in base-2, which means that the digits are 0, 1.**

Start from 0, which is equal to infinite zeros: …000000

Increase the rightmost digit.

...000000 ...000001

When the rightmost digit cannot increase any more,

set the rightmost digit to zero

and increase the second rightmost digit.

...000010

Continue to increase the rightmost digit,

keeping the other digits as they are.

...000011

When the rightmost digit cannot increase any more,

set the rightmost digit to zero

and increase the second rightmost digit.

But if the second righmost digit cannot increase anymore,

set it to zero as well

and increase the third rightmost digit.

...000100

And so on:

...000101 ...000110 ...000111 ...001000 ...001001 ...001010 ...001011 ...001100 ...001101 ...001110 ...001111 ...010000 ...010001 .........

And so on…

**Example in base-3, which means that the digits are 0,1,2.**

Start from 0, which is equal to infinte zeros: …000000

Increase the rightmost digit.

...000000 ...000001 ...000002

When the rightmost digit cannot increase any more,

set the rightmost digit to zero

and increase the second rightmost digit.

...000010

Continue to increase the rightmost digit,

keeping the other digits as they are.

...000011 ...000012

When the rightmost digit cannot increase any more,

set the rightmost digit to zero

and increase the second rightmost digit.

...000020

Continue to increase the rightmost digit,

keeping the other digits as they are.

...000021 ...000022

When the rightmost digit cannot increase any more,

set the rightmost digit to zero

and increase the second rightmost digit.

But if the second righmost digit cannot increase anymore,

set it to zero as well

and increase the third rightmost digit.

...000100

And so on:

...000101 ...000102 ...000110 ...000111 ...000112 ...000120 ...000121 ...000122 ...000200 ...000201 ...000202 ...000210 ...000211 ...000212 ...000220 ...000221 ...000222 ...001000 ...001001 ...001002 ...001010 ...001011 ...001012 ...001020 ...001021 ...001022 ...001100 ...001101 ...001102 ...001110 ...001111 ...001112 ...001120 ...001121 ...001122 ...001200 ...001201 ...001202 ...001210 ...001211 ...001212 ...001220 ...001221 ...001222 ...002000 ...002001 ...002002 ...002010 ...002011 ...002012 ...002020 ...002021 ...002022 ...002100 ...002101 ...002102 ...002110 ...002111 ...002112 ...002120 ...002121 ...002122 ...002200 ...002201 ...002202 ...002210 ...002211 ...002212 ...002220 ...002221 ...002222 ...010000 ...010001 .........

And so on…

**Additional notes:**

So now you know how to produce the numbers of any base in ascending order. There is another way to produce the numbers of any base in ascending order. This is done by writing vertically each digit column starting from the rightmost digit column. So, you create the rightmost digit column by writing each number once starting from 0 then 1 and so on. When the digits finish, you start over. So, for base 2, you write:

....0 ....1 ....0 ....1 ....0 ....1 ....0 ....1 .....

Then you create the second rightmost column by noticing the repeating pattern of the rightmost column and matching it with one digit in the second rightmost column, starting from zero. The repeating pattern of the rightmost column is 0-1. So you create the second rightmost column as follows:

...00 ...01 ...10 ...11 ...00 ...01 ...10 ...11 .....

As you may notice, the repeating pattern of the second rightmost column is 0-0-1-1.

So you create the third rightmost column as follows:

..000 ..001 ..010 ..011 ..100 ..101 ..110 ..111 .....

The repeating pattern of the third rightmost column is 0-0-0-0-1-1-1-1.

And so on.

For base-3, the repeating pattern of the rightmost column would be 0-1-2. The repeating pattern of the second rightmost column would be 0-0-0-1-1-1-2-2-2. The repeating pattern of the third rightmost column would be 0-0-0-0-0-0-0-0-0-1-1-1-1-1-1-1-1-1-2-2-2-2-2-2-2-2-2. And so on.

Counting is important and base-2 and bases that are powers of 2, especially base-16, are very important when dealing with digital electronics and computers in low-level. Let me explain why.

First of all, computers are created as large bundles of electronic switches. Switches, electronic or otherwise, have two states: off and on. So, engineers assign the number 0 to one of the states and the number 1 to the other state (in a consistent manner, of course) and can set each switch to any state or read any switch’s state. That’s how computations are made at a low-level. So, binary arithmetic is essential to enginners for the programming and operation of a computer. The state of each electronic switch is either 0 or 1, and 0 and 1 are the “binary” digits, or bits as they called in computer parlance. Just for your information, each electronic switch is made up from a few transistors, which can me made really tiny. A computer chip may contain billions of transistors.

OK, so base-2 and the corresponding arithmetic (binary arithmetic) of this numbering system is important to computers, But why is base-16 (hexadecimal arithmetic) also important? Well, the numbering systems of the powers of the same base have an important connection. I will now explain what this connection is. For example, let us take the number 2. The numbering systems that are powers of 2 are: base-2, base-4, base-8, base-16, base-32, base-64, and so on. The conversion between any of these numbering systems to another such system can be easily done.

Here is how: Let us study base-2 and base-16. suppose we have a number in base-16, for example B8. What is this number in base-2? To answer, we will represent each of the hexadecimal digits with 4 binary digits, since we need 4 binary digits to represent the highest hexadecimal digit (F in base-16 is 1111 in base-2). So, we have the number B8, and B in base-16 is 1011 in base-2, and 8 in base-16 is 1000 in base-2. The important property of numbering systems of powers of the same base allows us to find a number’s equal in another such base, as follows: We substitute each digit from the higher base to the equivalent digits of the lower base, or we group the digits of the lower base to the equibalent digits of the higher base. In the case of the base-16 number B8, it is equal to 10111000 in base-2, where the first four binary digits correspond to B and the next 4 binary digits correspond to 8.

Another example: Given the base-2 number 110100011, what is the equivalent base-16 number? Well we will group the digits by four’s, starting from the right and adding leading zeros if we need to. So our number becomes: 0001 1010 0011. Substituting each group of 4 digits with its hexadecimal equivalent gives us the base-16 number 1A3.

This property is very important to computing and one of the reasons engineers chose to represent information in bytes. Each byte is an ordered set of 8 bits. By choosing bytes to be comprised of 8 bits each, it makes their representation very easy: Each byte can be represented by two hexadecimal digits. So a byte with the following value in bits: 00100100, can be represented as 24 in hexadecimal (base-16).

I found that knowing how to count in base-2 was enough to solve any IP (Internet Protocol) subnetting problem that I ever encountered! Of course, it will be very beneficial to you if you learn how to do other operations as well (beyond counting, like addition, subtraction, multiplication, division, transformation of a number from one base to another). And, if you will be dealing with computers, you may often encounter base-2 and base-16 number representations.

**My program which counts in any numbering system**

I created a program in C# that counts in any numbering system. I will present the code below and you can also download the code or even the complete Visual Studio project from the link I provide in the beginning of this blog post.

If you want to recreate the project yourself, just create a new project in Visual Studio as a Windows Forms C# application. In a form place two textboxes, a button and a DataGridView. You may also place two labels, to show what each textbox use is. And then, use my code as the form’s code.

You, may see what the form looks like below:

In the first textbox, you enter the base for which you want to count. Counting will start from 0 up to the number you want. You must specify this number in its base-10 representation in the second textbox. When you press the button, the program will create two columns in the datagridview. The first column will contain the numbers in base-10 for your reference and the second column will contain the equivalent numbers in the base you specified in the first textbox.

In the code you will see that there is a string (array of characters) called strDigitSymbols. These are the digits that the program uses to construct the numbers in the second datagridview column. So, even if the program “knows” for sure it “wants” to use a 0 or a 1 in the second gridcolumn, it will never put 0 or 1, but instead it will put strDigitSymbols.Substring(0, 1) instead of 0 and strDigitSymbols.Substring(0, 1) instead of 1. This is because I want to let the user specify alternate symbols, should she wish to do so. Thus, whereas the “normal” strDigitSymbols would be “0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ”, the user is allowed to replace it with whatever string she wishes, for example “%#*@(F4SL!)-+0=”, No, this is not swearing, it is a string with 15 characters, which means that the program can count for bases up to base-15. The string I have put in the program contains 36 characters, which means that the program, as is, can count up to base-36. You can add more digits to the string, so you can request counting in even larger bases. The program can count up to the base that has the same number as the number of digits that exist in strDigitNumbers.

As for the first datagridview column, it is in base-10 for your reference and does not look in the strDigitSymbols to get its symbols. The program uses regular good old decimal digits for the first datagridview column.

Here is the code:

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace Count { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } private void button1_Click(object sender, EventArgs e) { const string strDigitSymbols = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; dataGridView1.Rows.Clear(); dataGridView1.Columns.Clear(); dataGridView1.Refresh(); bool isNumerical; int intBase = 0; isNumerical = false; isNumerical = int.TryParse(textBox1.Text, out intBase); if (!isNumerical) { MessageBox.Show("The base number must be an integer equal or greater than 2", "Error in the base number: Not an integer.", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (intBase < 2) { MessageBox.Show("The base number cannot be less than 2.", "Error in the base number: Too small.", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (intBase > strDigitSymbols.Length) { MessageBox.Show("There are not enough digit symbols to represent the numbers for the base number you requested.", "Error in the base number: Too big.", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } int intMaximumCount = 0; isNumerical = false; isNumerical = int.TryParse(textBox2.Text, out intMaximumCount); if (!isNumerical) { MessageBox.Show("The number in base-10 to count up to must be a positive integer", "Error in the count number: Not an integer.", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } dataGridView1.Columns.Add("Base 10", "Base 10"); dataGridView1.Columns.Add("Requested Base", "Requested Base"); dataGridView1.Columns["Base 10"].DefaultCellStyle.Alignment = DataGridViewContentAlignment.BottomRight; dataGridView1.Columns["Requested Base"].DefaultCellStyle.Alignment = DataGridViewContentAlignment.BottomRight; dataGridView1.Columns["Base 10"].HeaderCell.Style.Alignment = DataGridViewContentAlignment.BottomRight; dataGridView1.Columns["Requested Base"].HeaderCell.Style.Alignment = DataGridViewContentAlignment.BottomRight; string strPreviousNumber = strDigitSymbols.Substring(0, 1); dataGridView1.Rows.Add(0, strPreviousNumber); string strNextNumber; string strDigit; string strNextDigit; int i; bool blnFinished = false; for (int intCount = 1; intCount <= intMaximumCount; intCount++) { // We begin each for iteration with the strPreviousNumber set at the end of the pevious for iteration. // The goal of each for iteration is to find the strNextNumber, which is the number that succeds the strPreviousNumber. strNextNumber = ""; strDigit = ""; strNextDigit = ""; i = 0; blnFinished = false; // We will get each digit of the previous number starting from the right of the previous number, // using i as the counter to access the digits of the previous number. while (true) { // Get next digit of the previous number from the left. strDigit = strPreviousNumber.Substring(strPreviousNumber.Length - 1 - i, 1); // For the digit obtained, find the coresponding digit that succeeds it, // using j as the counter to scan strDigitSymbols. for (int j = 0; j <= intBase - 1; j++) { if (strDigit == strDigitSymbols.Substring(j, 1)) { // We found the digit and now we will take the corresponding digit that suceeds it and then we will break from the inner for loop. if (j < intBase - 1) { // If we are here, it means that we have the "normal" case where the next digit is greater than the previous digit. // Example in Base-10: strDigit = "6", thus strNextDigit = "7". // Because this kind of incementation will happen, we will set blnFinished to true, in order to break from the while loop. strNextDigit = strDigitSymbols.Substring(j + 1, 1); if (strPreviousNumber.Length - 1 - i > 0) { // If we are here, it means that there are more digits of the previous number to the left of the digit we are processing. strNextNumber = strPreviousNumber.Substring(0, strPreviousNumber.Length - 1 - i) + strNextDigit + strNextNumber; } else { // If we are here, it means that there no are more digits of the previous number to the left of the digit we are processing. strNextNumber = strNextDigit + strNextNumber; } // We finished processing and we need to break from the while loop. blnFinished = true; } if (j == intBase - 1) { // If we are here, it means that the next digit is the first in strDigitSymbols. // Example in Base-10: strDigit = "9", thus strNextDigit = "0".\ // Because this kind of incementation will happen, we will not set blnFinished to true, in order to continue looping in the while loop. strNextDigit = strDigitSymbols.Substring(0, 1); strNextNumber = strNextDigit + strNextNumber; } break; // Break from the inner for loop. } // End of the outer if statement. } // End of the inner for loop. if (blnFinished == true) { break; // Break from the while loop. } i++; if (i == strPreviousNumber.Length) { break; // Break from the while loop because there are no more digits to process. } } // End of the while loop. if (blnFinished == false) { // If we are here, it means that all digits have been turned to zero, // so we need to add a "1" in front of all these zeros. // Example in Base-10: strPreviousNumber = "9999", thus strNextNumber = "10000". strNextNumber = strDigitSymbols.Substring(1, 1) + strNextNumber; } dataGridView1.Rows.Add(intCount, strNextNumber); // We begin each for iteration with the strPreviousNumber set at the end of the pevious for iteration. // The goal of each for iteration is to find the strNextNumber, which is the number that succeds the strPreviousNumber. strPreviousNumber = strNextNumber; } // End of the for loop. } // End of the button1_Click. } // End of the class. } // End of the namespace.

The outer for loop is used to count from 0 to the decimal number in the second textbox. This represents up to how many numbers we will count. The counter for this for loop is a regular decimal numbers and is used to populate the first datagridview column for your reference. In each outer for loop iteration, the program finds the number that will go in the second datagridview column, based in the base you requested in the first textbox. How does the program find the number in the requested base? Well, the first number is 0, or, rather, the first number in strDigitSymbols. In each outer for loop iteration it uses the knowledge of what the previous number was and it scans the previous number’s digits as well as the strDigitSymbols digits, to deduce the “current” number.

The program never breaks form the outer for loop. The loop continues until it reaches the number you have specified in the second textbox.

In each for loop iteration, the program uses a while loop to scan the digits of the previous and an inner for loop to scan the strDigitSymbols. This way, the program can deduce the next number in the sequence.

The program is heavily commented, so you may understand its inner workings.

]]>