Mind boggling card trick: Difference between revisions
m (→{{header|Python}}: added zkl header) |
|||
Line 89:
=={{header|zkl}}==
<lang zkl>cards:=[1..52].pump(List,"isEven","toInt").shuffle(); // red==1
stacks:=T(List(),List()); // black stack (0), red stack (1)
blkStk,redStk := stacks;
foreach card in (cards){ stacks[card].append(__cardWalker.next()) }
println("Stacks:\n Black stack: ",blkStk,"\n Red stack: ",redStk);
numSwaps:=(1).random(1000); // do lots of swaps
do(numSwaps){ blkStk.append(redStk.pop(0)); redStk.append(blkStk.pop(0)); }
println("Post %d swaps:\n Black stack: %s\n Red stack: %s"
.fmt(numSwaps,blkStk,redStk));
numBlack,numRed := blkStk.filter('==(0)).len(), redStk.filter().len();
if(numBlack==numRed)
println("Agreed, black stack has same number of black cards \n "
"as red stack has number of red cards: ",numRed);
else println("Boo, differnt stack lenghts");</lang>
{{out}}
<pre>
Stacks:
Black stack: L(0,0,1,1,0,0,1,0,0,0,0)
Red stack: L(0,1,0,1,0,1,1,1,0,1,0,0,1,1,0)
Post 99 swaps:
Black stack: L(0,0,1,1,0,0,0,1,1,0,0)
Red stack: L(1,0,0,0,0,0,1,0,1,0,1,1,1,0,1)
Agreed, black stack has same number of black cards
as red stack has number of red cards: 7
</pre>
|
Revision as of 18:53, 25 August 2018
Matt Parker of the Stand Up Maths channel on you tube has a video of a card trick that creates a semblance of order from chaos.
The task is to simulate the trick in a way that mimicks the steps shown in the video.
- 1. Cards
- Create a
pack
of 52 cards, half red - half black. - Give the pack a good shuffle.
- 2. Deal from the randomised pack into three stacks
- Assemble the cards face down.
- Turn up the top card,
- if it is black then add the next card, unseen, to the
black-stack
. - If it is red then instead add that next card, unseen, to the
red-stack
.
- if it is black then add the next card, unseen, to the
- Add the card you turned over to see what colour it was above, to the
discard-stack
.
(You might optionally show these discard cards to give an idea of the randomness).
- Turn up the top card,
- Repeat the above for the whole of the assembled pack.
- 3. Swap the same, random, number of cards between the two stacks.
- Randomly choose the number of cards to swap.
- Randomly choose that number of cards out of each stack to swap.
(Without knowing those cards - they could be red or black cards from the stacks, we don't know).
- 4. Order from randomness?
- Check the mathematicians assertion that: The number of black cards in the black pile equals the number of red cards in the red pile.
Show output on this page.
Python
The code is layed out to follow the task decription, leading to some deviations from the PEP8 guidelines <lang python>import random
- 1. Cards
n = 52 Black, Red = 'Black', 'Red' blacks = [Black] * (n // 2) reds = [Red] * (n // 2) pack = blacks + reds
- Give the pack a good shuffle.
random.shuffle(pack)
- 2. Deal from the randomised pack into three stacks
black_stack, red_stack, discard = [], [], [] while pack:
top = pack.pop() if top == Black: black_stack.append(pack.pop()) else: red_stack.append(pack.pop()) discard.append(top)
print('(Discards:', ' '.join(d[0] for d in discard), ')\n')
- 3. Swap the same, random, number of cards between the two stacks.
- We can't swap more than the number of cards in a stack.
max_swaps = min(len(black_stack), len(red_stack))
- Randomly choose the number of cards to swap.
swap_count = random.randint(0, max_swaps) print('Swapping', swap_count)
- Randomly choose that number of cards out of each stack to swap.
def random_partition(stack, count):
"Partition the stack into 'count' randomly selected members and the rest" sample = random.sample(stack, count) rest = stack[::] for card in sample: rest.remove(card) return rest, sample
black_stack, black_swap = random_partition(black_stack, swap_count) red_stack, red_swap = random_partition(red_stack, swap_count)
- Perform the swap.
black_stack += red_swap red_stack += black_swap
- 4. Order from randomness?
if black_stack.count(Black) == red_stack.count(Red):
print('Yeha! The mathematicians assertion is correct.')
else:
print('Whoops - The mathematicians (or my card manipulations) are flakey')</lang>
A run.
- Output:
(Discards: R B R R B B R R R B B B B R R R B R R B B B B R B R ) Swapping 11 Yeha! The mathematicians assertion is correct.
A second run:
- Output:
(Discards: R B B R B B R B R R R B R R B B B B R R B R R B B R ) Swapping 2 Yeha! The mathematicians assertion is correct.
zkl
<lang zkl>cards:=[1..52].pump(List,"isEven","toInt").shuffle(); // red==1 stacks:=T(List(),List()); // black stack (0), red stack (1) blkStk,redStk := stacks; foreach card in (cards){ stacks[card].append(__cardWalker.next()) } println("Stacks:\n Black stack: ",blkStk,"\n Red stack: ",redStk);
numSwaps:=(1).random(1000); // do lots of swaps do(numSwaps){ blkStk.append(redStk.pop(0)); redStk.append(blkStk.pop(0)); } println("Post %d swaps:\n Black stack: %s\n Red stack: %s"
.fmt(numSwaps,blkStk,redStk));
numBlack,numRed := blkStk.filter('==(0)).len(), redStk.filter().len(); if(numBlack==numRed)
println("Agreed, black stack has same number of black cards \n " "as red stack has number of red cards: ",numRed);
else println("Boo, differnt stack lenghts");</lang>
- Output:
Stacks: Black stack: L(0,0,1,1,0,0,1,0,0,0,0) Red stack: L(0,1,0,1,0,1,1,1,0,1,0,0,1,1,0) Post 99 swaps: Black stack: L(0,0,1,1,0,0,0,1,1,0,0) Red stack: L(1,0,0,0,0,0,1,0,1,0,1,1,1,0,1) Agreed, black stack has same number of black cards as red stack has number of red cards: 7