WEBVTT

00:00:05.796 --> 00:00:09.170
SRINI DEVADAS: We're going to
do something quite different

00:00:09.170 --> 00:00:10.860
in terms of a puzzle.

00:00:10.860 --> 00:00:16.550
And while it's a
recursive puzzle,

00:00:16.550 --> 00:00:21.810
it's going to play out to
be a recursive solution.

00:00:21.810 --> 00:00:27.559
It looks quite different
from the N-queens puzzle.

00:00:27.559 --> 00:00:29.350
And so this is going
to be a tiling puzzle.

00:00:34.570 --> 00:00:36.320
And so I set up the
puzzle, and then we're

00:00:36.320 --> 00:00:42.440
going to take a little segue
off into a canonical recursive

00:00:42.440 --> 00:00:45.310
algorithm called merge
sort because I think

00:00:45.310 --> 00:00:49.790
it's good for you to see that
algorithm before you dive

00:00:49.790 --> 00:00:51.470
into solving this
particular puzzle

00:00:51.470 --> 00:00:53.630
because it kind of
shows you the way.

00:00:53.630 --> 00:00:56.950
All right, and but
I'll set up the puzzle.

00:00:56.950 --> 00:00:59.660
I guess I didn't have
to erase this square.

00:00:59.660 --> 00:01:05.900
It's a courtyard
that has a bunch--

00:01:05.900 --> 00:01:06.470
of tiles.

00:01:06.470 --> 00:01:11.960
You're supposed to tile it,
and it's all square tiles.

00:01:11.960 --> 00:01:18.438
And I'll just make it eight
by eight like a chessboard.

00:01:21.782 --> 00:01:23.240
And in general, we
are going to say

00:01:23.240 --> 00:01:31.177
that this is a 2 raised to n
by 2 raised to n courtyard.

00:01:35.000 --> 00:01:40.210
And I want to tile
this courtyard.

00:01:47.790 --> 00:01:49.800
So this is a three tile--

00:01:49.800 --> 00:01:53.130
some people call it a tromino.

00:01:53.130 --> 00:01:56.250
You can think of it's
really an L-shaped tile,

00:01:56.250 --> 00:01:59.550
and it can be oriented
in any different way.

00:01:59.550 --> 00:02:03.080
It could be an
inverted L, et cetera.

00:02:03.080 --> 00:02:09.020
And you're supposed to tile this
courtyard using L-shaped tiles

00:02:09.020 --> 00:02:13.590
or trominos.

00:02:13.590 --> 00:02:15.530
And they're called
trominos because there's

00:02:15.530 --> 00:02:18.320
three tiles in there--
three squares in there.

00:02:18.320 --> 00:02:22.080
And so that's your job.

00:02:22.080 --> 00:02:25.710
I guess kind of a weird
job, but this is a puzzle.

00:02:25.710 --> 00:02:28.500
And so you're out there with 2
raised to n by 2 raised to n.

00:02:28.500 --> 00:02:30.840
And all you have are
these L-shaped tiles,

00:02:30.840 --> 00:02:32.460
and you're not
allowed to break them.

00:02:32.460 --> 00:02:36.300
If you break them, then that's
not considered a valid tiling.

00:02:36.300 --> 00:02:39.480
That's bad, and that's your job.

00:02:42.840 --> 00:02:46.100
Oh, and obviously, it
needs to look like this,

00:02:46.100 --> 00:02:48.180
and these look like the floor.

00:02:48.180 --> 00:02:52.200
Maybe you'd like to see
the markings because these

00:02:52.200 --> 00:02:53.900
are tiles, after all.

00:02:53.900 --> 00:02:56.100
But you can't have
something that is uneven.

00:02:56.100 --> 00:02:58.350
You can't have a tile
on top of another tile.

00:02:58.350 --> 00:03:00.150
That's a definite no-no.

00:03:00.150 --> 00:03:04.710
And you can't not have a tile
in any part of the courtyard.

00:03:04.710 --> 00:03:07.500
So I think that was
kind of obvious,

00:03:07.500 --> 00:03:10.770
but it's worth
explicitly stating just

00:03:10.770 --> 00:03:14.780
so you don't get confused here.

00:03:14.780 --> 00:03:21.750
So that's the question that
we're going to try and answer.

00:03:21.750 --> 00:03:28.200
But as I said, I want to talk
about something a little bit

00:03:28.200 --> 00:03:30.510
different for about
5 or 10 minutes

00:03:30.510 --> 00:03:32.910
and actually show you
some code because I

00:03:32.910 --> 00:03:35.760
want to introduce
this notion that's

00:03:35.760 --> 00:03:40.140
a little bit different from the
N-queens recursive paradigm.

00:03:40.140 --> 00:03:44.310
It is recursive, but it's called
recursive divide and conquer.

00:03:44.310 --> 00:03:48.450
And usually, when we use
the term recursive divide

00:03:48.450 --> 00:03:52.200
and conquer, you might think
that it's applicable, even

00:03:52.200 --> 00:03:54.250
to the N-queens recursive code.

00:03:54.250 --> 00:03:58.260
But from a technical
term standpoint

00:03:58.260 --> 00:04:01.130
when we say recursive
divide and conquer,

00:04:01.130 --> 00:04:04.950
we're really saying that
we're taking the problem,

00:04:04.950 --> 00:04:12.200
and we are dividing it
up into smaller problems.

00:04:12.200 --> 00:04:13.950
So you take the problem,
and you divide it

00:04:13.950 --> 00:04:17.370
into two problems that are half
the size or three problems that

00:04:17.370 --> 00:04:19.850
are a third of the
size et cetera.

00:04:19.850 --> 00:04:22.470
Which is not what happened
in the case of the N-queens

00:04:22.470 --> 00:04:23.640
problem.

00:04:23.640 --> 00:04:26.370
And in the case of the N-queens
problem, you took a column,

00:04:26.370 --> 00:04:29.430
and you actually did
iterations on the column.

00:04:29.430 --> 00:04:32.250
So it potentially
exploded on you.

00:04:32.250 --> 00:04:35.030
And then you had a problem
that is slightly smaller

00:04:35.030 --> 00:04:36.530
than the N-queens.

00:04:36.530 --> 00:04:39.810
It was effectively
n minus 1 queens.

00:04:39.810 --> 00:04:44.880
And so it's not n over 2
or n over 2 or 3-- n over 3

00:04:44.880 --> 00:04:49.470
in the case of a three-way
recursive divide and conquer.

00:04:49.470 --> 00:04:51.610
So there's a
qualitative difference.

00:04:51.610 --> 00:04:55.050
And there's also a quantitative
difference in the sense

00:04:55.050 --> 00:04:58.110
that these kinds
of algorithms are

00:04:58.110 --> 00:05:01.140
going to be efficient
in that they are going

00:05:01.140 --> 00:05:04.410
to run very quickly
in polynomial time,

00:05:04.410 --> 00:05:05.820
perhaps quadratic time.

00:05:05.820 --> 00:05:10.440
We can do some analysis for both
of the merge sort that we're

00:05:10.440 --> 00:05:12.300
going to do now
and for the tiling

00:05:12.300 --> 00:05:14.190
puzzle, once we get to that.

00:05:14.190 --> 00:05:17.560
But that's something
to keep in mind.

00:05:17.560 --> 00:05:23.700
So merge sort is the
canonical recursive divide

00:05:23.700 --> 00:05:25.350
and conquer approach.

00:05:25.350 --> 00:05:27.950
And I'll put up code
for it, but I'm not

00:05:27.950 --> 00:05:28.950
going to show it to you.

00:05:28.950 --> 00:05:30.900
You can look at
it in the website.

00:05:30.900 --> 00:05:33.570
But I'm going to
describe the algorithm

00:05:33.570 --> 00:05:38.360
to you using a trivial example.

00:05:38.360 --> 00:05:45.760
And so I want to sort these
numbers in ascending order.

00:05:48.590 --> 00:05:50.290
So I have these four
numbers that I want

00:05:50.290 --> 00:05:52.100
to sort in ascending order.

00:05:52.100 --> 00:05:54.730
And obviously, I could do
this many different ways.

00:05:54.730 --> 00:05:56.750
We looked at selection sort.

00:05:56.750 --> 00:06:00.880
But this is a large
array, and I want

00:06:00.880 --> 00:06:03.730
to do something more efficient
than that quadratic algorithm

00:06:03.730 --> 00:06:04.990
and n squared algorithm.

00:06:04.990 --> 00:06:07.510
And merge sort, which is
recursive divide and conquer,

00:06:07.510 --> 00:06:08.740
fits the bill.

00:06:08.740 --> 00:06:11.494
And what merge sort says is
I'm going to split the array.

00:06:11.494 --> 00:06:12.910
I'm just going to
take this array,

00:06:12.910 --> 00:06:16.352
and I'm going to split it
up into two sub-arrays.

00:06:16.352 --> 00:06:18.310
And I could do this
recursively, but let's just

00:06:18.310 --> 00:06:19.779
talk about the first step.

00:06:19.779 --> 00:06:21.820
So I'm going to go ahead
and split this array up,

00:06:21.820 --> 00:06:23.650
and I have 76 and 32.

00:06:23.650 --> 00:06:29.830
And I'm going to call merge
sort on this smaller array.

00:06:29.830 --> 00:06:32.080
And the first thing
that merge sort does

00:06:32.080 --> 00:06:36.070
is split the array up
into something smaller,

00:06:36.070 --> 00:06:38.740
and you end up getting that.

00:06:38.740 --> 00:06:43.570
So this is the first thing,
and that's the first split.

00:06:43.570 --> 00:06:46.420
And then you end up
splitting 48 and 32,

00:06:46.420 --> 00:06:52.520
and I'm sorry-- or
12, 76, 32, 48, 12.

00:06:52.520 --> 00:06:55.100
Yep, I got that right.

00:06:55.100 --> 00:06:57.437
And so far, you've done nothing.

00:06:57.437 --> 00:06:59.270
I mean, you've just
sort of broken things up

00:06:59.270 --> 00:07:03.140
and turned this into four
one arrays or one list

00:07:03.140 --> 00:07:04.610
or what have you.

00:07:04.610 --> 00:07:07.670
But then the fun
starts where after you

00:07:07.670 --> 00:07:11.930
do the split, after you
return, and so 76 as singleton

00:07:11.930 --> 00:07:14.087
is trivially sorted so
there's no work to do.

00:07:14.087 --> 00:07:15.920
So there's no more
splits that you could do.

00:07:15.920 --> 00:07:17.450
There's nothing
that says you can--

00:07:17.450 --> 00:07:20.520
I mean, 76 is a monolithic
element in their array,

00:07:20.520 --> 00:07:22.020
so you can't do
anything with it.

00:07:22.020 --> 00:07:23.550
And so you just leave it be.

00:07:23.550 --> 00:07:25.910
And the same thing with
32, and so on and so forth.

00:07:25.910 --> 00:07:29.420
But after your two
calls return, you

00:07:29.420 --> 00:07:31.920
have to merge the two together.

00:07:31.920 --> 00:07:34.370
And the way you merge
the two together--

00:07:34.370 --> 00:07:37.520
the invariant here is that when
you merge the two together,

00:07:37.520 --> 00:07:39.470
they have to be
sorted in the order

00:07:39.470 --> 00:07:42.520
that you want the overall
array to be sorted,

00:07:42.520 --> 00:07:44.450
which is ascending order.

00:07:44.450 --> 00:07:46.940
So in this case, you
have down at the bottom,

00:07:46.940 --> 00:07:50.000
it's trivial code because
you have two singleton lists.

00:07:50.000 --> 00:07:52.160
And you just decide
which order they go into.

00:07:52.160 --> 00:07:56.140
OK, so the merge, in this
case, would simply be produced,

00:07:56.140 --> 00:07:58.580
you would produce 32 and 76.

00:07:58.580 --> 00:08:03.140
OK, and in this case, the
merger produced 12 and 48.

00:08:03.140 --> 00:08:08.600
So at this level, you're going
to return 32 and 76 back.

00:08:08.600 --> 00:08:10.970
You're going to
return 32 and 76 back.

00:08:10.970 --> 00:08:14.060
And here you're going to
return 12 and 48 back.

00:08:14.060 --> 00:08:16.700
Now it gets a little
more interesting.

00:08:16.700 --> 00:08:18.980
Now it gets a little more
interesting because now you

00:08:18.980 --> 00:08:23.780
have 32 and 76 and 12 and
48, and those are both

00:08:23.780 --> 00:08:25.580
sorted in ascending
order, and you

00:08:25.580 --> 00:08:27.770
need to merge them together.

00:08:27.770 --> 00:08:31.460
And so if you had
a 128 element list,

00:08:31.460 --> 00:08:33.392
you would go, go,
go all the way down,

00:08:33.392 --> 00:08:34.850
and then you would
do some merging.

00:08:34.850 --> 00:08:39.950
Come up all the way and then the
most time-consuming step really

00:08:39.950 --> 00:08:43.940
would be taking two
64 element lists

00:08:43.940 --> 00:08:46.520
that the left one is
in ascending order,

00:08:46.520 --> 00:08:48.380
and the right one is
in descending order.

00:08:48.380 --> 00:08:50.300
And then you need to
merge them together

00:08:50.300 --> 00:08:53.180
so the result is
in ascending order.

00:08:53.180 --> 00:08:55.190
That makes sense?

00:08:55.190 --> 00:08:57.726
And so in this
case, the way we're

00:08:57.726 --> 00:08:59.780
going to do this
is if you have--

00:08:59.780 --> 00:09:06.380
and I can do this for this
example or a different example.

00:09:06.380 --> 00:09:13.250
But I'll just stick with 32,
76, and this could be larger.

00:09:13.250 --> 00:09:15.210
This is 12 and 48.

00:09:15.210 --> 00:09:18.530
So I need to merge these two
to produce in ascending order.

00:09:18.530 --> 00:09:21.440
And we use a
straightforward algorithm

00:09:21.440 --> 00:09:24.140
that's called the
two-finger algorithm, which

00:09:24.140 --> 00:09:26.840
says I'm going to start
with my fingers pointing

00:09:26.840 --> 00:09:31.160
to the beginning
of the two arrays,

00:09:31.160 --> 00:09:35.270
and I'm going to choose
the element that's smaller.

00:09:35.270 --> 00:09:39.260
And I'm going to write
it into my output array.

00:09:39.260 --> 00:09:41.300
So I'm going to
compare 32 and 12.

00:09:41.300 --> 00:09:43.690
12 is smaller, so I'm
going to write 12 down.

00:09:43.690 --> 00:09:45.980
And because I picked
12 from this array,

00:09:45.980 --> 00:09:48.710
and I didn't pick 32, I'm going
to leave my top finger where

00:09:48.710 --> 00:09:51.380
it is, and I'm going to
move my bottom finger--

00:09:51.380 --> 00:09:54.860
my right-hand finger--
over to the next element.

00:09:54.860 --> 00:09:57.770
And then I'm going to compare
32 with 48 because this finger

00:09:57.770 --> 00:09:58.579
didn't move.

00:09:58.579 --> 00:10:00.620
And I'm going to figure
out which one is smaller,

00:10:00.620 --> 00:10:01.410
and it's 32.

00:10:01.410 --> 00:10:03.180
And I'm going to
put that over here.

00:10:03.180 --> 00:10:05.930
And then I'm going to move this
finger because I took away 32.

00:10:05.930 --> 00:10:11.941
And then at this 48 is smaller,
and then I'm off this way,

00:10:11.941 --> 00:10:13.190
assuming the array ended here.

00:10:13.190 --> 00:10:14.720
But if it didn't, I keep going.

00:10:14.720 --> 00:10:18.760
And then the last thing
I do is put 76 down.

00:10:18.760 --> 00:10:22.120
So that is a recursive
divide and conquer algorithm.

00:10:22.120 --> 00:10:25.140
It's the simplest
algorithm I can think of,

00:10:25.140 --> 00:10:28.780
and that is still interesting.

00:10:28.780 --> 00:10:30.920
I'll show you code for it.

00:10:30.920 --> 00:10:35.470
I'm not going to explain it.

00:10:35.470 --> 00:10:37.570
It is worth looking
at the overall code.

00:10:37.570 --> 00:10:40.240
And then the merge, which is
this two-finger algorithm,

00:10:40.240 --> 00:10:42.220
is actually the
most amount of code.

00:10:42.220 --> 00:10:45.700
But the split itself,
as you can see, is you

00:10:45.700 --> 00:10:48.640
see as with our
recursion, we say

00:10:48.640 --> 00:10:50.380
we want to have a base case.

00:10:50.380 --> 00:10:53.117
And so when the length
of the list becomes 2,

00:10:53.117 --> 00:10:54.700
I'm just going to
do that little flip.

00:10:54.700 --> 00:10:56.440
This is a sorting
algorithm that only

00:10:56.440 --> 00:10:58.740
works for a list of length 2.

00:10:58.740 --> 00:11:01.300
But the beauty of this is
that I can keep going down

00:11:01.300 --> 00:11:03.300
to get smaller
and smaller lists,

00:11:03.300 --> 00:11:05.440
such that the sorting
algorithm actually works.

00:11:05.440 --> 00:11:06.310
And this is it.

00:11:06.310 --> 00:11:09.790
This is a fine sorting
algorithm for a base case.

00:11:09.790 --> 00:11:11.800
And we do have a base case here.

00:11:11.800 --> 00:11:16.250
We also have the other property
that I'm actually calling.

00:11:16.250 --> 00:11:19.630
I'm making two recursive calls
with significantly smaller

00:11:19.630 --> 00:11:20.470
problems.

00:11:20.470 --> 00:11:22.390
In this case, I'm
using list splicing

00:11:22.390 --> 00:11:23.932
to get the first
part of the list

00:11:23.932 --> 00:11:26.140
and the second part of the
list, and I'm just calling

00:11:26.140 --> 00:11:29.380
merge sort on those two lists.

00:11:29.380 --> 00:11:33.340
And then finally, the
workhorse in merge sort

00:11:33.340 --> 00:11:35.212
is the merge step--
this two finger thing

00:11:35.212 --> 00:11:36.420
that I just described to you.

00:11:36.420 --> 00:11:38.410
That is this merge thing.

00:11:38.410 --> 00:11:40.010
And this merge thing,
as you can see--

00:11:40.010 --> 00:11:41.830
there's not a lot of code.

00:11:41.830 --> 00:11:46.930
But it's doing this movement
and the comparisons.

00:11:46.930 --> 00:11:50.670
And that's essentially
what you have there.

00:11:50.670 --> 00:11:52.870
So given that context--

00:11:52.870 --> 00:11:59.260
right given that context, let's
go back to our tiling puzzle.

00:11:59.260 --> 00:12:03.070
And let's talk about this
tiling puzzle and how we could

00:12:03.070 --> 00:12:05.920
we could solve
this tiling puzzle.

00:12:05.920 --> 00:12:10.060
So you're going to break
this courtyard up clearly

00:12:10.060 --> 00:12:11.650
because that's
really what I've been

00:12:11.650 --> 00:12:14.470
trying to tell you in terms of
recursive divide and conquer.

00:12:14.470 --> 00:12:19.660
First question-- look
at this 2 raised to n,

00:12:19.660 --> 00:12:23.140
and 2 raised to n, and
look at this three tile.

00:12:23.140 --> 00:12:26.290
I am going to ask
you the question.

00:12:26.290 --> 00:12:30.340
Is there a solution
that is a perfect tiling

00:12:30.340 --> 00:12:37.150
with no overlapping tiles and
no squares with holes in them?

00:12:37.150 --> 00:12:38.110
Is someone?

00:12:41.860 --> 00:12:43.970
Fadi had his hand up first.

00:12:43.970 --> 00:12:45.029
Go for it.

00:12:45.029 --> 00:12:47.445
AUDIENCE: Well, if we look at
the case of n is equal to 1,

00:12:47.445 --> 00:12:50.550
you have a two by two
courtyard, then it's impossible,

00:12:50.550 --> 00:12:52.422
you can see that trivially.

00:12:52.422 --> 00:12:58.865
But in a general case, then we
will have 2 to the 2n squares.

00:12:58.865 --> 00:13:01.568
And every time we're adding
3, 3, 3, the number of tiles

00:13:01.568 --> 00:13:04.452
is a multiple of 3.

00:13:04.452 --> 00:13:05.410
SRINI DEVADAS: Correct.

00:13:05.410 --> 00:13:09.290
So 2 to the 2n-- and Josh
probably had the same answer--

00:13:09.290 --> 00:13:12.020
2 to the 2n is not
a multiple of 3.

00:13:12.020 --> 00:13:14.080
The only thing that
divides it is 2.

00:13:20.940 --> 00:13:23.420
So OK so we're going
to change the problem.

00:13:23.420 --> 00:13:25.350
We're going to say
that there's a statue

00:13:25.350 --> 00:13:31.570
of your favorite person that
is going to be out here.

00:13:31.570 --> 00:13:35.900
And so you don't
need to tile that.

00:13:35.900 --> 00:13:44.790
So now you have 2
raised to 2n minus 1

00:13:44.790 --> 00:13:47.850
let me write that out properly.

00:13:47.850 --> 00:13:50.760
2 raised to 2n minus 1 squares.

00:13:56.560 --> 00:14:01.900
Now can you do this for all n?

00:14:01.900 --> 00:14:05.350
Clearly, it works
for n equals 1.

00:14:05.350 --> 00:14:07.480
And then for n equals
2, you have what?

00:14:07.480 --> 00:14:13.300
2 raised to 4, which
is 16 minus 115.

00:14:13.300 --> 00:14:15.050
That seems to work.

00:14:15.050 --> 00:14:18.250
And then you get
up to, I think 80--

00:14:18.250 --> 00:14:20.280
what is it?

00:14:20.280 --> 00:14:22.870
2 raised to 6 would be 64.

00:14:22.870 --> 00:14:24.550
And so that will be 63.

00:14:24.550 --> 00:14:25.469
That works too.

00:14:25.469 --> 00:14:26.510
In general, does it work?

00:14:30.150 --> 00:14:31.200
It does.

00:14:31.200 --> 00:14:34.260
So it turns out if
you think about it,

00:14:34.260 --> 00:14:39.780
you can write this out
as 2 raised to n minus 1

00:14:39.780 --> 00:14:42.840
times 2 raised to n plus 1.

00:14:42.840 --> 00:14:48.240
And in the middle there, pretend
that there's 2 raised to n.

00:14:48.240 --> 00:14:50.050
So you have three
consecutive numbers.

