Answers Built From Smaller Answers
Splitting the Work in Half
Last timeWhat the Machine Is Holding While It Waits
Shrinking a problem by one gives a method as slow as the loop it replaced, and shrinking it by half gives something qualitatively different for the same three lines.
The same three lines, a different method
Everything so far has made the problem smaller by one. Take off the first
item, solve the rest, combine. The combining is cheap, the depth is the size
of the input, and the total work is roughly the same as a loop would have
done. The recursion was a way of writing the method, not a way of improving it.
Now change one thing. Instead of removing one item, cut the input in half,
solve both halves, and combine those. The code is barely different and the
method is not.
def biggest_one(xs):
if len(xs) == 1:
return xs[0]
rest = biggest_one(xs[1:]) # depth equals the length
return xs[0] if xs[0] > rest else rest
def biggest_half(xs):
if len(xs) == 1:
return xs[0]
mid = len(xs) // 2
left = biggest_half(xs[:mid]) # depth is the number of halvings
right = biggest_half(xs[mid:])
return left if left > right else right
nums = list(range(1, 100001))
print(biggest_half(nums)) # 100000, depth about 17
print(biggest_one(nums)) # RecursionError, long before it finishesHow many levels there are
The reason the depth collapses is worth seeing as a count rather than taking
on trust.
Start with a million items. One split gives pieces of half a million. The next
gives a quarter of a million. Each level halves the size, so after levels
the pieces have size , and the splitting stops when that reaches one.
Setting gives , so is the number of times can be
halved, which is its logarithm in base two.
- the number of items at the start
- the number of levels of splitting before the pieces are single items
Where the work actually goes
The depth is the easy part. The cost of the method is in what happens at each
level, and it has a pleasant structure.
At the top level there is one piece of size , and merging its two halves
costs whatever the merging step costs on items. At the next level there
are two pieces of size , and merging each costs half as much, but there
are two of them, so the level costs the same in total. At the next there are
four pieces of a quarter the size. Every level costs the same, because the
pieces shrink exactly as fast as they multiply.
The lesson stops here
3 more paragraphs to go
You have read the opening. The rest of the argument, the problems that check whether it landed, and the lines worth keeping at the end all come with a plan.
The first lesson of every course in the library reads the whole way through, free, so you can see exactly what the rest of them are.
See the planThe contentsThis is the reading half
Starting the course gives you your own copy of it. Every idea on every page has problems standing under it, marked with a reason rather than a tick, and any sentence you do not believe can be opened and argued with. None of that can happen on a page nobody owns.
The contents