Skip to content

← Computing Further 6–8

How Does the Mind-Reading Card Trick Work?

Topic 6 · Grades 6–8 · Binary

Binary, from Grade 6; the blocks from Grade 7 (Variables and Choices); the Python parts from Grade 8 (loops, lists and functions).

What this builds on from class
In this unit 8 sections
  1. Try it
  2. How it works
  3. Program it
  4. What your program shows
  5. Going further still
  6. Challenges
  7. Questions
  8. Where to go next

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.

Try it

Read my mind

Think of a number from 1 to 31 and keep it secret. Answer each card honestly: press Yes if your number is on it, No if it isn’t.

Card 1 of 5

135791113151719212325272931
Card 5 ·
Card 4 ·
Card 3 ·
Card 2 ·
Card 1 ·

Think of a number from 1 to 31 and keep it secret. Is it on this card?

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.

Try it

Which cards is it on?

The cards your number is on are outlined, and the row under them shows each card as a 1 (your number is on it) or a 0 (it isn’t).

16171819202122232425262728293031
891011121314152425262728293031
4567121314152021222328293031
2367101114151819222326273031
135791113151719212325272931
16 1
8 0
4 1
2 0
1 1

21 is on the cards that start with 16, 4 and 1: 16 + 4 + 1 = 21. In binary, 21 is 10101.

  • 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.

Try it

The mind reader

Think of a number, press Run, and type yes or no for each card (look at the cards at the top of the page). Watch number grow in the trace table. Then press Test: it tries five secret numbers.

What the program says and asks appears here.

number – no value
card – no value
answer – no value
StepBlocknumbercardanswer
TestShould sayIt said
21Your number is 21
10Your number is 10
1Your number is 1
16Your number is 16
31Your number is 31

Press Run to start the program, or Step to do one block at a time.

Loading the blocks…

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.

Try it

Make a card

Press Run and type 4: does it say the same numbers as the card that starts with 4? Try 1, 8 and 16 too, then press Test.

What the program says and asks appears here.

card – no value
n – no value
numbers – no value
TestShould sayIt said
Card 11 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31
Card 44 5 6 7 12 13 14 15 20 21 22 23 28 29 30 31
Card 88 9 10 11 12 13 14 15 24 25 26 27 28 29 30 31
Card 1616 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

Press Run to start the program, or Step to do one block at a time.

Loading the blocks…

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 1

Read 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.

Try it

The trick with your cards

Press Make the cards, then think of a number from 1 to 63. When you have played, press Check every number: the page plays the trick with your cards for all 63 secret numbers and counts how many it gets right. Then change make_card (try == 0 instead of == 1) and see what happens to the trick.

Card 1 of 6

No cards yet

Card 6 ·
Card 5 ·
Card 4 ·
Card 3 ·
Card 2 ·
Card 1 ·

Press Make the cards: the page calls your make_card once for each card, then does the trick with what it gives back.

Numbers the trick finds
—
First number it gets wrong
—

What your make_card prints, and any error, appears here.

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 1048575

Twenty 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.

A black-and-white photo of Claude Shannon, a man with graying hair in a dark suit, in front of a tall rack of electronic equipment
Figure 6.1 Claude Shannon, who counted information in bits. Photo: Konrad Jacobs, CC BY-SA 2.0 de

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.

Try it

★ The magician’s helper

What the program says and asks appears here.

n – no value
row – no value
card – no value
StepBlocknrowcard
TestShould sayIt said
21YNYNY
10NYNYN
1NNNNY
16YNNNN
31YYYYY

Press Run to start the program, or Step to do one block at a time.

Loading the blocks…

Hint
Answer

★★ 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))

Try it

★★ Which cards?

  1. 21 cards_for(21) Should give [1, 4, 16] Yours —
  2. 1000 cards_for(1000) Should give [8, 32, 64, 128, 256, 512] Yours —
Tests passed
— / 8
Challenge
★★ solved

Write your cards_for in the program above (Edit), then check it.

A test your function gets wrong, anything it prints, and any error appear here.

Hint
Answer

★★★ 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))

Try it

★★★ Fibonacci cards

  1. The 5 card, up to 20 fib_card(5, 20) Should give [5, 6, 7, 18, 19, 20] Yours —
  2. The 13 card, up to 20 fib_card(13, 20) Should give [13, 14, 15, 16, 17, 18, 19, 20] Yours —
Tests passed
— / 9
Challenge
★★★ solved

Write your fib_card in the program above (Edit), then check it.

A test your function gets wrong, anything it prints, and any error appear here.

Hint
Another hint
Answer

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.

a.

Write down the cards (by their first numbers) that 27 is on, and show how you worked it out.

Answer
b.

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
c.

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