00:14:50.050 --> 00:14:53.460
And when you multiply
three consecutive numbers,

00:14:53.460 --> 00:14:54.510
they're consecutive.

00:14:54.510 --> 00:14:56.250
Doesn't matter what
the numbers are.

00:14:56.250 --> 00:14:59.760
The product is always
going to be a multiple of 3

00:14:59.760 --> 00:15:02.670
because one of those things is
going to be a multiple of 3.

00:15:02.670 --> 00:15:05.430
And you know that 2 raised
to n is not a multiple of 3.

00:15:05.430 --> 00:15:07.680
This is not a product of
three consecutive numbers.

00:15:07.680 --> 00:15:11.910
But if it were, and you
pretended that 2 raised to n

00:15:11.910 --> 00:15:14.970
was in here, either this
one is a multiple of 3,

00:15:14.970 --> 00:15:17.070
or that one is a multiple of 3.

00:15:17.070 --> 00:15:18.320
So this is good.

00:15:18.320 --> 00:15:24.090
So we know that at least
from a standpoint of volume--

00:15:24.090 --> 00:15:26.140
our surface area, if you will--

00:15:26.140 --> 00:15:27.450
that this is going to work.

00:15:27.450 --> 00:15:30.210
Whereas the original problem
didn't work from a surface area

00:15:30.210 --> 00:15:31.800
standpoint.

00:15:31.800 --> 00:15:34.920
So it comes down
to how am I going

00:15:34.920 --> 00:15:38.910
to solve this problem using
recursive divide and conquer?

00:15:38.910 --> 00:15:40.470
And so I can break this up.

00:15:40.470 --> 00:15:44.850
And you want to have a similar
feel to the merge sort,

00:15:44.850 --> 00:15:48.670
where when you go down to
the base case of merge sort,

00:15:48.670 --> 00:15:50.670
you had this trivial
problem to solve.

00:15:50.670 --> 00:15:52.560
That's the beauty of
divide and conquer.

00:15:52.560 --> 00:15:54.810
It becomes obvious when you
have such a small problem

00:15:54.810 --> 00:15:56.820
like one queen.

00:15:56.820 --> 00:15:59.190
That's not technically
not divide and conquer,

00:15:59.190 --> 00:16:01.020
but you do get to
the smaller part.

00:16:01.020 --> 00:16:04.110
But clearly, in this case,
this is a classic divide

00:16:04.110 --> 00:16:05.635
and conquer
algorithm merge sort.

00:16:05.635 --> 00:16:08.010
And you can see that the first
two or three lines of code

00:16:08.010 --> 00:16:12.150
are the trivial case
of two elements that

00:16:12.150 --> 00:16:13.750
needed to be sorted.

00:16:13.750 --> 00:16:16.050
So let's go back
and forget that.

00:16:16.050 --> 00:16:19.050
Let's look at this
picture and think

00:16:19.050 --> 00:16:21.027
about how you'd break this up.

00:16:21.027 --> 00:16:22.110
How would I bring this up?

00:16:30.600 --> 00:16:33.096
So think two-dimensionally.

00:16:33.096 --> 00:16:35.950
And merge sort was
a single dimension.

00:16:35.950 --> 00:16:38.361
OK, think two dimensional.

00:16:38.361 --> 00:16:39.360
This is two dimensional.

00:16:39.360 --> 00:16:40.420
This is a
two-dimensional problem.

00:16:40.420 --> 00:16:42.380
It's in that sense,
closer to N-queens.

00:16:42.380 --> 00:16:47.304
But merge sort was simply
a single dimension.

00:16:47.304 --> 00:16:48.470
All right, I see Kevin had--

00:16:48.470 --> 00:16:49.290
Fadi had his hand up.

00:16:49.290 --> 00:16:50.130
Kevin has a hand up.

00:16:50.130 --> 00:16:50.690
Someone else?

00:16:55.060 --> 00:16:56.226
All right, go ahead, Kevin.

00:16:56.226 --> 00:16:58.939
AUDIENCE: Do you keep cutting
the square into quarters?

00:16:58.939 --> 00:17:00.230
SRINI DEVADAS: Quarters-- good.

00:17:00.230 --> 00:17:01.520
OK, yeah.

00:17:01.520 --> 00:17:04.660
So all right, so let's do that.

00:17:04.660 --> 00:17:05.319
Let's do that.

00:17:05.319 --> 00:17:06.402
You're on the right track.

00:17:10.380 --> 00:17:16.770
And by the way, this particular
thing could be over there.

00:17:16.770 --> 00:17:20.329
And I'll just do this
just to make sure.

00:17:20.329 --> 00:17:22.619
Your algorithm needs
to work, regardless

00:17:22.619 --> 00:17:23.730
of where that statue is.

00:17:23.730 --> 00:17:25.980
So maybe the statue
is over here.

00:17:25.980 --> 00:17:27.390
Maybe the statue is over there.

00:17:27.390 --> 00:17:29.907
There's only one statue
that is covering one square,

00:17:29.907 --> 00:17:31.740
but it's not necessarily
in near the center.

00:17:31.740 --> 00:17:33.330
It could even be anywhere.

00:17:33.330 --> 00:17:35.610
You need a
general-purpose scheme

00:17:35.610 --> 00:17:39.210
that would work, regardless
of where the statue is as long

00:17:39.210 --> 00:17:41.640
as it only occupies one square.

00:17:41.640 --> 00:17:43.200
That's the only
constraint we have.

00:17:43.200 --> 00:17:46.380
So you're on the
right track, Kevin.

00:17:46.380 --> 00:17:48.900
Someone else or, Fadi,
you want to add to that?

00:17:51.894 --> 00:17:55.387
AUDIENCE: So in something
that's similar to the merge sort

00:17:55.387 --> 00:17:58.443
so you divide it into
quarters and then you

00:17:58.443 --> 00:18:00.568
reach the base case and
then we tile that obviously

00:18:00.568 --> 00:18:01.567
with an L shaped tile.

00:18:01.567 --> 00:18:03.462
SRINI DEVADAS: Right,
that's exactly right.

00:18:03.462 --> 00:18:03.962
So yeah.

00:18:03.962 --> 00:18:06.270
So that there's one thing
that's missing in what

00:18:06.270 --> 00:18:09.120
both you and Kevin have put up.

00:18:09.120 --> 00:18:12.510
The thing with merge sort was
I had exactly the same problem

00:18:12.510 --> 00:18:13.710
to solve.

00:18:13.710 --> 00:18:15.420
It was exactly the same problem.

00:18:15.420 --> 00:18:16.590
It was just smaller.

00:18:16.590 --> 00:18:19.830
I needed to sort the smaller
array in ascending order.

00:18:19.830 --> 00:18:22.800
And I had two of them, and it
was exactly the same problem.

00:18:22.800 --> 00:18:25.260
But when I split this up
into four quarters like you

00:18:25.260 --> 00:18:28.200
guys are suggesting, do I
have exactly the same four

00:18:28.200 --> 00:18:30.210
problems to solve?

00:18:30.210 --> 00:18:35.690
In fact, can I even
solve this the 16 problem

00:18:35.690 --> 00:18:36.910
with L-shaped tiles?

00:18:36.910 --> 00:18:37.660
I can't.

00:18:37.660 --> 00:18:40.225
So at some level, I have three
problems that I can't solve.

00:18:40.225 --> 00:18:42.100
And then a smaller
problem that I don't quite

00:18:42.100 --> 00:18:44.266
know how to solve-- other
than maybe splitting it up

00:18:44.266 --> 00:18:46.630
even more, which is kind of
interesting, which is good.

00:18:46.630 --> 00:18:48.220
But then the next
time, if I go ahead

00:18:48.220 --> 00:18:51.100
and split that, then wonderful.

00:18:51.100 --> 00:18:55.990
I will find one problem that's
two by two that I can solve,

00:18:55.990 --> 00:18:58.550
but that doesn't
solve my puzzle.

00:18:58.550 --> 00:19:02.350
So I have to do one
more thing in order

00:19:02.350 --> 00:19:06.550
to make this look like merge
sort or any recursive divide

00:19:06.550 --> 00:19:07.210
and conquer.

00:19:07.210 --> 00:19:09.700
One of the paradigms of
recursive divide and conquer

00:19:09.700 --> 00:19:12.580
is you're not creating
new types of problems.

00:19:12.580 --> 00:19:15.790
You're creating the same type
of problem, except smaller.

00:19:15.790 --> 00:19:18.520
And therefore,
eventually easier.

00:19:18.520 --> 00:19:20.590
So I have to do one more thing.

00:19:20.590 --> 00:19:24.700
And this is an aha moment
here that I'm hoping--

00:19:24.700 --> 00:19:26.950
I don't want to
take an answer yet

00:19:26.950 --> 00:19:28.930
because I want you
to think about it

00:19:28.930 --> 00:19:31.930
and perhaps arrive at it.

00:19:31.930 --> 00:19:36.280
But it's one of those things
where you're going to go "oh!"

00:19:36.280 --> 00:19:38.380
if you don't know the answer.

00:19:38.380 --> 00:19:41.530
But it is worth spending
another minute--

00:19:41.530 --> 00:19:44.680
another minute for each
of you thinking about it.

00:19:44.680 --> 00:19:47.680
How am I going to set it up so
these quarters-- so all of this

00:19:47.680 --> 00:19:48.400
is good?

00:19:48.400 --> 00:19:50.200
I'm going to split
it up into quarters,

00:19:50.200 --> 00:19:57.910
but I want all four problems
to look exactly the same

00:19:57.910 --> 00:19:59.350
in the sense that they look--

00:19:59.350 --> 00:20:01.210
this obviously looks different
from these other ones.

00:20:01.210 --> 00:20:02.626
Well, there's a
tile missing here,

00:20:02.626 --> 00:20:05.680
but there is no tile missing
over in the other three.

00:20:05.680 --> 00:20:10.340
So how do I make all
problems look the same?

00:20:10.340 --> 00:20:12.760
I know you know,
but we need more.

00:20:17.610 --> 00:20:19.382
I'll give you 30 more
seconds, and I'll

00:20:19.382 --> 00:20:20.340
give you one more hint.

00:20:27.150 --> 00:20:30.390
All! right, the hint
is place one tile--

00:20:30.390 --> 00:20:32.381
place one L-shaped tile.

00:20:32.381 --> 00:20:32.880
All right.

00:20:32.880 --> 00:20:34.214
Yeah, go for it.

00:20:34.214 --> 00:20:37.710
AUDIENCE: Yeah, you know that
with those last four quarters--

00:20:37.710 --> 00:20:39.948
you know that that
L-shape has to go around?

00:20:39.948 --> 00:20:40.776
SRINI DEVADAS: Yes.

00:20:40.776 --> 00:20:41.567
Yeah, that's right.

00:20:41.567 --> 00:20:43.475
So you set it up so you tile.

00:20:46.680 --> 00:20:49.860
The reason I picked
this L-shape this way

00:20:49.860 --> 00:20:54.050
is because this was the statue.

00:20:54.050 --> 00:21:01.170
So I wanted to remove a tile
from each of the other 3/4.

00:21:01.170 --> 00:21:03.540
I'm sorry, remove a square.

00:21:03.540 --> 00:21:05.160
A tile is L-shaped.

00:21:05.160 --> 00:21:07.380
And so this was
a missing square,

00:21:07.380 --> 00:21:10.232
which was part of the
specification of the problem.

00:21:10.232 --> 00:21:11.690
It has nothing to
do with the tile.

00:21:11.690 --> 00:21:14.370
It's just a missing square
because there's a statue on it.

00:21:14.370 --> 00:21:18.390
But what I could do is if I
oriented the tile in this way,

00:21:18.390 --> 00:21:25.140
now I have this being a
smaller problem, which

00:21:25.140 --> 00:21:28.290
is one-quarter of the size of
the original problem with one

00:21:28.290 --> 00:21:29.670
square missing.

00:21:29.670 --> 00:21:31.020
This one is one square missing.

00:21:31.020 --> 00:21:32.311
This one is one square missing.

00:21:32.311 --> 00:21:33.750
This one is one square missing.

00:21:33.750 --> 00:21:36.930
Now that makes all of the
problems look the same.

00:21:36.930 --> 00:21:40.500
Now, at first, they're not
exactly the same in the sense

00:21:40.500 --> 00:21:44.490
that the missing square is
in a different position.

00:21:44.490 --> 00:21:47.940
But there's some generality that
we need in our algorithm that

00:21:47.940 --> 00:21:50.970
says that eventually, if
I keep breaking this up

00:21:50.970 --> 00:21:54.750
in this fashion, I just need
to orient my L-shaped tile

00:21:54.750 --> 00:21:56.760
in the appropriate way.

00:21:56.760 --> 00:21:59.450
So there's only
four different ways

00:21:59.450 --> 00:22:05.420
that an L-shaped tile
is going to be oriented.

00:22:05.420 --> 00:22:08.420
It could be oriented like this.

00:22:08.420 --> 00:22:09.700
And I won't draw all of them.

00:22:09.700 --> 00:22:12.160
It could be oriented like that.

00:22:12.160 --> 00:22:17.910
And it could also
be that's the same.

00:22:17.910 --> 00:22:18.870
So what else is there?

00:22:18.870 --> 00:22:22.030
Oh, it could be
flipped this way.

00:22:22.030 --> 00:22:26.560
Yeah, like that
and the fourth one.

00:22:26.560 --> 00:22:27.830
So that's what I did here.

00:22:27.830 --> 00:22:29.350
This one is what I put up there.

00:22:29.350 --> 00:22:33.760
And then as I break
this up, let's

00:22:33.760 --> 00:22:36.370
just say that now I'm going
to make four recursive calls.

00:22:36.370 --> 00:22:38.200
I'm going to place one tile--

00:22:38.200 --> 00:22:40.360
one L-shaped tile--
and I'm going

00:22:40.360 --> 00:22:41.650
to mark off of these things.

00:22:41.650 --> 00:22:43.750
And I'm going to make
four recursive calls

00:22:43.750 --> 00:22:47.350
to basically myself, except that
the arguments are different.

00:22:47.350 --> 00:22:49.000
It's the same code, obviously.

00:22:49.000 --> 00:22:51.486
So when I go up
here, I go like that,

00:22:51.486 --> 00:22:53.110
and hopefully, this
will become clearer

00:22:53.110 --> 00:22:54.610
if you're going to
do a tiling here.

00:22:54.610 --> 00:22:58.054
I'm going to go focus on the top
left, and I'm going to do this.

00:22:58.054 --> 00:22:59.470
What am I going
to do with respect

00:22:59.470 --> 00:23:05.110
to this at this particular
quarter of the courtyard?

00:23:05.110 --> 00:23:09.600
How am I going to orient the
L-shaped tile for this one?

00:23:09.600 --> 00:23:12.060
Point with your fingers.

00:23:12.060 --> 00:23:12.690
Exactly right.

00:23:12.690 --> 00:23:14.130
So this is the same as this.

00:23:14.130 --> 00:23:15.546
I'm going to go
ahead and do that.

00:23:18.280 --> 00:23:21.480
So now I have this problem.

00:23:21.480 --> 00:23:26.590
So I'm going to mark that
with a different color.

00:23:26.590 --> 00:23:29.740
So I'm focused on this problem,
and I've done that break.

00:23:29.740 --> 00:23:34.840
And now I'm good because I have
four two by two courtyards,

00:23:34.840 --> 00:23:39.670
and each of these
four has one square

00:23:39.670 --> 00:23:43.420
missing in each of these four
little two by two courtyards.

00:23:43.420 --> 00:23:45.190
So clearly, I can solve that.

00:23:45.190 --> 00:23:47.680
And then once I solve that,
I move on to this one,

00:23:47.680 --> 00:23:50.570
and I move onto this one--
whatever order you want.

00:23:50.570 --> 00:23:51.340
That's it.

00:23:51.340 --> 00:23:54.940
And so the code for this is--

00:23:54.940 --> 00:23:58.300
from a control flow
standpoint, from a standpoint

00:23:58.300 --> 00:24:02.860
of the overall algorithm, it's
extremely straightforward.

00:24:02.860 --> 00:24:04.720
It's almost exactly
like merge sort,

00:24:04.720 --> 00:24:08.150
except that you have
four-way recursion

00:24:08.150 --> 00:24:10.660
because it's two
dimensional, and you end up

00:24:10.660 --> 00:24:11.620
getting quarters.

00:24:11.620 --> 00:24:13.740
And the only thing that's
annoying about this code

00:24:13.740 --> 00:24:17.590
to write and also to understand,
which you guys will--

00:24:17.590 --> 00:24:23.630
I'll put this up, and I'll
show you what to look for--

00:24:23.630 --> 00:24:27.970
is how you represent
this as such

00:24:27.970 --> 00:24:32.140
that you get all
the values right.

00:24:32.140 --> 00:24:37.540
So you get an arbitrary square,
to begin with, that is missing.

00:24:37.540 --> 00:24:41.320
And then you have
to go to the middle.

00:24:41.320 --> 00:24:42.136
That's clear.

00:24:42.136 --> 00:24:44.260
You're going to go to the
middle of this courtyard,

00:24:44.260 --> 00:24:45.500
and you're going to split it.

00:24:45.500 --> 00:24:47.920
And you're going to decide
which way this L-shaped tile is

00:24:47.920 --> 00:24:51.790
oriented, and then you got
to do the splitting again

00:24:51.790 --> 00:24:53.320
and so it's just bookkeeping.

00:24:53.320 --> 00:24:55.120
That's really what
this is all about.

00:24:55.120 --> 00:24:57.220
It's not algorithmically
interesting.

00:24:57.220 --> 00:24:59.800
It's just bookkeeping in
terms of the orientation

00:24:59.800 --> 00:25:01.757
of these L-shaped tiles.

00:25:01.757 --> 00:25:03.340
So if you look at
the code, and if you

00:25:03.340 --> 00:25:11.140
ignore a bunch of these indices
of these different variables--

00:25:11.140 --> 00:25:13.100
let me show you.

00:25:13.100 --> 00:25:18.120
Well, first, I'll show you what
happens when you run the code.

00:25:18.120 --> 00:25:21.530
I'm running it for two
different kinds of courtyards.

00:25:21.530 --> 00:25:25.780
And I've used A through,
I guess, something like S,

00:25:25.780 --> 00:25:27.430
in this case, to signify a tile.

00:25:27.430 --> 00:25:28.810
So you see AAA here.

00:25:28.810 --> 00:25:31.120
AAA is an L-shaped tile.

00:25:31.120 --> 00:25:32.590
BBB is an L-shaped tile.

00:25:32.590 --> 00:25:34.840
FFF is an L-shaped
tile, et cetera.

00:25:34.840 --> 00:25:38.020
The original specification
of the problem--

00:25:38.020 --> 00:25:40.120
this is just simply an
eight by eight problem--

00:25:40.120 --> 00:25:41.560
had this tile that you see here.

00:25:41.560 --> 00:25:45.130
That's a blank that I've
covered up that was missing.

00:25:45.130 --> 00:25:47.170
I'm sorry, this square missing.

00:25:47.170 --> 00:25:52.750
And then I broke this up
into two or four 4 by 4's.

00:25:52.750 --> 00:25:55.480
And then I went all the way
up and then the first tile

00:25:55.480 --> 00:26:01.270
that I placed, I pretended to
place this U tile over here.

00:26:01.270 --> 00:26:04.270
I could've placed it and
then called it the A tile.

00:26:04.270 --> 00:26:09.430
But this is essentially what you
think of the one in the center

00:26:09.430 --> 00:26:11.300
exactly the way
this is oriented.

00:26:11.300 --> 00:26:12.646
That's your U tile over here.

00:26:12.646 --> 00:26:14.020
And then you go
all the way down.

00:26:14.020 --> 00:26:17.440
And explicitly, it's just the
A tile that displays first,

00:26:17.440 --> 00:26:19.880
and then the B tile,
and so on and so forth.

00:26:19.880 --> 00:26:22.600
And if you take a look
at the code, what's

00:26:22.600 --> 00:26:26.210
the best place to start?

00:26:26.210 --> 00:26:28.430
So this is the base case--

00:26:28.430 --> 00:26:30.970
same thing as we've
talked about before.

00:26:30.970 --> 00:26:32.830
You always need to
have a base case.

00:26:32.830 --> 00:26:34.660
The base cases is a two by two.

00:26:34.660 --> 00:26:38.800
And this code places one
L-shaped tile on a two

00:26:38.800 --> 00:26:41.170
by two yard.

00:26:41.170 --> 00:26:43.660
This is going to make four
recursive calls, as you

00:26:43.660 --> 00:26:47.650
can see from range
four, and there's

00:26:47.650 --> 00:26:50.710
two different kinds of
recursive calls in the sense

00:26:50.710 --> 00:26:53.770
that they're both
calling recursive tile,

00:26:53.770 --> 00:26:55.600
but the arguments of
the recursive style

00:26:55.600 --> 00:26:59.890
are different for
this recursive call

00:26:59.890 --> 00:27:03.790
because it already had
the missing square in it.

00:27:03.790 --> 00:27:05.800
And these three
recursive calls that are

00:27:05.800 --> 00:27:10.220
going to have the missing
square in one of their corners.

00:27:10.220 --> 00:27:14.160
So that's why you see
the if and the else here.

00:27:14.160 --> 00:27:17.830
And if the original
for the recursive

00:27:17.830 --> 00:27:20.230
call that already had
the missing square

00:27:20.230 --> 00:27:23.920
because it had the statue on
it, that's the if statement.

00:27:23.920 --> 00:27:28.720
And the other ones are the
ones that are in the corners.

00:27:28.720 --> 00:27:31.420
So the first things it would
be a corner for this one.

00:27:31.420 --> 00:27:33.170
This is the corner of
that, one and that's

00:27:33.170 --> 00:27:35.480
the corner of that one.

00:27:35.480 --> 00:27:37.570
So that's pretty much all I had.

00:27:37.570 --> 00:27:41.440
This code-- you need to
gaze at it for a few minutes

00:27:41.440 --> 00:27:44.230
to figure out that I got
all the arguments correct.

00:27:44.230 --> 00:27:46.240
But from a standpoint
of, as I said,

00:27:46.240 --> 00:27:47.950
the control flow
and the algorithm,

00:27:47.950 --> 00:27:51.310
it is hopefully completely
clear to you at this point.

00:27:51.310 --> 00:27:52.920
If not, ask me questions.

00:27:52.920 --> 00:27:54.160
Come to office hours.

00:27:54.160 --> 00:27:56.250
Have a good long weekend.