1
00:00:00,040 --> 00:00:02,460
The following content is
provided under a Creative

2
00:00:02,460 --> 00:00:03,870
Commons license.

3
00:00:03,870 --> 00:00:06,910
Your support will help MIT
OpenCourseWare continue to

4
00:00:06,910 --> 00:00:10,560
offer high-quality educational
resources for free.

5
00:00:10,560 --> 00:00:13,460
To make a donation or view
additional materials from

6
00:00:13,460 --> 00:00:19,290
hundreds of MIT courses, visit
MIT OpenCourseWare at

7
00:00:19,290 --> 00:00:20,540
ocw.mit.edu.

8
00:00:22,830 --> 00:00:24,710
ERIC GRIMSON: Good morning.

9
00:00:24,710 --> 00:00:27,980
Professor Guttag has to
be out of town today.

10
00:00:27,980 --> 00:00:29,130
My name's Professor Grimson.

11
00:00:29,130 --> 00:00:30,390
I'm going to be subbing
for him.

12
00:00:30,390 --> 00:00:33,150
And just to show you how much
we value education here at

13
00:00:33,150 --> 00:00:36,920
MIT, and especially in EECS,
you get the incoming

14
00:00:36,920 --> 00:00:38,570
chancellor as a substitute
teacher.

15
00:00:38,570 --> 00:00:40,350
So how cool is that?

16
00:00:40,350 --> 00:00:42,490
All right, maybe
not very cool.

17
00:00:42,490 --> 00:00:43,330
But I'm going to talk
to you anyway

18
00:00:43,330 --> 00:00:46,100
for the next 50 minutes.

19
00:00:46,100 --> 00:00:49,960
At the end of last lecture,
I think Professor Guttag

20
00:00:49,960 --> 00:00:54,760
introduced dictionaries to you,
a really powerful type.

21
00:00:54,760 --> 00:00:58,430
It's got a great capability,
which is it's a tool, a data

22
00:00:58,430 --> 00:01:01,970
type that lets you association
almost any kind of structure

23
00:01:01,970 --> 00:01:03,370
with a key.

24
00:01:03,370 --> 00:01:05,910
So it could be that you're
associating keys with numbers,

25
00:01:05,910 --> 00:01:08,000
you're associating keys
with strings.

26
00:01:08,000 --> 00:01:10,160
But you could be associating
keys with other things,

27
00:01:10,160 --> 00:01:12,046
including dictionaries.

28
00:01:12,046 --> 00:01:14,030
And I don't know if he showed
this to you or not, but those

29
00:01:14,030 --> 00:01:16,770
keys themselves can also
be really powerful.

30
00:01:16,770 --> 00:01:18,820
It could be just a string.

31
00:01:18,820 --> 00:01:23,220
But the key could also be a
tuple, or a list, an x- and

32
00:01:23,220 --> 00:01:25,750
y-coordinate, or a set of
names, or other things.

33
00:01:25,750 --> 00:01:28,740
So it's a really great data
structure to use.

34
00:01:28,740 --> 00:01:33,630
Now, one of the things you could
ask, though, is, gee,

35
00:01:33,630 --> 00:01:37,340
what if Python or whatever
language you're using didn't

36
00:01:37,340 --> 00:01:38,730
come with dictionaries?

37
00:01:38,730 --> 00:01:41,190
Could we still get
the same power?

38
00:01:41,190 --> 00:01:42,050
And the answer is sure.

39
00:01:42,050 --> 00:01:43,510
So I want to show you
a little example.

40
00:01:43,510 --> 00:01:46,390
So on your handout, if we look
at this little procedure up

41
00:01:46,390 --> 00:01:51,090
here at the top, key search, I
could build it out of lists.

42
00:01:51,090 --> 00:01:53,150
I could just use a list as
my way of storing it.

43
00:01:53,150 --> 00:01:54,620
So let's look at what
this procedure.

44
00:01:54,620 --> 00:02:01,340
Says it says, OK, if I've got a
list, and I've got a key, K,

45
00:02:01,340 --> 00:02:04,960
I could write a little loop that
just walks down the list,

46
00:02:04,960 --> 00:02:08,919
saying, is the first part of
each element equal to the key

47
00:02:08,919 --> 00:02:10,620
I'm looking for?

48
00:02:10,620 --> 00:02:14,090
And if it is, I'll return the
second part of that element.

49
00:02:14,090 --> 00:02:16,460
And if I get to the end of the
list, I haven't found it, I

50
00:02:16,460 --> 00:02:18,390
return none.

51
00:02:18,390 --> 00:02:20,540
So notice I'm making
a choice here.

52
00:02:20,540 --> 00:02:23,790
I'm assuming that I'm storing in
the dictionary things that

53
00:02:23,790 --> 00:02:27,880
are lists too long, key and the
associated value, another

54
00:02:27,880 --> 00:02:29,640
key and the associated value,
another key and

55
00:02:29,640 --> 00:02:31,070
the associated value.

56
00:02:31,070 --> 00:02:32,070
But this would work fine.

57
00:02:32,070 --> 00:02:33,150
So if I didn't have
dictionaries,

58
00:02:33,150 --> 00:02:34,750
I could build it.

59
00:02:34,750 --> 00:02:37,030
If I wanted to make things that
had a more complicated

60
00:02:37,030 --> 00:02:38,520
lookup, I'd have to make
sure that that

61
00:02:38,520 --> 00:02:39,740
equality test did it.

62
00:02:39,740 --> 00:02:43,210
But you could see how
I might do it.

63
00:02:43,210 --> 00:02:45,420
So the question then can be,
so why do we bother with

64
00:02:45,420 --> 00:02:48,920
dictionaries, if we could
just use it with lists?

65
00:02:48,920 --> 00:02:50,010
Here's my question to you.

66
00:02:50,010 --> 00:02:52,730
So how long in this
implementation is it going to

67
00:02:52,730 --> 00:02:55,640
take me to figure out if
something's in my dictionary?

68
00:02:58,400 --> 00:03:00,240
Oh my god, he's asking
questions at 10

69
00:03:00,240 --> 00:03:01,130
o'clock in the morning.

70
00:03:01,130 --> 00:03:02,210
This is really terrifying.

71
00:03:02,210 --> 00:03:02,700
Somebody help me out.

72
00:03:02,700 --> 00:03:03,890
How long?

73
00:03:03,890 --> 00:03:05,334
Yeah?

74
00:03:05,334 --> 00:03:07,302
AUDIENCE: Probably on
average on the order

75
00:03:07,302 --> 00:03:09,270
the size of the list.

76
00:03:09,270 --> 00:03:09,762
ERIC GRIMSON: Yeah.

77
00:03:09,762 --> 00:03:12,870
On average, it's going to take
me half the size of the list.

78
00:03:12,870 --> 00:03:14,870
But that's the same thing as
being the size of the list.

79
00:03:14,870 --> 00:03:17,810
So if that list is really
long, I'm toast.

80
00:03:17,810 --> 00:03:19,830
If it's not in the dictionary,
in fact, I'm going to have to

81
00:03:19,830 --> 00:03:22,170
go all the way through the list
before I get to the end

82
00:03:22,170 --> 00:03:23,130
to decide it's not there.

83
00:03:23,130 --> 00:03:27,870
So this is not as efficient an
implementation as we'd like.

84
00:03:27,870 --> 00:03:30,690
Now, the flip that is you say,
OK, how long does it take for

85
00:03:30,690 --> 00:03:33,360
the dictionaries, the built-in
associated retrieval that you

86
00:03:33,360 --> 00:03:35,020
have inside of Python?

87
00:03:35,020 --> 00:03:37,960
And the interesting answer there
is that that retrieval

88
00:03:37,960 --> 00:03:38,720
is constant.

89
00:03:38,720 --> 00:03:42,170
It takes the same amount of time
independent of the size

90
00:03:42,170 --> 00:03:42,800
of the dictionary.

91
00:03:42,800 --> 00:03:45,580
And that's wonderful.

92
00:03:45,580 --> 00:03:47,100
We're not going to talk
about how today.

93
00:03:47,100 --> 00:03:48,610
You're going to see that
later on in the term.

94
00:03:48,610 --> 00:03:51,360
But it is something that drives
home, if you like, the

95
00:03:51,360 --> 00:03:53,010
point that different
data structures

96
00:03:53,010 --> 00:03:54,570
have different costs.

97
00:03:54,570 --> 00:03:56,800
And while some are easier to
implement in, they may not be

98
00:03:56,800 --> 00:03:58,740
as efficient, some may be a
little more difficult to

99
00:03:58,740 --> 00:04:00,570
implement in, but they are
much more efficient.

100
00:04:00,570 --> 00:04:02,450
And that's one of the great
things about dictionaries.

101
00:04:05,270 --> 00:04:07,380
The second thing I think you
saw at the end of last

102
00:04:07,380 --> 00:04:08,990
lecture, and I want to just
highlight in a slightly

103
00:04:08,990 --> 00:04:11,150
different way, is I believe
Professor Guttag showed you a

104
00:04:11,150 --> 00:04:15,110
little example of a very simple
translation function.

105
00:04:15,110 --> 00:04:16,310
We had a little dictionary.

106
00:04:16,310 --> 00:04:18,750
I'm going to give you a version
right here, and

107
00:04:18,750 --> 00:04:19,579
un-comment it.

108
00:04:19,579 --> 00:04:25,150
In fact, there's a little
dictionary that simply

109
00:04:25,150 --> 00:04:27,290
associates English words
with French words.

110
00:04:27,290 --> 00:04:29,160
And yes, it's pretty simple,
but it's a little way of

111
00:04:29,160 --> 00:04:31,340
pairing those things up.

112
00:04:31,340 --> 00:04:35,050
And the idea would be if I have
a sentence just a string

113
00:04:35,050 --> 00:04:37,600
that consists of a bunch of
words, I'd like to translate

114
00:04:37,600 --> 00:04:40,010
that English sentence, if
I can, into French.

115
00:04:40,010 --> 00:04:42,130
And let's look at the code
that's going to do it.

116
00:04:42,130 --> 00:04:43,470
I'm going to, again,
un-comment it here.

117
00:04:43,470 --> 00:04:44,190
It's on your handout.

118
00:04:44,190 --> 00:04:45,570
I want to walk you through it.

119
00:04:49,660 --> 00:04:52,540
So first thing I'm going to do
is actually write a little

120
00:04:52,540 --> 00:04:54,550
procedure the says, given a
word in English, I want to

121
00:04:54,550 --> 00:04:57,040
find the corresponding
word in French.

122
00:04:57,040 --> 00:04:59,020
And that's pretty easy.

123
00:04:59,020 --> 00:05:01,610
It says, if you give me a,
word, and you give me a

124
00:05:01,610 --> 00:05:06,080
dictionary, I'm just going to
look it up in the dictionary.

125
00:05:06,080 --> 00:05:07,670
That's just that associative
retrieval.

126
00:05:07,670 --> 00:05:09,940
It does all the work to go into
the dictionary, say, if

127
00:05:09,940 --> 00:05:12,400
that's a key for something in
the dictionary, it's going to

128
00:05:12,400 --> 00:05:13,770
give it back to me.

129
00:05:13,770 --> 00:05:18,020
And in particular, I can get it
back by simply retrieving

130
00:05:18,020 --> 00:05:20,410
it out of the dictionary.

131
00:05:20,410 --> 00:05:22,410
And notice I'm doing this
a little more carefuly.

132
00:05:22,410 --> 00:05:25,370
I'm not just directly going, and
saying, give me the thing

133
00:05:25,370 --> 00:05:27,490
corresponding to the word in
the dictionary, because it

134
00:05:27,490 --> 00:05:28,600
might not be there.

135
00:05:28,600 --> 00:05:32,530
So that test basically says,
if the word is in the

136
00:05:32,530 --> 00:05:34,540
dictionary, it'll return true.

137
00:05:34,540 --> 00:05:38,270
And in that case, I get out
the corresponding element.

138
00:05:38,270 --> 00:05:40,280
If it's not in the dictionary,
I'm just going to be stuck

139
00:05:40,280 --> 00:05:43,990
with the English words, so we'll
just return the word.

140
00:05:43,990 --> 00:05:45,720
Now, let's look at the
more fun part of it.

141
00:05:45,720 --> 00:05:50,260
I now want to translate
a sentence.

142
00:05:50,260 --> 00:05:54,020
And the sentence is
a string of words.

143
00:05:54,020 --> 00:05:55,970
I need to find where
the words are.

144
00:05:55,970 --> 00:05:57,260
I need to look them up.

145
00:05:57,260 --> 00:06:00,180
I need to gather together
a translation.

146
00:06:00,180 --> 00:06:02,760
So notice what the heart of this
thing does, right down

147
00:06:02,760 --> 00:06:04,800
here in this part of the loop
that I'm going to highlight

148
00:06:04,800 --> 00:06:05,940
right there.

149
00:06:05,940 --> 00:06:06,750
Oops, I mis-did that.

150
00:06:06,750 --> 00:06:11,410
Let me try it again,
right there.

151
00:06:11,410 --> 00:06:13,660
What's that doing?

152
00:06:13,660 --> 00:06:15,510
It's walking down
the sentence.

153
00:06:15,510 --> 00:06:16,800
A sentence is some
big, long string.

154
00:06:16,800 --> 00:06:20,340
And it says for each character
C in the sentence, I need to

155
00:06:20,340 --> 00:06:22,710
find where the word is.

156
00:06:22,710 --> 00:06:26,690
So I'm going to keep walking
along until I find a place

157
00:06:26,690 --> 00:06:28,330
where there's a space.

158
00:06:28,330 --> 00:06:33,490
So that first test there is
saying, if C is not a space,

159
00:06:33,490 --> 00:06:36,010
just add it onto the
end of the word.

160
00:06:36,010 --> 00:06:38,130
Oh, yeah, I need to have
inititalized word, which I did

161
00:06:38,130 --> 00:06:38,820
right up here.

162
00:06:38,820 --> 00:06:41,260
I said, let's set word to
just be an empty string.

163
00:06:41,260 --> 00:06:45,680
So I'm just walking along the
sentence until I find a space.

164
00:06:45,680 --> 00:06:47,640
Until I do that, I'm just
gathering together all of

165
00:06:47,640 --> 00:06:48,230
those characters.

166
00:06:48,230 --> 00:06:49,740
So I'm building up the word.

167
00:06:49,740 --> 00:06:54,540
When I get to the place where
in fact C is a space, then

168
00:06:54,540 --> 00:06:56,370
here's what I'm going to do.

169
00:06:56,370 --> 00:06:59,480
I'm going to translate the word
using that procedure I

170
00:06:59,480 --> 00:06:59,980
just wrote.

171
00:06:59,980 --> 00:07:01,110
It looks it up in
the dictionary.

172
00:07:01,110 --> 00:07:03,160
It either gives me back the
French word, if it's there,

173
00:07:03,160 --> 00:07:05,890
and if not, it just gives me
back the English word.

174
00:07:05,890 --> 00:07:07,680
And, oh yeah, I'm doing
a whole long sentence.

175
00:07:07,680 --> 00:07:08,900
So I need to add it together.

176
00:07:08,900 --> 00:07:12,300
So I'm simply going to add it
to the end of what I've

177
00:07:12,300 --> 00:07:15,070
translated so far.

178
00:07:15,070 --> 00:07:16,910
And I'm doing a slightly
funky thing in there.

179
00:07:16,910 --> 00:07:19,530
I'm inserting a space in
between, just to keep the

180
00:07:19,530 --> 00:07:20,690
words separate.

181
00:07:20,690 --> 00:07:23,960
And of course, I need to have
initialized translation up

182
00:07:23,960 --> 00:07:26,780
here, which I did, to
be an empty string.

183
00:07:26,780 --> 00:07:27,620
So what's this do?

184
00:07:27,620 --> 00:07:29,140
Walks along character
by character.

185
00:07:29,140 --> 00:07:31,250
When it gets to a space, it
says, I've got a word.

186
00:07:31,250 --> 00:07:33,830
Find the translation, add it
to the end of this other

187
00:07:33,830 --> 00:07:36,370
internal variable,
and keep going.

188
00:07:36,370 --> 00:07:39,200
And I'll do that until I get to
the end of that sentence.

189
00:07:39,200 --> 00:07:42,140
And then I'll just return
the translation.

190
00:07:42,140 --> 00:07:44,570
Nice little iterative loop.

191
00:07:44,570 --> 00:07:46,160
And it's simply using
two pieces to

192
00:07:46,160 --> 00:07:47,410
make all of this happen.

193
00:07:50,260 --> 00:07:52,200
I lied too you-- sorry,
I didn't lie.

194
00:07:52,200 --> 00:07:54,410
I misspoke to you.

195
00:07:54,410 --> 00:07:57,640
Which is, what's that funky
thing at the end?

196
00:07:57,640 --> 00:07:58,520
What's it returning?

197
00:07:58,520 --> 00:08:00,770
It's returning this strange
thing this says,

198
00:08:00,770 --> 00:08:04,990
"Translation," starting with the
first element, a copy of

199
00:08:04,990 --> 00:08:10,190
all of that, plus a translation
of the word.

200
00:08:10,190 --> 00:08:14,250
So what assumption am I making
about the inputs that causes

201
00:08:14,250 --> 00:08:16,806
me to do this strange
thing at the end?

202
00:08:16,806 --> 00:08:19,070
I'm actually making two
assumptions about my input.

203
00:08:19,070 --> 00:08:20,810
But I'm making a particular
assumption.

204
00:08:20,810 --> 00:08:24,430
Why do I not just return
translation when I'm done?

205
00:08:24,430 --> 00:08:27,560
Why am I doing this
last piece?

206
00:08:27,560 --> 00:08:29,581
Anybody help me out?

207
00:08:29,581 --> 00:08:32,780
Boy, I notice everybody sits way
back at the back, where I

208
00:08:32,780 --> 00:08:34,030
can't make any eye contact.

209
00:08:38,110 --> 00:08:42,080
How do I characterize
words in my string?

210
00:08:42,080 --> 00:08:44,430
They have to end with a space.

211
00:08:44,430 --> 00:08:48,115
Ooh, is there a space at
the end of my example?

212
00:08:48,115 --> 00:08:50,100
So I guess I haven't shown
you an example.

213
00:08:50,100 --> 00:08:52,260
But I'm assuming if I give you
a sentence, you don't usually

214
00:08:52,260 --> 00:08:54,240
have spaces at the
end of sentences.

215
00:08:54,240 --> 00:08:57,260
So I'm making an assumption, is
that the words, except for

216
00:08:57,260 --> 00:08:59,830
the last one, are characterized
by spaces.

217
00:08:59,830 --> 00:09:03,640
So this last little piece here
is to get the very last word,

218
00:09:03,640 --> 00:09:04,830
and translate it.

219
00:09:04,830 --> 00:09:08,810
Because it won't be a space.

220
00:09:08,810 --> 00:09:10,440
Let's try a couple
of examples.

221
00:09:10,440 --> 00:09:15,760
Let's just un-comment these,
and see if this does it.

222
00:09:15,760 --> 00:09:18,090
Yes, commenting them again
is not a good idea.

223
00:09:18,090 --> 00:09:19,340
We'll go the other direction.

224
00:09:28,130 --> 00:09:30,370
Looks like it did right.

225
00:09:30,370 --> 00:09:32,530
John-- we should have translated
John into Jean.

226
00:09:32,530 --> 00:09:34,650
I don't know what the hell Eric
is in French, but John

227
00:09:34,650 --> 00:09:38,230
mange du pan, Eric
boit du vin.

228
00:09:38,230 --> 00:09:39,050
John has that right.

229
00:09:39,050 --> 00:09:39,760
He's eats bread.

230
00:09:39,760 --> 00:09:41,030
I like to drink wine.

231
00:09:41,030 --> 00:09:45,380
And, of course, tout
le monde aime 6.00.

232
00:09:45,380 --> 00:09:47,680
Or in this case, everyone
likes 6.00.

233
00:09:47,680 --> 00:09:50,680
You just got HASS credit, by the
way, for listening to me

234
00:09:50,680 --> 00:09:53,498
do French really badly.

235
00:09:53,498 --> 00:09:57,390
OK, as I said, I made an
assumption, which that the

236
00:09:57,390 --> 00:09:58,250
words end in spaces.

237
00:09:58,250 --> 00:10:00,582
What's the other assumption
I made here?

238
00:10:00,582 --> 00:10:02,220
I know you're just looking
at the code.

239
00:10:02,220 --> 00:10:04,440
But I made another assumption
inside of my code.

240
00:10:04,440 --> 00:10:05,720
And it's always good
to figure out what

241
00:10:05,720 --> 00:10:09,110
those assumptions are.

242
00:10:09,110 --> 00:10:10,926
Yeah?

243
00:10:10,926 --> 00:10:14,342
AUDIENCE: That the first word is
a noun, so we don't have to

244
00:10:14,342 --> 00:10:15,318
translate it?

245
00:10:15,318 --> 00:10:16,782
ERIC GRIMSON: I didn't
assume that.

246
00:10:16,782 --> 00:10:19,020
I could if I was doing a more
clever translation.

247
00:10:19,020 --> 00:10:20,000
But I'm actually making
no assumptions

248
00:10:20,000 --> 00:10:21,900
linguistically here.

249
00:10:21,900 --> 00:10:23,150
I'll give you a hint.

250
00:10:23,150 --> 00:10:27,390
How many spaces do I
have between words?

251
00:10:27,390 --> 00:10:28,560
Just one.

252
00:10:28,560 --> 00:10:30,440
I'm sort of building that
into this assumption.

253
00:10:30,440 --> 00:10:32,040
It's a reasonable assumption
to make.

254
00:10:32,040 --> 00:10:34,480
But it points out, if I wanted
to improve the code, I should

255
00:10:34,480 --> 00:10:35,700
think about these other cases.

256
00:10:35,700 --> 00:10:37,900
And of course, to build a real
translation system, I'd need

257
00:10:37,900 --> 00:10:39,150
something much more
sophisticated.

258
00:10:42,140 --> 00:10:44,860
So this shows you little
example of using the

259
00:10:44,860 --> 00:10:45,200
dictionaries.

260
00:10:45,200 --> 00:10:47,770
But I want to use this to lead
into the main part of today's

261
00:10:47,770 --> 00:10:50,980
lecture, which is, why did I
write this separate little

262
00:10:50,980 --> 00:10:54,820
procedure up here called
translate word?

263
00:10:54,820 --> 00:10:58,670
I could have buried that
inside the code.

264
00:10:58,670 --> 00:11:02,420
And the answer is twofold.

265
00:11:02,420 --> 00:11:05,910
First one is it saves a
small amount of code.

266
00:11:05,910 --> 00:11:08,790
If I'm going to use it in
multiple places, I don't want

267
00:11:08,790 --> 00:11:11,000
to rewrite the code.

268
00:11:11,000 --> 00:11:13,610
And that actually is valuable,
not just to save you typing.

269
00:11:13,610 --> 00:11:16,355
It means I only have
to debug it once.

270
00:11:16,355 --> 00:11:18,750
It's one piece of code.

271
00:11:18,750 --> 00:11:21,750
But the real reason I wanted to
introduce it is it gives me

272
00:11:21,750 --> 00:11:24,210
what you might think of as
modular abstraction.

273
00:11:24,210 --> 00:11:27,820
Those are fancy words that
basically say I am isolating

274
00:11:27,820 --> 00:11:31,240
that function in one place.

275
00:11:31,240 --> 00:11:35,740
If I decide to change how I'm
going to translate words, I

276
00:11:35,740 --> 00:11:38,440
don't have to search through all
of my code to find all the

277
00:11:38,440 --> 00:11:40,070
places where I was using that.

278
00:11:40,070 --> 00:11:45,140
I just need to change the
definition of that procedure.

279
00:11:45,140 --> 00:11:47,600
And I agree, in a simple example
like this, it looks

280
00:11:47,600 --> 00:11:48,150
pretty simple.

281
00:11:48,150 --> 00:11:50,580
But if you've got a million
lines of code, you're using it

282
00:11:50,580 --> 00:11:53,500
10,000 different places, you
don't want to have to find all

283
00:11:53,500 --> 00:11:54,530
the places to change.

284
00:11:54,530 --> 00:11:59,460
So this is an example of modular
abstraction, isolating

285
00:11:59,460 --> 00:12:00,510
where that thing is.

286
00:12:00,510 --> 00:12:03,500
And that is an example,
in fact, of a general

287
00:12:03,500 --> 00:12:09,770
problem-solving principle we're
going to use, called

288
00:12:09,770 --> 00:12:11,175
divide and conquer.

289
00:12:16,800 --> 00:12:20,370
Divide and conquer is basically
the idea of taking a

290
00:12:20,370 --> 00:12:24,380
hard problem, and breaking it
up into some simpler pieces,

291
00:12:24,380 --> 00:12:26,890
or into smaller problems, where
those smaller problems

292
00:12:26,890 --> 00:12:28,140
have two properties.

293
00:12:33,670 --> 00:12:43,830
Small problems are easier to
solve than the original one.

294
00:12:43,830 --> 00:12:49,070
More importantly, the solutions
to the small

295
00:12:49,070 --> 00:12:54,680
problems can easily
be combined--

296
00:12:54,680 --> 00:12:56,270
I want to stress easily--

297
00:13:00,150 --> 00:13:01,400
to solve the big problem.

298
00:13:14,070 --> 00:13:15,370
And we're going to look
at a bunch of examples

299
00:13:15,370 --> 00:13:17,740
today to show that.

300
00:13:17,740 --> 00:13:20,130
This is a really old idea.

301
00:13:20,130 --> 00:13:21,840
Julius Caesar used it.

302
00:13:21,840 --> 00:13:22,860
He did it in Latin.

303
00:13:22,860 --> 00:13:25,370
My Latin is terrible, but it's
something like divide et

304
00:13:25,370 --> 00:13:28,100
impera, which literally
means divide and rule.

305
00:13:28,100 --> 00:13:30,980
That's how he created
the Roman Empire.

306
00:13:30,980 --> 00:13:32,330
The British knew this
really well.

307
00:13:32,330 --> 00:13:34,300
That's how they control the
Indian subcontinent

308
00:13:34,300 --> 00:13:36,990
brilliantly for several
decades.

309
00:13:36,990 --> 00:13:39,120
Ben Franklin actually knew it.

310
00:13:39,120 --> 00:13:41,270
In particular, he knew how good
the British were at this.

311
00:13:41,270 --> 00:13:42,610
So there's a famous quote.

312
00:13:42,610 --> 00:13:44,640
You may well remember-- when he
signed the Declaration of

313
00:13:44,640 --> 00:13:48,270
Independence, he said, quote,
"We must all hang together, or

314
00:13:48,270 --> 00:13:51,560
assuredly we will hang
separately," meaning divide

315
00:13:51,560 --> 00:13:54,590
and conquer is going to
be a real problem.

316
00:13:54,590 --> 00:13:56,210
So second HASS credit for you.

317
00:13:56,210 --> 00:13:57,780
We just did some history.

318
00:13:57,780 --> 00:13:59,070
Why are we going to
use it today?

319
00:13:59,070 --> 00:14:01,210
Boy, you're a tough audience,
I noticed, by the way.

320
00:14:01,210 --> 00:14:02,800
That's all right.

321
00:14:02,800 --> 00:14:04,880
We're going to use it today,
because we're going to use it

322
00:14:04,880 --> 00:14:06,540
as a tool for problem-solving.

323
00:14:06,540 --> 00:14:10,460
And in particular, we're
going to use it with

324
00:14:10,460 --> 00:14:11,480
one particular example.

325
00:14:11,480 --> 00:14:14,450
You're going to see divide and
conquer later on in the term,

326
00:14:14,450 --> 00:14:17,590
when Professor Guttag talks
about algorithm design.

327
00:14:17,590 --> 00:14:20,380
Today, I'm going to show you one
great technique for doing

328
00:14:20,380 --> 00:14:22,920
divide and conquer kind
of algorithms.

329
00:14:22,920 --> 00:14:24,525
And that is the technique
of recursion.

330
00:14:33,040 --> 00:14:35,060
How many people here have heard
that term used before by

331
00:14:35,060 --> 00:14:37,680
computer scientists?

332
00:14:37,680 --> 00:14:40,310
OK, not to worry.

333
00:14:40,310 --> 00:14:42,040
If you've heard it, you probably
think that it's a

334
00:14:42,040 --> 00:14:45,160
really subtle programming
technique.

335
00:14:45,160 --> 00:14:47,220
I'll let you in on a secret.

336
00:14:47,220 --> 00:14:48,950
That's a PR job.

337
00:14:48,950 --> 00:14:50,890
It's what computer scientists
tell you to make you think

338
00:14:50,890 --> 00:14:53,620
that they're much smarter
than they really are.

339
00:14:53,620 --> 00:14:56,050
It's not subtle, and
it's much more than

340
00:14:56,050 --> 00:14:57,070
a programming technique.

341
00:14:57,070 --> 00:14:59,900
And we're going to
talk about it.

342
00:14:59,900 --> 00:15:03,190
Now, it gets used not just as
a programming technique.

343
00:15:03,190 --> 00:15:05,520
It gets used two other ways
in computer science.

344
00:15:05,520 --> 00:15:08,200
And I'm going to talk
about both.

345
00:15:08,200 --> 00:15:18,320
It's both a way of describing or
defining problems, so it's

346
00:15:18,320 --> 00:15:20,580
a way of characterizing a
problem independent of how we

347
00:15:20,580 --> 00:15:21,960
might implement it.

348
00:15:21,960 --> 00:15:24,225
And it is a way of designing
solutions.

349
00:15:34,440 --> 00:15:36,625
So an example of divide
and conquer.

350
00:15:39,630 --> 00:15:41,612
Let me give you an example just
to show you of why it's a

351
00:15:41,612 --> 00:15:44,600
way of defining a problem.

352
00:15:44,600 --> 00:15:49,080
Consider the part of the legal
code that defines the notion

353
00:15:49,080 --> 00:15:52,355
of a natural-born US citizen,
and remind you, to be eligible

354
00:15:52,355 --> 00:15:55,130
to run for president, which I
hope you all do, you have to

355
00:15:55,130 --> 00:15:57,710
be a natural-born US citizen.

356
00:15:57,710 --> 00:15:59,460
Definition has two parts.

357
00:15:59,460 --> 00:16:02,350
Part number one, anyone born
within the United States is a

358
00:16:02,350 --> 00:16:04,690
natural-born citizen.

359
00:16:04,690 --> 00:16:08,880
Part number two, anyone born
outside the United States,

360
00:16:08,880 --> 00:16:13,050
both of whose parents are
citizens of the United States,

361
00:16:13,050 --> 00:16:15,620
is a natural-born citizen,
as long as one parent has

362
00:16:15,620 --> 00:16:18,520
lived in the US.

363
00:16:18,520 --> 00:16:19,840
A little more complicated.

364
00:16:19,840 --> 00:16:20,620
What does that actually say?

365
00:16:20,620 --> 00:16:21,730
Well, it's got two parts.

366
00:16:21,730 --> 00:16:24,085
And that's what a recursive
definition has.

367
00:16:24,085 --> 00:16:25,925
The first part is simple.

368
00:16:25,925 --> 00:16:29,640
You're born here, natural-born
US citizen.

369
00:16:29,640 --> 00:16:30,850
Notice the second part.

370
00:16:30,850 --> 00:16:33,120
It says, you weren't born here,
you might still be a

371
00:16:33,120 --> 00:16:33,950
natural-born citizen.

372
00:16:33,950 --> 00:16:34,550
But what you have to do?

373
00:16:34,550 --> 00:16:38,110
You have to decide if your
parents are US citizens--

374
00:16:38,110 --> 00:16:40,360
which they could be by having
been born here, but there are

375
00:16:40,360 --> 00:16:42,260
other ways to be naturalized--

376
00:16:42,260 --> 00:16:44,280
and that may require you
determining if your

377
00:16:44,280 --> 00:16:48,970
grandparents are US citizens,
which may require you to-- ah.

378
00:16:48,970 --> 00:16:52,890
So you may have to chain down
several sets of problems.

379
00:16:52,890 --> 00:16:54,620
Those two parts are what exactly
we're going to use

380
00:16:54,620 --> 00:16:56,470
when we talk about recursive
definitions.

381
00:16:56,470 --> 00:16:59,430
There's what we call a base
part, which typically

382
00:16:59,430 --> 00:17:02,450
describes the simplest version
of the problem.

383
00:17:02,450 --> 00:17:08,420
And then there is an inductive
part that tends to describe

384
00:17:08,420 --> 00:17:10,690
how you reduce the problem
to simpler

385
00:17:10,690 --> 00:17:11,810
versions of the same problem.

386
00:17:11,810 --> 00:17:14,079
So in fact, let me write
those both down.

387
00:17:14,079 --> 00:17:15,304
We have--

388
00:17:15,304 --> 00:17:16,780
it's called a base case.

389
00:17:21,970 --> 00:17:26,720
This typically gives
us a direct answer.

390
00:17:26,720 --> 00:17:29,570
It just tells us very simply,
using very simple methods,

391
00:17:29,570 --> 00:17:32,060
whether this is something that
satisfies that recursive

392
00:17:32,060 --> 00:17:33,650
definition.

393
00:17:33,650 --> 00:17:37,350
And there is the recursive
or inductive case.

394
00:17:43,280 --> 00:17:55,360
Here, you reduce to a simpler
version of the same problem,

395
00:17:55,360 --> 00:17:56,835
plus some other simple
operations.

396
00:18:04,400 --> 00:18:06,040
OK, again, a bunch of words.

397
00:18:06,040 --> 00:18:07,290
Let me show you some examples.

398
00:18:09,800 --> 00:18:11,700
I'm going to start with three
or four different examples,

399
00:18:11,700 --> 00:18:13,040
just to show you how
quickly we do this.

400
00:18:13,040 --> 00:18:16,340
What I want you to see in all of
these examples is that when

401
00:18:16,340 --> 00:18:19,080
I describe the problem, I'm
describing it in terms of

402
00:18:19,080 --> 00:18:22,330
what's the simplest case, and
then how do I build solutions

403
00:18:22,330 --> 00:18:25,500
to bigger problems from
solutions to smaller versions

404
00:18:25,500 --> 00:18:27,680
of the same problems?

405
00:18:27,680 --> 00:18:30,060
OK, here's the first case
I'm going to do.

406
00:18:30,060 --> 00:18:34,200
Suppose I tell you I want to
build a little procedure to do

407
00:18:34,200 --> 00:18:37,890
exponentiation, integer
exponents.

408
00:18:37,890 --> 00:18:39,250
I want to compute b to the n.

409
00:18:39,250 --> 00:18:42,120
But I tell you I've got a really
cheap machine, and all

410
00:18:42,120 --> 00:18:43,870
I can do is multiplication.

411
00:18:43,870 --> 00:18:46,820
So I can't use exp.

412
00:18:46,820 --> 00:18:47,540
Mathematician--

413
00:18:47,540 --> 00:18:51,222
a course 18 person would
say, what's b to the n?

414
00:18:51,222 --> 00:18:59,290
That's b times b times
b, n times.

415
00:18:59,290 --> 00:19:00,510
How could I solve this?

416
00:19:00,510 --> 00:19:03,380
Well, recursively, I'd like to
say, suppose I could solve

417
00:19:03,380 --> 00:19:05,950
smaller versions of
the same problem.

418
00:19:05,950 --> 00:19:07,800
And if somebody gave me a
solution to that smaller

419
00:19:07,800 --> 00:19:09,480
version, how would I
build a solution

420
00:19:09,480 --> 00:19:11,210
to the bigger problem?

421
00:19:11,210 --> 00:19:12,880
Oh, that's easy.

422
00:19:12,880 --> 00:19:24,290
That's the same as b times
b to the n minus 1.

423
00:19:24,290 --> 00:19:26,500
All right, I can see you're
all going, well, duh.

424
00:19:26,500 --> 00:19:27,750
I guess that's what
chancellors know.

425
00:19:27,750 --> 00:19:28,820
They're not very bright.

426
00:19:28,820 --> 00:19:30,490
Of course, you know that.

427
00:19:30,490 --> 00:19:32,340
But notice what I did.

428
00:19:32,340 --> 00:19:34,320
I've now reduced it to a simpler
version of the same

429
00:19:34,320 --> 00:19:37,100
problem, recursively.

430
00:19:37,100 --> 00:19:43,090
This basically says I wanted
to solve b to the n.

431
00:19:43,090 --> 00:19:48,050
It's b times b to
the n minus 1.

432
00:19:48,050 --> 00:19:49,080
Oh, yeah, but I've
got to figure out

433
00:19:49,080 --> 00:19:50,710
when to unwrap this.

434
00:19:50,710 --> 00:19:52,430
So there's an if there.

435
00:19:52,430 --> 00:19:57,170
And that's true as long as
n is greater than one--

436
00:19:57,170 --> 00:19:59,120
actually, as long as n
is greater than 0.

437
00:19:59,120 --> 00:20:01,150
We'll do it that way.

438
00:20:01,150 --> 00:20:08,860
And if n is equal to 0, I know
the answer is just 1.

439
00:20:08,860 --> 00:20:11,850
I know you don't believe me,
but that's really cool.

440
00:20:11,850 --> 00:20:12,980
Why is it really cool?

441
00:20:12,980 --> 00:20:13,360
What do I have?

442
00:20:13,360 --> 00:20:15,500
I have a base case.

443
00:20:15,500 --> 00:20:18,140
And if it's equal to 0, I know
the answer right away.

444
00:20:18,140 --> 00:20:22,640
If n is bigger than 0, oh, let's
assume that I've got

445
00:20:22,640 --> 00:20:24,220
somebody who will give
me the solution to

446
00:20:24,220 --> 00:20:25,180
that smaller problem.

447
00:20:25,180 --> 00:20:26,730
When I get it, I can
just use it, do the

448
00:20:26,730 --> 00:20:29,260
multiplication, and I'm done.

449
00:20:29,260 --> 00:20:33,710
And so, in fact, here is a
simple piece of implementation

450
00:20:33,710 --> 00:20:35,720
of that, which I know is not in
your handout, but I'm just

451
00:20:35,720 --> 00:20:39,490
going to show to you, because
I simply want you to see the

452
00:20:39,490 --> 00:20:42,780
form of it.

453
00:20:42,780 --> 00:20:45,455
It's an exact Python
translation

454
00:20:45,455 --> 00:20:47,590
of what I just said.

455
00:20:47,590 --> 00:20:50,690
It says, if I want to take an
exponent of b to the n, if n

456
00:20:50,690 --> 00:20:54,490
is equal to 0, just return 1.

457
00:20:54,490 --> 00:20:59,180
If not, solve a smaller version
of the same problem

458
00:20:59,180 --> 00:21:01,950
right there.

459
00:21:01,950 --> 00:21:04,330
Call to the same procedure,
same function,

460
00:21:04,330 --> 00:21:05,610
but different argument.

461
00:21:05,610 --> 00:21:08,650
And when I get that answer back,
just multiply it by b,

462
00:21:08,650 --> 00:21:11,860
and return that.

463
00:21:11,860 --> 00:21:14,110
This may look a little funky.

464
00:21:14,110 --> 00:21:16,110
This is the kind of thing that
your high school geometry

465
00:21:16,110 --> 00:21:17,900
teacher would rap your knuckles
with, although

466
00:21:17,900 --> 00:21:19,210
they're not allowed to
do that anymore.

467
00:21:19,210 --> 00:21:21,930
You don't define things in
terms of themselves.

468
00:21:21,930 --> 00:21:23,160
This is not geometry.

469
00:21:23,160 --> 00:21:24,210
This is programming.

470
00:21:24,210 --> 00:21:26,720
And this is a perfectly
legal recursive

471
00:21:26,720 --> 00:21:28,380
definition of a problem.

472
00:21:28,380 --> 00:21:33,690
It will stop, because it will
keep unwinding those recursive

473
00:21:33,690 --> 00:21:36,090
calls until it gets down
to the base case.

474
00:21:36,090 --> 00:21:39,050
And I'm going to show you an
example of that in a second.

475
00:21:39,050 --> 00:21:40,845
I want to show you a much nicer
example of recursion.

476
00:21:40,845 --> 00:21:43,190
And again, part of my message
here is when you get a

477
00:21:43,190 --> 00:21:45,550
problem, don't instantly
start writing code.

478
00:21:45,550 --> 00:21:47,570
Think about, how do I break
this down recursively?

479
00:21:47,570 --> 00:21:51,830
So I have brought some very
high-tech tools with me today.

480
00:21:51,830 --> 00:21:53,690
This is my version of the
tower of Hanoi problem.

481
00:21:53,690 --> 00:21:56,820
How many people know the problem
of the tower of Hanoi?

482
00:21:56,820 --> 00:21:57,350
Only a few.

483
00:21:57,350 --> 00:21:59,270
OK, so here's the story.

484
00:21:59,270 --> 00:22:03,460
There's a temple in Hanoi
staffed by a bunch of monks.

485
00:22:03,460 --> 00:22:05,610
In that temple, there
are three tall,

486
00:22:05,610 --> 00:22:07,680
jewel-encrusted spikes.

487
00:22:07,680 --> 00:22:09,510
Mine aren't nearly as fancy.

488
00:22:09,510 --> 00:22:14,170
And there are 64 golden disks,
all of a different size.

489
00:22:14,170 --> 00:22:17,710
Stack starts out on one of those
spikes, and the monks

490
00:22:17,710 --> 00:22:20,230
move one disk at a time.

491
00:22:20,230 --> 00:22:23,870
Their goal is to move the entire
stack of 64 from one

492
00:22:23,870 --> 00:22:27,170
spike to another.

493
00:22:27,170 --> 00:22:29,830
And the rules are they can it
of one disk at a time, but

494
00:22:29,830 --> 00:22:32,210
they can never cover
up a smaller disk

495
00:22:32,210 --> 00:22:34,270
with a larger disk.

496
00:22:34,270 --> 00:22:36,640
I have to tell you, I don't know
what happens when they

497
00:22:36,640 --> 00:22:37,920
move the entire stack.

498
00:22:37,920 --> 00:22:40,880
I mean, the universe ends, or
you all get A's in 600, or

499
00:22:40,880 --> 00:22:43,630
something equally as cool.

500
00:22:43,630 --> 00:22:45,610
Question is, could we write a
piece of code to help the

501
00:22:45,610 --> 00:22:47,342
monks, to tell them
how to move them?

502
00:22:47,342 --> 00:22:48,970
All right, so let's
figure this out.

503
00:22:48,970 --> 00:22:50,430
And I'm going to show
you some examples.

504
00:22:50,430 --> 00:22:54,320
So I'm going to move a
stack of size one.

505
00:22:54,320 --> 00:22:57,110
Well, that's not very hard.

506
00:22:57,110 --> 00:22:58,240
Watch carefully, because
you're going to

507
00:22:58,240 --> 00:22:59,160
write code to do this.

508
00:22:59,160 --> 00:23:01,920
I want to move a stack of size
two, so I've got to just make

509
00:23:01,920 --> 00:23:03,270
sure that I move the
bottom one off.

510
00:23:03,270 --> 00:23:06,530
That's not so hard.

511
00:23:06,530 --> 00:23:08,330
Now, I want to move a
stack of size three.

512
00:23:08,330 --> 00:23:10,550
I've got to be a little more
careful, because I can't cover

513
00:23:10,550 --> 00:23:12,270
up the smaller one with
a larger one.

514
00:23:12,270 --> 00:23:14,981
But that doesn't
look very hard.

515
00:23:14,981 --> 00:23:16,280
Got the solution, right?

516
00:23:16,280 --> 00:23:17,770
Now, we go for stack
of size four.

517
00:23:17,770 --> 00:23:19,885
This one definitely takes a
little bit more care, because

518
00:23:19,885 --> 00:23:21,320
you really can't cover it up.

519
00:23:21,320 --> 00:23:23,650
But as long as you do it right,
you can actually move

520
00:23:23,650 --> 00:23:24,980
the-- oops, and I didn't
do it right.

521
00:23:24,980 --> 00:23:26,880
You've got to move the pieces
in the right way.

522
00:23:26,880 --> 00:23:29,800
I do this for taking money off
of Harvard students in Harvard

523
00:23:29,800 --> 00:23:32,160
Square, by the way.

524
00:23:32,160 --> 00:23:33,420
Got it?

525
00:23:33,420 --> 00:23:34,740
Real easy to see the
solution, right?

526
00:23:34,740 --> 00:23:35,920
You could write code
for that right now.

527
00:23:35,920 --> 00:23:37,660
I'm not going to do five,
but it's really

528
00:23:37,660 --> 00:23:39,360
easy to see the solution.

529
00:23:39,360 --> 00:23:40,610
Yeah.

530
00:23:42,930 --> 00:23:43,530
I blew it, too.

531
00:23:43,530 --> 00:23:46,060
I did one move I had
to backtrack on.

532
00:23:46,060 --> 00:23:49,000
Let's think about this
recursively.

533
00:23:49,000 --> 00:23:51,230
What's the recursive solution?

534
00:23:51,230 --> 00:23:54,560
Break it down into a simpler
problem, or a problem of a

535
00:23:54,560 --> 00:23:56,260
smaller size.

536
00:23:56,260 --> 00:23:58,590
Ah, here's the solution.

537
00:23:58,590 --> 00:24:01,410
To solve this, I've got a stack,
I've got a stack I'm

538
00:24:01,410 --> 00:24:02,920
going to, I've got
a spare stack.

539
00:24:02,920 --> 00:24:03,590
What's the solution?

540
00:24:03,590 --> 00:24:07,690
You take a stack of size n
minus 1, move it onto the

541
00:24:07,690 --> 00:24:09,450
spare stack.

542
00:24:09,450 --> 00:24:10,790
Now I've got a simple problem.

543
00:24:10,790 --> 00:24:13,200
I can always move a
stack of size one.

544
00:24:13,200 --> 00:24:18,550
And then I move a stack of size
n minus 1 to the target.

545
00:24:18,550 --> 00:24:20,500
And, of course, how I move a
stack of size n minus 1?

546
00:24:20,500 --> 00:24:22,560
Well, I just unwrap
it one more.

547
00:24:22,560 --> 00:24:26,970
That's a really easy
explanation, right?

548
00:24:26,970 --> 00:24:30,230
And it's really easy to write
code to do exactly that.

549
00:24:30,230 --> 00:24:33,190
So let me show it to you.

550
00:24:33,190 --> 00:24:34,910
Again, I know this isn't in
your handout, but I just

551
00:24:34,910 --> 00:24:37,060
wanted to see it.

552
00:24:37,060 --> 00:24:39,710
And you could write
this yourself.

553
00:24:39,710 --> 00:24:41,440
I'm going to write a
little procedure

554
00:24:41,440 --> 00:24:43,080
right here called Hanoi.

555
00:24:47,020 --> 00:24:48,570
What are my arguments?

556
00:24:48,570 --> 00:24:49,970
Going to tell how big
a stack there is.

557
00:24:49,970 --> 00:24:50,960
That's m.

558
00:24:50,960 --> 00:24:53,760
And I'm just going to give it
labels, the from stack, the to

559
00:24:53,760 --> 00:24:56,610
stack, and the spare stack.

560
00:24:56,610 --> 00:24:58,880
Look how simple the code is.

561
00:24:58,880 --> 00:25:02,650
Says, if it's a stack of
size 1, just move it.

562
00:25:02,650 --> 00:25:04,040
I'll just print out
the instruction.

563
00:25:04,040 --> 00:25:06,500
Move it from the from
stack to the target

564
00:25:06,500 --> 00:25:08,490
stack, or the to stack.

565
00:25:08,490 --> 00:25:11,610
If it's bigger than
1, what do I do?

566
00:25:11,610 --> 00:25:16,470
I move a stack of size n minus
1 onto the spare stack.

567
00:25:16,470 --> 00:25:19,450
I move a stack of size 1, which
is what's left, onto the

568
00:25:19,450 --> 00:25:20,670
target stack.

569
00:25:20,670 --> 00:25:23,970
And then, I move that stack over
here that's on the spare

570
00:25:23,970 --> 00:25:26,490
stack over to the
target stack.

571
00:25:26,490 --> 00:25:29,100
It's what I just showed
you right there.

572
00:25:29,100 --> 00:25:30,100
OK?

573
00:25:30,100 --> 00:25:31,350
So let's try it.

574
00:25:35,400 --> 00:25:36,900
Yes, I know I still
like French.

575
00:25:36,900 --> 00:25:37,710
We're going to do Hanoi.

576
00:25:37,710 --> 00:25:39,030
Move a stack of size 1.

577
00:25:39,030 --> 00:25:40,670
And we'll just give this
some labels, just

578
00:25:40,670 --> 00:25:44,130
from, to, and spare.

579
00:25:44,130 --> 00:25:44,670
Well, duh.

580
00:25:44,670 --> 00:25:46,540
You just move it there.

581
00:25:46,540 --> 00:25:46,950
All right.

582
00:25:46,950 --> 00:25:49,710
Let's try a stack of size 2.

583
00:25:54,580 --> 00:25:55,920
It's just what I did.

584
00:25:55,920 --> 00:25:57,940
I'm sure you remember that.

585
00:25:57,940 --> 00:25:59,530
Let's be a little more
daring here.

586
00:26:05,060 --> 00:26:06,970
There's the solution to move
a stack of size 5.

587
00:26:06,970 --> 00:26:08,880
I'll let you check
it separately,

588
00:26:08,880 --> 00:26:12,340
make sure it's right.

589
00:26:12,340 --> 00:26:13,530
One of the things you
can also see here--

590
00:26:13,530 --> 00:26:14,410
I'm not going to
talk about it.

591
00:26:14,410 --> 00:26:17,020
You might think about it, ask
your TA in recitation is, how

592
00:26:17,020 --> 00:26:20,070
long does it take to
solve this problem?

593
00:26:20,070 --> 00:26:22,590
How long is it going to take
those monks to actually move a

594
00:26:22,590 --> 00:26:23,850
stack of size 64?

595
00:26:23,850 --> 00:26:25,000
I'll give you a hint.

596
00:26:25,000 --> 00:26:27,880
The answer is measured
in billions of years.

597
00:26:27,880 --> 00:26:29,480
This is an exponential
problem.

598
00:26:29,480 --> 00:26:31,830
And you can see that
growth right away.

599
00:26:31,830 --> 00:26:32,780
That's a separate topic.

600
00:26:32,780 --> 00:26:37,040
But notice coming up with that
solution on your own, maybe

601
00:26:37,040 --> 00:26:37,810
not so easy.

602
00:26:37,810 --> 00:26:41,560
Thinking about it recursively,
very easy to think about.

603
00:26:41,560 --> 00:26:44,440
And that's the way we
want to look at it.

604
00:26:44,440 --> 00:26:48,630
OK, let me give you another
example of breaking a problem

605
00:26:48,630 --> 00:26:53,350
down recursively, and then
writing the code to do.

606
00:26:53,350 --> 00:26:58,730
I want to decide if a sentence
is a palindrome.

607
00:26:58,730 --> 00:27:00,190
Remember what a palindrome is?

608
00:27:00,190 --> 00:27:02,450
It is not an ex-governor
from Alaska.

609
00:27:02,450 --> 00:27:04,500
It is a string of characters--

610
00:27:04,500 --> 00:27:07,450
I guess an airport in Alaska--
it's a string of characters

611
00:27:07,450 --> 00:27:09,240
that have the property
that they read the

612
00:27:09,240 --> 00:27:12,290
same front to back.

613
00:27:12,290 --> 00:27:14,030
The most famous one in English--
which is, of course,

614
00:27:14,030 --> 00:27:16,550
amusing because it's attributed
to a Frenchman-- is

615
00:27:16,550 --> 00:27:21,140
Napoleon supposedly saying,
"Able was I ere I saw Elba."

616
00:27:21,140 --> 00:27:23,270
Same thing back to front.

617
00:27:23,270 --> 00:27:26,330
How would I write a piece of
code to decide if something is

618
00:27:26,330 --> 00:27:28,190
a palindrome?

619
00:27:28,190 --> 00:27:28,990
I'm going to do it
in a second.

620
00:27:28,990 --> 00:27:29,870
You've got it on the handout.

621
00:27:29,870 --> 00:27:32,610
But let's think about
it for a second.

622
00:27:32,610 --> 00:27:34,120
What would the base cases be--

623
00:27:34,120 --> 00:27:36,090
or base case?

624
00:27:36,090 --> 00:27:36,640
Somebody help me out.

625
00:27:36,640 --> 00:27:38,000
What's a good base case here?

626
00:27:41,250 --> 00:27:45,310
What's the shortest possible
sentence I could have?

627
00:27:45,310 --> 00:27:46,520
I?

628
00:27:46,520 --> 00:27:46,980
A?

629
00:27:46,980 --> 00:27:47,440
A?

630
00:27:47,440 --> 00:27:49,050
Don't worry about whether it's
a legal sense of not.

631
00:27:49,050 --> 00:27:50,430
It might need a verb in there.

632
00:27:50,430 --> 00:27:53,480
Base case is presumably, if
I've got a string one

633
00:27:53,480 --> 00:27:56,130
character long, it's
a palindrome.

634
00:27:56,130 --> 00:27:59,120
If I've got a string zero
characters long, it's probably

635
00:27:59,120 --> 00:28:02,550
a palindrome as well.

636
00:28:02,550 --> 00:28:05,940
How would I take a longer string
and break it down into

637
00:28:05,940 --> 00:28:08,420
a simpler version of the same
problem to decide if something

638
00:28:08,420 --> 00:28:09,670
is a palindrome?

639
00:28:11,720 --> 00:28:12,970
Anybody want to help me out?

640
00:28:16,020 --> 00:28:17,680
Is that a hand up there,
or are you just

641
00:28:17,680 --> 00:28:18,930
scratching your head?

642
00:28:20,960 --> 00:28:21,940
Well-- yeah?

643
00:28:21,940 --> 00:28:25,206
AUDIENCE: Maybe take the first
and the last element, see if

644
00:28:25,206 --> 00:28:25,860
they're equal.

645
00:28:25,860 --> 00:28:28,310
If they are, then cut
them off, and--

646
00:28:28,310 --> 00:28:28,800
ERIC GRIMSON: Yeah.

647
00:28:28,800 --> 00:28:30,270
What's a palindrome?

648
00:28:30,270 --> 00:28:32,400
The easy way to start it is take
the things at the end,

649
00:28:32,400 --> 00:28:33,340
first and last character.

650
00:28:33,340 --> 00:28:34,890
If they're not the same, it
doesn't matter what's

651
00:28:34,890 --> 00:28:35,630
happening in the middle.

652
00:28:35,630 --> 00:28:36,890
This thing can't be
a palindrome.

653
00:28:36,890 --> 00:28:38,642
So let's check those.

654
00:28:38,642 --> 00:28:41,950
And oh, yeah, if those are the
same character, and I pull

655
00:28:41,950 --> 00:28:44,005
them off, what do I have?

656
00:28:44,005 --> 00:28:47,290
I have a smaller version
of the same problem.

657
00:28:47,290 --> 00:28:50,150
I have a new sentence that's
now two characters less.

658
00:28:50,150 --> 00:28:51,030
Do the same thing.

659
00:28:51,030 --> 00:28:53,300
Say, is that a palindrome?

660
00:28:53,300 --> 00:28:55,060
So if these characters
match, and that's a

661
00:28:55,060 --> 00:28:55,870
palindrome, I'm done.

662
00:28:55,870 --> 00:28:57,220
How do I tell if that's
a palindrome?

663
00:28:57,220 --> 00:28:59,530
Check if their two end
characters match, and the

664
00:28:59,530 --> 00:29:02,250
things in the middle.

665
00:29:02,250 --> 00:29:05,460
So let's look a little piece of
code to make this happen.

666
00:29:09,090 --> 00:29:12,320
I'm going to do it in
a couple of pieces.

667
00:29:12,320 --> 00:29:13,860
Here's the first piece
I'm going to write.

668
00:29:13,860 --> 00:29:15,110
I'm going to walk
you through it.

669
00:29:18,530 --> 00:29:20,520
First thing I'm going to do is
I'm going to do this outside

670
00:29:20,520 --> 00:29:23,000
of the recursive call is I
need to convert a string

671
00:29:23,000 --> 00:29:24,950
that's put in to make
sure that, in fact,

672
00:29:24,950 --> 00:29:25,770
it's in a form I want.

673
00:29:25,770 --> 00:29:28,300
So I don't care about
the spaces.

674
00:29:28,300 --> 00:29:29,850
Able was I ere I saw Elba.

675
00:29:29,850 --> 00:29:31,290
The spaces aren't in
the same place.

676
00:29:31,290 --> 00:29:31,400
That's OK.

677
00:29:31,400 --> 00:29:33,350
It's really the characters.

678
00:29:33,350 --> 00:29:35,400
And I don't really care
about capitalization.

679
00:29:35,400 --> 00:29:38,560
So this little procedure
basically says, given a

680
00:29:38,560 --> 00:29:42,260
string, convert it all into
lowercase-- and if you haven't

681
00:29:42,260 --> 00:29:45,050
seen that, I'm just importing
from a module called string

682
00:29:45,050 --> 00:29:46,770
some built-in procedures--

683
00:29:46,770 --> 00:29:48,220
and this one simply takes
the string, and

684
00:29:48,220 --> 00:29:50,180
makes it all lowercase.

685
00:29:50,180 --> 00:29:51,150
And then what do I do?

686
00:29:51,150 --> 00:29:53,660
Well, just like we did before,
I'm just going to walk down

687
00:29:53,660 --> 00:29:57,020
that string, gathering
together all of the

688
00:29:57,020 --> 00:29:58,270
characters.

689
00:29:58,270 --> 00:30:01,900
So this little loop just says,
let's initialize ans to be an

690
00:30:01,900 --> 00:30:02,530
empty string.

691
00:30:02,530 --> 00:30:05,910
And then for each character
in s, if it is a lowercase

692
00:30:05,910 --> 00:30:07,790
character-- and that little
test simply does that.

693
00:30:07,790 --> 00:30:11,590
It says, if it's in the set of
lowercase characters I'm going

694
00:30:11,590 --> 00:30:13,050
to add it to the end.

695
00:30:13,050 --> 00:30:15,490
And when I'm done, I'm just
going to return ans.

696
00:30:15,490 --> 00:30:18,424
Going to return the answer.

697
00:30:18,424 --> 00:30:19,490
A little procedure.

698
00:30:19,490 --> 00:30:21,360
And, by the way, this is a
nice piece of programming

699
00:30:21,360 --> 00:30:22,120
style, as well.

700
00:30:22,120 --> 00:30:25,540
I want to separate out things
that I want to do once from

701
00:30:25,540 --> 00:30:27,080
the things I'm going to
call multiple times.

702
00:30:27,080 --> 00:30:30,930
So I don't need to re-check
every time that my string is

703
00:30:30,930 --> 00:30:34,090
all lowercase, I'm just going
to convert it out.

704
00:30:34,090 --> 00:30:39,230
Now, let's look at how
do we test this.

705
00:30:39,230 --> 00:30:45,250
Well, it's literally just a
translation of what we said.

706
00:30:45,250 --> 00:30:46,860
But let's look at the pieces.

707
00:30:46,860 --> 00:30:50,690
It says, if I give you just
a string of characters--

708
00:30:50,690 --> 00:30:52,680
I've gotten rid of the spaces,
I've made it all lowercase--

709
00:30:52,680 --> 00:30:54,330
what does it say to do?

710
00:30:54,330 --> 00:30:55,560
I've got to check for
the base cases.

711
00:30:55,560 --> 00:30:58,060
And here, I'm actually
going to be careful.

712
00:30:58,060 --> 00:30:59,810
We could have discovered
this if we programmed.

713
00:30:59,810 --> 00:31:02,390
There actually are two base
cases here, which is, is the

714
00:31:02,390 --> 00:31:07,620
string of length one, or
is of length zero?

715
00:31:07,620 --> 00:31:09,430
Why would I end up with
two base cases?

716
00:31:09,430 --> 00:31:13,850
Why don't I just check for
a string of length one?

717
00:31:13,850 --> 00:31:14,782
Yeah?

718
00:31:14,782 --> 00:31:17,120
AUDIENCE: [INAUDIBLE]

719
00:31:17,120 --> 00:31:18,040
ERIC GRIMSON: Exactly.

720
00:31:18,040 --> 00:31:20,140
I can have an odd or an even
number of characters.

721
00:31:20,140 --> 00:31:22,850
So as I'm clipping them off the
ends, I might end up with

722
00:31:22,850 --> 00:31:24,450
nothing in the middle,
or I might have one

723
00:31:24,450 --> 00:31:25,200
in the middle exactly.

724
00:31:25,200 --> 00:31:27,040
And we might have discovered it
if we tried programming it.

725
00:31:27,040 --> 00:31:28,670
But right, exactly right.

726
00:31:28,670 --> 00:31:31,470
So I can capture that by just
saying, if the length is less

727
00:31:31,470 --> 00:31:33,010
than or equal to 1, which
gets both of those.

728
00:31:33,010 --> 00:31:36,610
In that case, we know the
palindrome will return true.

729
00:31:36,610 --> 00:31:38,140
Otherwise, what do we do?

730
00:31:38,140 --> 00:31:40,010
Well, we do what the gentleman
over here suggested.

731
00:31:40,010 --> 00:31:43,970
We take the first and the last
character of the string--

732
00:31:43,970 --> 00:31:47,190
again, remind you s with an
index of minus 1 goes

733
00:31:47,190 --> 00:31:49,230
backwards 1, if you like, and
gives me the last character.

734
00:31:49,230 --> 00:31:52,460
If those two characters are the
same, I've now reduced it

735
00:31:52,460 --> 00:31:54,040
to a simpler version of
the same problem.

736
00:31:54,040 --> 00:31:59,360
So I simply say, if that's true,
and everything else is a

737
00:31:59,360 --> 00:32:02,480
palindrome, return true.

738
00:32:02,480 --> 00:32:05,750
Now, if you've not seen this
particular little funky form

739
00:32:05,750 --> 00:32:13,160
right here, that is taking
string s, and saying, give me

740
00:32:13,160 --> 00:32:16,360
a copy of everything starting
with the first--

741
00:32:16,360 --> 00:32:18,320
which means not the
0th element--

742
00:32:18,320 --> 00:32:21,190
and ending with everything up
to, but not including, the

743
00:32:21,190 --> 00:32:22,930
last element.

744
00:32:22,930 --> 00:32:25,130
We'll use this to make copies
of other kinds of lists.

745
00:32:25,130 --> 00:32:27,870
But that's all that's doing, is
saying, give me what's in

746
00:32:27,870 --> 00:32:30,810
that string, throwing away the
first and the last element.

747
00:32:30,810 --> 00:32:32,920
And that gives me exactly the
recursive call I want.

748
00:32:32,920 --> 00:32:34,350
I'm now saying what?

749
00:32:34,350 --> 00:32:37,670
If the first and last character
are the same, and if

750
00:32:37,670 --> 00:32:41,420
what's left over is itself
a palindrome, I'm golden.

751
00:32:44,300 --> 00:32:46,500
Now, let me just wrap
all of that up in a

752
00:32:46,500 --> 00:32:49,440
little piece here.

753
00:32:49,440 --> 00:32:50,690
I'll un-comment this.

754
00:32:53,780 --> 00:32:56,080
Which is simply going to say,
I'm going to print out, or put

755
00:32:56,080 --> 00:32:56,950
a comment in it.

756
00:32:56,950 --> 00:32:58,680
And I'm simply going to put
the two pieces together.

757
00:32:58,680 --> 00:33:01,140
Given a string, I'm going to
convert it into all lowercase

758
00:33:01,140 --> 00:33:01,970
characters.

759
00:33:01,970 --> 00:33:05,450
And then I'm going to check,
is this thing a palindrome?

760
00:33:05,450 --> 00:33:09,985
So again, let's try
some examples.

761
00:33:13,190 --> 00:33:15,730
So we'll pick on Professor
Guttag.

762
00:33:15,730 --> 00:33:17,200
His name is almost
a palindrome.

763
00:33:20,440 --> 00:33:22,650
Not quite.

764
00:33:22,650 --> 00:33:25,860
So we're going to give
him a name change.

765
00:33:25,860 --> 00:33:27,110
It helps if I can type.

766
00:33:37,850 --> 00:33:40,760
Oh, good.

767
00:33:40,760 --> 00:33:43,740
Guttag is not, but Guttug,
whatever that means in German,

768
00:33:43,740 --> 00:33:47,400
is, because the Gs, the Us,
and the Ts all match up.

769
00:33:47,400 --> 00:33:48,270
Oh, and let's see.

770
00:33:48,270 --> 00:33:49,650
Let's try a couple of
other ones here.

771
00:33:49,650 --> 00:33:51,160
And I actually typed these in.

772
00:33:51,160 --> 00:33:54,140
We'll check to see if Napoleon
really was right when he used

773
00:33:54,140 --> 00:33:55,390
his palindrome.

774
00:33:58,250 --> 00:34:00,750
If you can't read this last
one, it says, "Are we not

775
00:34:00,750 --> 00:34:04,290
drawn onward, we few, drawn
onward to--" and I can't read

776
00:34:04,290 --> 00:34:05,540
the tail end of that--

777
00:34:09,980 --> 00:34:20,530
"to new era." And if we try
both of those, they are.

778
00:34:20,530 --> 00:34:24,489
What's my point, you're
wondering.

779
00:34:24,489 --> 00:34:27,820
I solved this problem by simply
breaking it down into

780
00:34:27,820 --> 00:34:29,380
simpler versions of
the same problem.

781
00:34:29,380 --> 00:34:31,670
That's the tool that you want.

782
00:34:31,670 --> 00:34:33,590
If you were just trying to think
about, how do I keep

783
00:34:33,590 --> 00:34:35,810
track of my indices as
I'm walking along?

784
00:34:35,810 --> 00:34:37,239
I'm going to come in from
both ends, so I've

785
00:34:37,239 --> 00:34:38,045
got to add and subtract.

786
00:34:38,045 --> 00:34:39,520
And I got to make sure
I'm checking things.

787
00:34:39,520 --> 00:34:42,159
You could write a nice
iterative loop

788
00:34:42,159 --> 00:34:42,659
that would do it.

789
00:34:42,659 --> 00:34:44,330
Actually, I'll take back
the word nice.

790
00:34:44,330 --> 00:34:46,139
You could write an iterative
loop that would do it.

791
00:34:46,139 --> 00:34:48,810
But it is not crisp, it's not
clean, and it's really

792
00:34:48,810 --> 00:34:50,600
easy to screw up.

793
00:34:50,600 --> 00:34:53,350
Or you could say, let's take
advantage of recursion.

794
00:34:53,350 --> 00:34:55,110
Let's just break it down
into a simpler

795
00:34:55,110 --> 00:34:56,730
version of the same problem.

796
00:34:56,730 --> 00:35:00,310
You'd get a very nice,
simple piece of code.

797
00:35:00,310 --> 00:35:02,530
Now, this may still feel
a little mysterious.

798
00:35:02,530 --> 00:35:04,090
I wouldn't blame
you if it did.

799
00:35:04,090 --> 00:35:06,550
So let's do the following.

800
00:35:09,310 --> 00:35:11,700
I'm going to comment these out
so that we're not constantly

801
00:35:11,700 --> 00:35:12,950
looking at them.

802
00:35:16,448 --> 00:35:18,800
And I'm going to show you what
happens if we actually look

803
00:35:18,800 --> 00:35:20,660
inside of this thing to
see what's going on.

804
00:35:20,660 --> 00:35:21,980
So just give me a second here.

805
00:35:21,980 --> 00:35:23,770
We're going to comment
all of those out.

806
00:35:26,330 --> 00:35:30,820
And let's build a version of
this that just prints out as

807
00:35:30,820 --> 00:35:33,790
we go along.

808
00:35:33,790 --> 00:35:36,560
So I'm going to show
you right here.

809
00:35:40,940 --> 00:35:44,150
It's the same basic pieces.

810
00:35:44,150 --> 00:35:45,550
And actually, I realized
I need to leave

811
00:35:45,550 --> 00:35:46,660
is characters around.

812
00:35:46,660 --> 00:35:50,410
Let me go find my is
characters part--

813
00:35:50,410 --> 00:35:51,430
two characters part.

814
00:35:51,430 --> 00:35:52,870
Sorry, give me a second here.

815
00:35:55,390 --> 00:35:56,640
Going to need that.

816
00:35:58,824 --> 00:36:00,480
So we'll un-comment
that region.

817
00:36:00,480 --> 00:36:02,830
That's just doing the
conversion for us.

818
00:36:02,830 --> 00:36:03,740
I think this is going to work.

819
00:36:03,740 --> 00:36:05,900
Let's look at what
we're doing here.

820
00:36:05,900 --> 00:36:07,200
This is exactly the
same thing.

821
00:36:07,200 --> 00:36:09,580
But I'm just going to put some
print statements in it, which

822
00:36:09,580 --> 00:36:11,380
as I'm sure you've already heard
from Professor Guttag,

823
00:36:11,380 --> 00:36:13,040
is a good thing to do as well.

824
00:36:13,040 --> 00:36:14,260
I want you to see
what happens.

825
00:36:14,260 --> 00:36:18,500
So the only changes I'm making
here are when I come into the

826
00:36:18,500 --> 00:36:20,170
thing that's doing the checking,
I'm going to print

827
00:36:20,170 --> 00:36:22,760
out a little thing that says,
what are you calling me with,

828
00:36:22,760 --> 00:36:25,220
so you can see how
it does the work.

829
00:36:25,220 --> 00:36:28,890
And then, if it's a base case,
I'm going to print out a

830
00:36:28,890 --> 00:36:30,940
statement that says I'm
in the base case.

831
00:36:30,940 --> 00:36:32,940
And otherwise, I'm just going
to print out something that

832
00:36:32,940 --> 00:36:35,960
says, here's what I'm about to
return for the piece of the

833
00:36:35,960 --> 00:36:38,330
string I'm looking at.

834
00:36:38,330 --> 00:36:40,640
So it's just instrumenting, if
you like, what I'm going to do

835
00:36:40,640 --> 00:36:41,320
inside of here.

836
00:36:41,320 --> 00:36:43,800
And the other piece I'm going
to do is I'm going to have a

837
00:36:43,800 --> 00:36:48,410
little space called indent, so
that every time I call a

838
00:36:48,410 --> 00:36:50,040
smaller version of the problem,
I'm just going to

839
00:36:50,040 --> 00:36:55,265
indent over a little bit, so you
can see how it unwraps it.

840
00:36:55,265 --> 00:37:03,110
And if we do this, just
run that through.

841
00:37:03,110 --> 00:37:06,110
Let's try it.

842
00:37:06,110 --> 00:37:12,530
So if I call is palindrome
print with Guttag--

843
00:37:16,780 --> 00:37:19,230
it would really help if I
could type, wouldn't it?

844
00:37:25,900 --> 00:37:27,780
Yes, it would really help
if I could type.

845
00:37:27,780 --> 00:37:29,750
You're all being really polite,
going, ah, he missed a

846
00:37:29,750 --> 00:37:30,460
character there.

847
00:37:30,460 --> 00:37:32,970
But we're not going to tell
him, because he's going to

848
00:37:32,970 --> 00:37:34,320
have to figure it
out for himself.

849
00:37:37,030 --> 00:37:39,470
Administrators cannot
possibly do this.

850
00:37:43,080 --> 00:37:45,760
Ah, notice what it did.

851
00:37:45,760 --> 00:37:47,730
This is how you can see the
recursive unwinding.

852
00:37:47,730 --> 00:37:48,810
It said--

853
00:37:48,810 --> 00:37:50,910
I'm going to check
this thing out.

854
00:37:50,910 --> 00:37:52,520
It said way up there--
actually,

855
00:37:52,520 --> 00:37:53,450
I'll just do it here.

856
00:37:53,450 --> 00:37:57,310
It said, I'm going to call
it initially with Guttag.

857
00:37:57,310 --> 00:38:00,230
Oh, the two Gs worked so
that recursively--

858
00:38:00,230 --> 00:38:02,680
and notice the push-in here--
said, I'm calling it again

859
00:38:02,680 --> 00:38:07,200
with U-T-T-A. Oh, that
one didn't work.

860
00:38:07,200 --> 00:38:10,535
So I didn't have to check any
further, and I pushed it out.

861
00:38:10,535 --> 00:38:21,290
On the other hand, if I do this,
ha, you can see all of

862
00:38:21,290 --> 00:38:21,840
the stages.

863
00:38:21,840 --> 00:38:23,170
You can see it unwinding it.

864
00:38:23,170 --> 00:38:26,860
It says, to decide if Guttug
is a palindrome,

865
00:38:26,860 --> 00:38:27,940
well, I check the ends.

866
00:38:27,940 --> 00:38:30,800
And I've got to check U-T-T-U.
I don't know what that is.

867
00:38:30,800 --> 00:38:32,130
Something interesting.

868
00:38:32,130 --> 00:38:33,510
Which says, I got
to check that.

869
00:38:36,040 --> 00:38:37,950
Which means I've got a check,
oh, there's that base case of

870
00:38:37,950 --> 00:38:39,060
the empty one.

871
00:38:39,060 --> 00:38:41,670
I can now return true-- and I'm
going to open this up so

872
00:38:41,670 --> 00:38:42,760
you can see it--

873
00:38:42,760 --> 00:38:45,160
from the base case, true
for that, true for

874
00:38:45,160 --> 00:38:47,260
that, true for that.

875
00:38:47,260 --> 00:38:51,690
Let's do one last one,
assuming I can type.

876
00:38:51,690 --> 00:38:52,940
I can't.

877
00:39:11,480 --> 00:39:14,130
Well, you get the idea, right?

878
00:39:14,130 --> 00:39:15,400
It's a little messy.

879
00:39:15,400 --> 00:39:17,270
But we go up a little bit,
you can start seeing--

880
00:39:17,270 --> 00:39:18,880
I'm obviously just going to
run out of those pieces

881
00:39:18,880 --> 00:39:20,830
there-- but notice
what it's doing.

882
00:39:20,830 --> 00:39:23,710
It's stripping off each of
those characters in turn.

883
00:39:23,710 --> 00:39:25,730
You can see how deep this goes
in, which is why you've got

884
00:39:25,730 --> 00:39:27,910
all those weird spaces there
as I keep going in.

885
00:39:27,910 --> 00:39:29,430
But it starts off by
saying, look at

886
00:39:29,430 --> 00:39:30,640
that, oh, look at that.

887
00:39:30,640 --> 00:39:31,270
I've got to look at--

888
00:39:31,270 --> 00:39:33,130
[GIBBERISH]

889
00:39:33,130 --> 00:39:35,800
Which says, I've got to
look at [GIBBERISH]

890
00:39:35,800 --> 00:39:36,670
You get the idea.

891
00:39:36,670 --> 00:39:37,910
But notice the key thing.

892
00:39:37,910 --> 00:39:39,750
I'm simply reducing
it to a simpler

893
00:39:39,750 --> 00:39:41,720
version of the same problem.

894
00:39:41,720 --> 00:39:43,620
You can also see that to get
the answer out, I've got to

895
00:39:43,620 --> 00:39:45,580
stack up a whole bunch
of things.

896
00:39:45,580 --> 00:39:48,650
All those indents are basically
held operations,

897
00:39:48,650 --> 00:39:51,920
which is one of the properties
of a recursive procedure.

898
00:39:51,920 --> 00:39:53,970
You have to hold onto
intermediate things.

899
00:39:53,970 --> 00:39:56,020
And that can cause,
in some languages,

900
00:39:56,020 --> 00:39:57,620
some efficiency issues.

901
00:39:57,620 --> 00:39:59,900
But in terms of solving the
problem, this is really easy.

902
00:39:59,900 --> 00:40:01,880
I've just broken it down into
those simple pieces.

903
00:40:01,880 --> 00:40:03,130
And that's really nice.

904
00:40:06,940 --> 00:40:09,130
So let me finish up with
one last example

905
00:40:09,130 --> 00:40:10,360
of a recursive procedure.

906
00:40:10,360 --> 00:40:12,530
Again, my goal here is to let
you see, what am I doing?

907
00:40:12,530 --> 00:40:14,580
I keep repeating this,
but it's important.

908
00:40:14,580 --> 00:40:17,870
To solve a problem, figure out
how to break it down into a

909
00:40:17,870 --> 00:40:20,386
simpler version of
the same problem.

910
00:40:20,386 --> 00:40:26,900
One of the classic examples
of recursion is Fibonacci.

911
00:40:26,900 --> 00:40:29,680
How many people here know
the Fibonacci numbers?

912
00:40:29,680 --> 00:40:31,200
A few more, good.

913
00:40:31,200 --> 00:40:33,650
For those of you who don't,
here's the story.

914
00:40:33,650 --> 00:40:37,260
Probably heard the phrase, "They
breed like rabbits."

915
00:40:37,260 --> 00:40:39,610
It's been used to describe a
population that the speaker

916
00:40:39,610 --> 00:40:42,020
thinks is growing too quickly.

917
00:40:42,020 --> 00:40:42,840
Works with rabbits.

918
00:40:42,840 --> 00:40:44,540
It works if you put two
pennies in a drawer.

919
00:40:44,540 --> 00:40:47,380
There's a whole bunch of ways
in which this happens.

920
00:40:47,380 --> 00:40:49,400
The history of this is
actually very old.

921
00:40:49,400 --> 00:40:54,750
It goes back to 1202, when an
Italian mathematician named

922
00:40:54,750 --> 00:40:58,600
Leonardo of Pisa, also known
as Fibonacci, developed a

923
00:40:58,600 --> 00:41:01,220
formula that he thought would
help him quantify the notion

924
00:41:01,220 --> 00:41:03,860
of how rapidly do
rabbits breed.

925
00:41:03,860 --> 00:41:04,870
And here was his model.

926
00:41:04,870 --> 00:41:06,440
His model is not great, and
we'll see that in a second.

927
00:41:06,440 --> 00:41:07,920
But here's his model.

928
00:41:07,920 --> 00:41:10,310
You start with a newborn
pair of rabbits, one

929
00:41:10,310 --> 00:41:12,390
male and one female.

930
00:41:12,390 --> 00:41:14,360
You put them in a pen.

931
00:41:14,360 --> 00:41:16,780
You assume that rabbits
are able to mate at

932
00:41:16,780 --> 00:41:19,130
the age of one month.

933
00:41:19,130 --> 00:41:21,480
And you further assume that
they have a one-month

934
00:41:21,480 --> 00:41:22,320
gestation period.

935
00:41:22,320 --> 00:41:26,590
So they can produce offspring
at the end of a month.

936
00:41:26,590 --> 00:41:29,250
Finally, let's suppose that
these mythical rabbits never

937
00:41:29,250 --> 00:41:33,770
die and that the female always
produces one new pair--

938
00:41:33,770 --> 00:41:36,020
that is, a male and a female
every month from its

939
00:41:36,020 --> 00:41:37,850
second month on.

940
00:41:37,850 --> 00:41:41,650
The question is, how many female
rabbits will there be

941
00:41:41,650 --> 00:41:44,044
at the end of a year?

942
00:41:44,044 --> 00:41:45,390
Hm.

943
00:41:45,390 --> 00:41:47,190
OK, let's see if we can
figure this out.

944
00:42:02,130 --> 00:42:07,530
OK, at month 0, when it starts
off, there's 1 female rabbit

945
00:42:07,530 --> 00:42:09,490
and 1 male rabbit.

946
00:42:09,490 --> 00:42:13,820
At the end of the first month,
there's still one female

947
00:42:13,820 --> 00:42:17,050
rabbit, but she's
now pregnant.

948
00:42:17,050 --> 00:42:21,340
So there's still 1.

949
00:42:21,340 --> 00:42:24,090
At the end of the second
month, what do we have?

950
00:42:24,090 --> 00:42:26,110
Well, that initial female
is still there.

951
00:42:26,110 --> 00:42:28,830
And she has produced one pair.

952
00:42:28,830 --> 00:42:30,095
So there is a second female.

953
00:42:33,550 --> 00:42:38,260
At the end of the third month,
that initial female has again

954
00:42:38,260 --> 00:42:40,440
been pregnant and
has produced.

955
00:42:40,440 --> 00:42:43,810
And these two are still there.

956
00:42:43,810 --> 00:42:47,060
So there are 3.

957
00:42:47,060 --> 00:42:52,540
At the end of the fourth month,
both of these females

958
00:42:52,540 --> 00:42:54,460
have now produced offspring.

959
00:42:54,460 --> 00:42:57,246
And those 3 females
are now pregnant.

960
00:42:57,246 --> 00:42:58,496
There are 5.

961
00:43:04,020 --> 00:43:08,390
At the end of the fifth
month, those 3 females

962
00:43:08,390 --> 00:43:09,590
have produced offspring.

963
00:43:09,590 --> 00:43:11,560
Those 5 are now pregnant.

964
00:43:11,560 --> 00:43:14,980
There are 8.

965
00:43:14,980 --> 00:43:17,940
And at the end of the sixth
month, there are 13.

966
00:43:21,340 --> 00:43:23,640
What did I just describe?

967
00:43:23,640 --> 00:43:26,435
I just described a nice
recursive relationship.

968
00:43:29,010 --> 00:43:32,110
That says, gee, there ought
to be a base case.

969
00:43:32,110 --> 00:43:35,840
And there ought to be
a recursive case.

970
00:43:35,840 --> 00:43:41,320
And, in fact, in this case, we
can describe this very nicely.

971
00:43:41,320 --> 00:43:48,090
The number of females at month
end is the number of females

972
00:43:48,090 --> 00:43:49,740
there were two months
earlier--

973
00:43:49,740 --> 00:43:51,620
because they've all given
birth, so that's

974
00:43:51,620 --> 00:43:53,440
that many new females--

975
00:43:53,440 --> 00:43:58,960
plus the number of females there
were at the previous

976
00:43:58,960 --> 00:44:03,370
month, who are now
all in whelp.

977
00:44:03,370 --> 00:44:05,790
Ah, that's a recursive
relationship.

978
00:44:05,790 --> 00:44:08,770
If I wanted to figure out how
many females there are at

979
00:44:08,770 --> 00:44:11,840
month end, what do
I have to do?

980
00:44:11,840 --> 00:44:14,380
Well, I just have to say,
what's the base case?

981
00:44:14,380 --> 00:44:15,880
Because there's the
recursive case.

982
00:44:15,880 --> 00:44:19,470
And the base case is--

983
00:44:19,470 --> 00:44:20,190
let me do it this way.

984
00:44:20,190 --> 00:44:26,580
If n is equal to
0 or 1, it's 1.

985
00:44:30,710 --> 00:44:34,300
And as a consequence, I should
be able to figure out how

986
00:44:34,300 --> 00:44:37,400
quickly do rabbits breed, at
least according to 12th

987
00:44:37,400 --> 00:44:41,260
century Italian mathematicians.

988
00:44:41,260 --> 00:44:45,310
A couple of things to notice
here, by the way.

989
00:44:45,310 --> 00:44:47,710
Sort of similar to what I saw
in the towers of Hanoi

990
00:44:47,710 --> 00:44:52,530
problem, I'm going to have
multiple recursive calls.

991
00:44:52,530 --> 00:44:55,950
To solve this problem of size n
over here, I've got to solve

992
00:44:55,950 --> 00:44:59,230
two smaller problems, and then
do the simple operation of

993
00:44:59,230 --> 00:45:00,250
adding them together.

994
00:45:00,250 --> 00:45:01,560
That's OK.

995
00:45:01,560 --> 00:45:03,350
It's going to change the
complexity of my algorithm,

996
00:45:03,350 --> 00:45:06,350
but it's perfectly fine to have
multiple recursive calls.

997
00:45:06,350 --> 00:45:09,330
And as I saw in my case of the
palindrome, I may have more

998
00:45:09,330 --> 00:45:10,370
than one base case.

999
00:45:10,370 --> 00:45:14,100
That's also OK, as long as
I can ground this out.

1000
00:45:14,100 --> 00:45:15,570
All right, so let's
just look at it.

1001
00:45:15,570 --> 00:45:16,940
How would we write this?

1002
00:45:16,940 --> 00:45:21,090
Let me get rid of that,
comment that out.

1003
00:45:21,090 --> 00:45:22,310
We can write a little

1004
00:45:22,310 --> 00:45:25,800
procedure to compute Fibonacci.

1005
00:45:30,090 --> 00:45:30,980
And there's the procedure.

1006
00:45:30,980 --> 00:45:31,740
It's in your handout.

1007
00:45:31,740 --> 00:45:34,080
I've got some things up at the
top here that are just making

1008
00:45:34,080 --> 00:45:36,240
sure that I got the right kinds
of arguments to pass in,

1009
00:45:36,240 --> 00:45:38,300
which is a cleaner, crisp
way of doing it.

1010
00:45:38,300 --> 00:45:39,300
But what do I say?

1011
00:45:39,300 --> 00:45:44,460
I say, if either x is 0 or x
is 1, two base cases, just

1012
00:45:44,460 --> 00:45:47,360
return the answer, which is 1.

1013
00:45:47,360 --> 00:45:50,300
Otherwise, solve two--

1014
00:45:50,300 --> 00:45:51,810
right there--

1015
00:45:51,810 --> 00:45:54,100
smaller sub-problems.

1016
00:45:54,100 --> 00:45:55,440
And what's the simple
operation?

1017
00:45:55,440 --> 00:45:57,830
Just add the two things
together, and return it out.

1018
00:46:00,370 --> 00:46:02,900
And if I do this, we can check
to see if we actually compute

1019
00:46:02,900 --> 00:46:05,260
Fibonacci properly.

1020
00:46:05,260 --> 00:46:08,370
All right, let's do
a test fib of 0.

1021
00:46:11,900 --> 00:46:14,550
It says, ah, fib of 0 is 1.

1022
00:46:14,550 --> 00:46:20,080
To do a test fib of 1-- there's
my other base case.

1023
00:46:20,080 --> 00:46:22,500
Aha, it says, there they go.

1024
00:46:22,500 --> 00:46:27,400
And now, let's do something
a little larger.

1025
00:46:31,180 --> 00:46:31,610
There it is.

1026
00:46:31,610 --> 00:46:35,290
As it gets each computation it's
doing, it says, to get

1027
00:46:35,290 --> 00:46:37,550
fib of 3, I've got to solve
fib of 0, fib of

1028
00:46:37,550 --> 00:46:39,130
1, and fib of 2.

1029
00:46:39,130 --> 00:46:39,970
And there's the answer.

1030
00:46:39,970 --> 00:46:46,480
And just to make sure we're
really doing this well, just

1031
00:46:46,480 --> 00:46:47,990
reproduce my table over there.

1032
00:46:50,740 --> 00:46:52,790
Do I expect you to get all
of that code right away?

1033
00:46:52,790 --> 00:46:54,490
No, although it's pretty
easy to understand.

1034
00:46:54,490 --> 00:46:56,970
What I do expect you to see,
though, is notice what I did.

1035
00:46:56,970 --> 00:47:00,180
I took a recursive problem,
and broke it down

1036
00:47:00,180 --> 00:47:02,170
into simpler pieces.

1037
00:47:02,170 --> 00:47:05,630
And then I used the solutions of
those pieces to give me the

1038
00:47:05,630 --> 00:47:09,150
solution to the larger
problem.

1039
00:47:09,150 --> 00:47:14,330
By the way, Leonardo
Pisa had it wrong.

1040
00:47:14,330 --> 00:47:17,360
In 1859, as I'm sure many
of you know, a wonderful

1041
00:47:17,360 --> 00:47:22,440
Australian farmer named Thomas
Austin imported 24 rabbits

1042
00:47:22,440 --> 00:47:25,610
from England to use as
targets for hunting.

1043
00:47:25,610 --> 00:47:28,670
10 years later there were 2
million rabbits being shot and

1044
00:47:28,670 --> 00:47:30,700
trapped in Australia.

1045
00:47:30,700 --> 00:47:33,650
And fib, while it grows fast,
doesn't go quite that fast.

1046
00:47:33,650 --> 00:47:36,150
So Leonardo of Pisa
had it wrong.

1047
00:47:36,150 --> 00:47:38,350
Of course, as you probably also
know, Australia, and I

1048
00:47:38,350 --> 00:47:41,170
think New Zealand, have the
wonderful property of having

1049
00:47:41,170 --> 00:47:43,440
more sheep than people.

1050
00:47:43,440 --> 00:47:45,340
I don't know what that says,
other than it's a great

1051
00:47:45,340 --> 00:47:47,490
recursive problem.

1052
00:47:47,490 --> 00:47:48,810
Fibonacci, by the way, actually

1053
00:47:48,810 --> 00:47:51,036
shows up in other places.

1054
00:47:51,036 --> 00:47:53,560
Again, it may not be a perfect
model of rabbit populations,

1055
00:47:53,560 --> 00:47:56,270
but it has some other really
interesting properties.

1056
00:47:56,270 --> 00:47:59,640
One of them is, if you let n get
close to infinity, and you

1057
00:47:59,640 --> 00:48:03,110
look at the ratio of fib of
n over fib of n minus 1--

1058
00:48:14,242 --> 00:48:16,110
it sounds like a strange
thing to look at.

1059
00:48:16,110 --> 00:48:17,970
It basically tells you how
quickly does fib grow.

1060
00:48:17,970 --> 00:48:20,346
Does anybody know the
answer to this?

1061
00:48:20,346 --> 00:48:27,210
The golden ratio, 1 plus root
5 over 2, which Leonardo--

1062
00:48:27,210 --> 00:48:29,320
the other Leonardo, the really
good Leonardo-- by the way,

1063
00:48:29,320 --> 00:48:30,650
used to design buildings with.

1064
00:48:30,650 --> 00:48:32,650
So there's a very strange
connection.

1065
00:48:32,650 --> 00:48:35,360
The other one thing I like about
this is that Fibonacci

1066
00:48:35,360 --> 00:48:37,400
shows up, actually,
a lot in nature.

1067
00:48:37,400 --> 00:48:41,400
So, for example, did you know
that the number of petals on

1068
00:48:41,400 --> 00:48:45,330
most flowers is a Fibonacci
number?

1069
00:48:45,330 --> 00:48:48,850
For example, black-eyed
Susans, 13 petals.

1070
00:48:51,560 --> 00:48:55,020
Field daisies, 34 petals.

1071
00:48:55,020 --> 00:48:57,130
You might ask why.

1072
00:48:57,130 --> 00:48:58,190
Oh, sorry.

1073
00:48:58,190 --> 00:48:59,800
I'm out of time.

1074
00:48:59,800 --> 00:49:01,650
I won't answer it today.

1075
00:49:01,650 --> 00:49:04,020
But you can ask Professor Guttag
next time around why it

1076
00:49:04,020 --> 00:49:07,150
is that petals come in
Fibonacci numbers.

1077
00:49:07,150 --> 00:49:09,620
What's the message
of this lecture?

1078
00:49:09,620 --> 00:49:11,840
Recursion, divide and conquer.

1079
00:49:11,840 --> 00:49:13,590
Break a problem down
into simpler

1080
00:49:13,590 --> 00:49:14,930
versions of the same problem.

1081
00:49:14,930 --> 00:49:16,900
Life is really easy.

1082
00:49:16,900 --> 00:49:18,410
And you'll see Professor
Guttag next time.