At a cousin’s wedding, a boy you have never met holds out five cards covered in numbers. “Think of any number from 1 to 31,” he says. “Don’t tell me. Just say yes or no: is it on this card?” He shows you the cards one at a time. You answer five times, and he tells you your number at once. He gets your sister’s right too, and your grandmother’s, though she chose 31 to catch him out.
He isn’t reading minds. He knows a secret you met in Grade 6, and once you know it you can make the cards yourself.
Here are his five cards. Think of a number and let the page read your mind.
Before you find out how: how much does the page need to know to find your number?
Pick an answer to see why.
You need: binary numbers, from Grade 6. For the blocks, variables and choices, from Grade 7. For the Python, loops, lists and functions, from Grade 8.
Try it
Look at the cards
Play the trick a few times above, then press How did it know? after one. Before you read on, look hard at the cards themselves.
- a.What is the first number, top left, on each of the five cards?
- b.Which number is on every card? Which numbers are on only one card?
- c.How many numbers are on each card?
Those first numbers, 1, 2, 4, 8, 16, are the place values of binary, the same as on the five dot cards you could make in Grade 6. That is not a coincidence.
Which cards is a number on?
Here are all five cards at once, the biggest first. Move the slider to choose a number, and watch which cards it is on.
- a.Find 21. Which cards is it on? Now read the row of 1s and 0s under the cards.
- b.Go from 15 to 16. What happens to the cards?
- c.Find 10 and 20. Compare their rows.
Your friend says yes to the cards that start with 8, 2 and 1, and no to the others. What is the number?
Pick an answer to see why.
How it works
Each card is one binary digit
Every number from 1 to 31 can be written in binary with five digits, worth 16, 8, 4, 2 and 1. The card that starts with 4 holds every number whose fours digit is 1, and no others. The same goes for every card: the card that starts with 16 holds every number with a 1 in the sixteens place.
So “is your number on this card?” really asks “is this binary digit of your number a 1?” Five answers give all five digits:
| Number | 16 | 8 | 4 | 2 | 1 | Cards it is on |
|---|---|---|---|---|---|---|
| 5 | 0 | 0 | 1 | 0 | 1 | 4 and 1 |
| 13 | 0 | 1 | 1 | 0 | 1 | 8, 4 and 1 |
| 21 | 1 | 0 | 1 | 0 | 1 | 16, 4 and 1 |
| 30 | 1 | 1 | 1 | 1 | 0 | 16, 8, 4 and 2 |
| 31 | 1 | 1 | 1 | 1 | 1 | all five |
The magician then reads the binary number as you did in Grade 6: he adds the place values that have a 1. A card’s first number is its place value, because the smallest number with a 1 in the fours place is 4 itself (100). That is why he only looks at the top-left corners.
Why five cards stop at 31
Each card is a yes or a no, so five cards give 2 × 2 × 2 × 2 × 2 = 32 patterns. One of them, no to every card, is 0, which the trick doesn’t use; the other 31 are the numbers 1 to 31. Add a sixth card, starting with 32, and the patterns double to 64: the trick works up to 63.
And every card holds 16 numbers because, counting in binary, each digit is 0 for half the patterns and 1 for the other half: the ones digit goes 0, 1, 0, 1…, the twos digit 0, 0, 1, 1…, the fours digit four 0s, then four 1s.
The pattern on a card
Look at the card that starts with 4: 4 5 6 7, skip 8 9 10 11, then 12 13 14 15, and so on: four on, four off. In each run of 8 numbers (0 to 7, 8 to 15…), the last four have a fours digit of 1.
A remainder tests it: divide by 8, and if the remainder is 4, 5, 6 or 7, the number is on the 4 card. For 21, 21 ÷ 8 is 2 remainder 5, so 21 is on it. For 10, the remainder is 2: not on it. The same works for any card: for the card worth c, divide by 2 × c and see whether the remainder is c or more.
Program it
With blocks: the mind reader
Here is the magician as a block program. It asks about each card in turn, starting with the card worth 1. When the answer is “yes”, it adds the card’s first number to number. Then it doubles card for the next card: 1, 2, 4, 8, 16.
With blocks: make a card
The magician needs the cards too. This program makes one. It asks which card (1, 2, 4, 8 or 16), then counts n from 1 to 31 and keeps each number whose remainder, divided by twice the card, is more than the card minus 1 (for whole numbers, the same as “the card or more”): the test from “The pattern on a card” above. It joins the numbers kept into one line of text, with a space after each, and says it at the end.
In Python (from Grade 8): one digit of a number
In Python, // divides and keeps the whole number, and % gives the remainder. number // card % 2 picks out one binary digit: dividing by the card’s value moves that digit to the ones place (as halving did in Grade 7), and % 2 says whether it is odd.
number = 21for card in [1, 2, 4, 8, 16]: digit = number // card % 2 print('Card', card, ':', number, '//', card, '=', number // card, ', so the digit is', digit)Output
Card 1 : 21 // 1 = 21 , so the digit is 1Card 2 : 21 // 2 = 10 , so the digit is 0Card 4 : 21 // 4 = 5 , so the digit is 1Card 8 : 21 // 8 = 2 , so the digit is 0Card 16 : 21 // 16 = 1 , so the digit is 1Read the digits from the bottom up: 10101, which is 21 in binary. Each 1 is a card that 21 is on.
Making every card
Now a function that makes a whole card: every number from 1 to biggest whose digit for value is 1.
def make_card(value, biggest): card = [] for n in range(1, biggest + 1): if n // value % 2 == 1: card.append(n) return card for value in [1, 2, 4, 8, 16]: print(make_card(value, 31))Output
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31][2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31][4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31][8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31][16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]Those are the five cards at the top of the page, made by your program. The cards in the widget below are made by your make_card from the program just above, as you have it (press Edit to change it). It asks for six cards, make_card(1, 63) up to make_card(32, 63), so the trick now reads any number from 1 to 63.
What your program shows
Does the trick work for every number, or only for the ones we tried? This program plays it once for each secret number from 1 to 63, with the six cards made by make_card. For each, it writes the answers as a row of Y and N (biggest card on the left, as binary is written), adds the first numbers of the cards said yes to, and checks the total.
def make_card(value, biggest): card = [] for n in range(1, biggest + 1): if n // value % 2 == 1: card.append(n) return card cards = []for value in [1, 2, 4, 8, 16, 32]: cards.append(make_card(value, 63)) found = 0rows = []for secret in range(1, 64): row = '' total = 0 for card in cards: if secret in card: row = 'Y' + row total = total + card[0] else: row = 'N' + row if total == secret: found = found + 1 rows.append(row) print('The trick found', found, 'of 63 secret numbers')same = 0for row in rows: if rows.count(row) > 1: same = same + 1print('Numbers with the same answers as another number:', same)for secret in [5, 21, 42, 63]: print(secret, rows[secret - 1], bin(secret))for card in cards: print('The card that starts with', card[0], 'has', len(card), 'numbers')Output
The trick found 63 of 63 secret numbersNumbers with the same answers as another number: 05 NNNYNY 0b10121 NYNYNY 0b1010142 YNYNYN 0b10101063 YYYYYY 0b111111The card that starts with 1 has 32 numbersThe card that starts with 2 has 32 numbersThe card that starts with 4 has 32 numbersThe card that starts with 8 has 32 numbersThe card that starts with 16 has 32 numbersThe card that starts with 32 has 32 numbers(row = 'Y' + row puts the new letter on the left, so the biggest card ends up first. rows.count(row) counts how many times a row is in the list. bin() writes a number in binary after the letters 0b.)
- The trick never fails: 63 secret numbers, 63 found.
- No two numbers share their answers. Each row of Y and N belongs to one number only, so six answers are always enough.
- Each row of answers is the number in binary, with Y for 1 and N for 0: 21 answers NYNYNY, and
bin(21)is 10101. - Every card holds exactly half, 32 of the 64 patterns.
So the cards are binary written out so that a person who knows nothing about binary hands you the digits of their number, one by one.
More cards, bigger numbers
How many cards would you need for any number up to a million? Each new card doubles the patterns, so the biggest number becomes double the last, plus one.
cards = 0biggest = 0while biggest < 1000000: cards = cards + 1 biggest = biggest * 2 + 1 print(cards, 'cards: 1 to', biggest)Output
1 cards: 1 to 12 cards: 1 to 33 cards: 1 to 74 cards: 1 to 155 cards: 1 to 316 cards: 1 to 637 cards: 1 to 1278 cards: 1 to 2559 cards: 1 to 51110 cards: 1 to 102311 cards: 1 to 204712 cards: 1 to 409513 cards: 1 to 819114 cards: 1 to 1638315 cards: 1 to 3276716 cards: 1 to 6553517 cards: 1 to 13107118 cards: 1 to 26214319 cards: 1 to 52428720 cards: 1 to 1048575Twenty cards are enough for any number up to a million. Twenty yes-or-no questions pick out one number among more than a million: that is the power of doubling. (Each card would hold 524,288 numbers.) A computer’s memory works the same way: each switch in it is one yes or no, one bit, and every extra bit doubles what can be stored.
Going further still
The guessing game. “I’m thinking of a number from 1 to 100.” Seven cards (1 to 127) find it with seven questions fixed in advance. Binary search, from Grade 8, also needs at most seven, but chooses each question after the last answer (“Is it more than 50?”). Each answer halves the possibilities, and 2 multiplied by itself 7 times, 128, is the first power of 2 above 100.
Three answers instead of two. Suppose each card can say three things: the number is not on it, it is on it in black, or on it in red (counted twice). Then each card is a digit in base 3, and three cards give 3 × 3 × 3 = 27 patterns, 0 to 26. A famous trick of dealing 27 cards into three piles, three times, works in base 3 too (the mathematician Joseph Gergonne worked out why in about 1813, and Martin Gardner wrote about it in Mathematics, Magic and Mystery, 1956). Can you design base-3 cards, with first numbers 1, 3 and 9?
Cards with other first numbers. Do the first numbers have to be powers of two? Challenge ★★★ makes cards that start with 1, 2, 3, 5, 8, 13…, and the trick still works.
Challenges
★ The magician’s helper (blocks)
The program asks for a secret number. Finish it so that it says the row of answers the person would give, Y or N for each card, the 16 card first. For 21 it says YNYNY. Two blocks to put inside are lying ready; you need an if/else and its condition. Then press Test.
★★ Which cards? (Python, from Grade 8)
A magician with as many cards as needed wants to know which cards a number is on. Write cards_for(n) that gives back the first numbers of every card that n is on, smallest first. n can be as big as a million.
def cards_for(n): # give back the first numbers of the cards n is on, smallest first return [] print(cards_for(21))★★★ Fibonacci cards (Python, from Grade 8)
Make cards whose first numbers are 1, 2, 3, 5, 8, 13, 21…, where each is the sum of the two before it. To find the cards a number is on, take the biggest of these that fits into it, then the biggest that fits into what is left, and so on until nothing is left: 20 is 13 + 5 + 2, so 20 goes on the 13, 5 and 2 cards. Write fib_card(f, biggest), which gives back every number from 1 to biggest, smallest first, that is on the card that starts with f.
def fib_card(f, biggest): # give back every number from 1 to biggest that is on the card starting with f return [] print(fib_card(5, 20))Questions
Someone says yes to the cards that start with 16, 8 and 4, and no to the 2 and 1 cards. What is their number?
Pick an answer to see why.
Write down the cards (by their first numbers) that 27 is on, and show how you worked it out.
Answer
A magician wants a trick for any number from 1 to 200. How many cards does she need, and what is the first number on the last one? Explain.
Answer
Your friend says: “The trick works because the magician has memorized all 31 numbers on every card.” Explain to your friend why that is wrong.
Answer
Where to go next
- Grade 6, Zeros and Ones: counting in binary, and the dot cards that work like these.
- Grade 7, How Computers Store Everything: binary both ways, by place values and by halving.
- Grade 8, Searching and Sorting: binary search, the guessing game that halves with every question.
- How do you always win at Nim? Another secret written in binary: a game of stones you can always win.
- How does a barcode catch a typing mistake? An extra digit that spots a mistake: what the card trick can’t do.
