From New Scientist #1461, 20th June 1985 [link]
I showed my son the famous 21 card trick. I used 21 cards numbered from 1 to 21, which remained face upwards throughout the trick. I started with them in numerical order in a pile, 1 being on the top. I dealt them into three piles (1 on to the first, 2 on to the second, 3 on to the third, 4 on to the first again, and so on) and asked my son to choose one of the numbers without telling me which. Then he had to tell me which pile his number was in.
I then picked up the piles, placing his chosen pile in the middle of the three. With this new pile I started all over again and repeated the performance twice more, my son pointing out the pile which contained his chosen number each time. After the third and final collecting up of the cards his chosen card was (of course) in 11th place.
He then tried it on me, but he didn’t know the trick. He started with the cards in order as I had done, I chose a number, he went through the three deals (but collecting up the piles in his own fashion) and, not surprisingly, the trick went wrong.
The number I had chosen ended up in the 10th place, not the 11th. The number in the 11th place was in fact half my number. And the number which was twice mine ended up in the same place in the pile as it had started in.
What was my chosen number?
[enigma313]
This Python program examines all the possible orders that the piles can be picked up in. It runs in 37ms.
Solution: Your chosen number was 10.
On the first deal the “10” card would appear in pile 1, and the piles are collected as pile 1 + pile 2 + pile 3.
On the second deal the “10” card would appear in pile 1, and the piles are collected as pile 2 + pile 1 + pile 3.
On the third deal the “10” card would appear in pile 1, and the piles are collected as pile 3 + pile 1 + pile 2.
The final order of the cards is: (13, 8, 3, 1, 18, 7, 2, 17, 12, 10, 5, 16, 11, 6, 4, 21, 19, 14, 9, 20, 15), with the chosen “10” card at position 10, the “5” card at position 11 and the “20” card at position 20.
I don’t think you need to bother with the loop at line 17. Something like this would do: