1 00:00:07,192 --> 00:00:08,566 SRINI DEVADAS: Morning, everyone. 2 00:00:08,566 --> 00:00:12,830 Welcome to 6.S095. 3 00:00:12,830 --> 00:00:14,520 Thanks for registering for this class. 4 00:00:14,520 --> 00:00:15,760 I hope you like it. 5 00:00:15,760 --> 00:00:17,180 My name is Srini Devadas. 6 00:00:17,180 --> 00:00:22,900 I'm a professor of computer science at MIT, obviously, 7 00:00:22,900 --> 00:00:26,275 and I've been teaching at MIT for 30 years. 8 00:00:26,275 --> 00:00:28,810 So I've been at it for a while. 9 00:00:28,810 --> 00:00:30,730 The reason I'm teaching this IAP class 10 00:00:30,730 --> 00:00:36,550 is because I want to try out this way of teaching 11 00:00:36,550 --> 00:00:40,750 programming that starts with the recreational world 12 00:00:40,750 --> 00:00:44,080 of mathematical puzzles, algorithmic puzzles, 13 00:00:44,080 --> 00:00:48,760 and I want to connect it up to writing programs. 14 00:00:48,760 --> 00:00:54,090 And I have taught this material before in 6.009 15 00:00:54,090 --> 00:00:57,620 that I think some of you are registered for, 16 00:00:57,620 --> 00:01:01,510 but I wanted to teach it in a more interactive, 17 00:01:01,510 --> 00:01:02,860 informal setting. 18 00:01:02,860 --> 00:01:06,250 And I should mention that I wrote a book 19 00:01:06,250 --> 00:01:09,970 on this, which is a book that's recommended, though not 20 00:01:09,970 --> 00:01:11,680 required, for 6.009. 21 00:01:11,680 --> 00:01:15,460 And so you might see this in the MIT Press 22 00:01:15,460 --> 00:01:17,440 Bookstore and other places. 23 00:01:17,440 --> 00:01:21,120 And most of the material I'm going to cover here 24 00:01:21,120 --> 00:01:22,510 is from the book. 25 00:01:22,510 --> 00:01:24,700 But I don't want you to read the book 26 00:01:24,700 --> 00:01:29,710 because I want you to listen to my explanations for the puzzles 27 00:01:29,710 --> 00:01:32,470 and try and think of the solutions 28 00:01:32,470 --> 00:01:37,810 yourself and then obviously do some amount of coding 29 00:01:37,810 --> 00:01:40,600 not during lecture but offline. 30 00:01:40,600 --> 00:01:43,120 And I'll show you some solutions to the puzzles, 31 00:01:43,120 --> 00:01:45,430 and there will be some exercises. 32 00:01:45,430 --> 00:01:48,970 So I don't want to spend a whole lot of time on logistics. 33 00:01:48,970 --> 00:01:52,690 This is an IAP class, as I mentioned. 34 00:01:52,690 --> 00:01:55,810 I'd like this to be informal and relaxed. 35 00:01:55,810 --> 00:01:59,920 So we meet every day for two weeks. 36 00:01:59,920 --> 00:02:01,630 We have the holiday coming up on Monday, 37 00:02:01,630 --> 00:02:06,930 so we'll have nine total lectures roughly for an hour. 38 00:02:06,930 --> 00:02:10,509 It might spill over, but hopefully, you'll be OK with it 39 00:02:10,509 --> 00:02:14,110 because you don't have another class to go to at noon. 40 00:02:14,110 --> 00:02:16,870 And if you do, well, let me know, 41 00:02:16,870 --> 00:02:20,920 and I'll give you that five minutes of overflow 42 00:02:20,920 --> 00:02:25,720 personally at a time of your choosing. 43 00:02:25,720 --> 00:02:29,780 But hopefully, I'll keep on time. 44 00:02:29,780 --> 00:02:32,930 And in terms of work, this is a pass/fail. 45 00:02:32,930 --> 00:02:34,900 It's a for-credit class. 46 00:02:34,900 --> 00:02:37,540 I know some of you may be listeners, but some of you 47 00:02:37,540 --> 00:02:38,710 are registered for it. 48 00:02:38,710 --> 00:02:40,660 So I'll have to assign you a grade, 49 00:02:40,660 --> 00:02:42,149 so there will be some exercises. 50 00:02:42,149 --> 00:02:43,690 And I'm going to make it very simple. 51 00:02:46,230 --> 00:02:48,320 There'll be exercises up on the website. 52 00:02:48,320 --> 00:02:51,550 They'll be due two days from when I put them up. 53 00:02:51,550 --> 00:02:54,070 And you'll have options in terms of whether to do 54 00:02:54,070 --> 00:02:56,590 a really simple exercise that's probably 55 00:02:56,590 --> 00:03:00,570 going to take about five minutes or do something harder. 56 00:03:00,570 --> 00:03:02,050 And for each of the puzzles, there 57 00:03:02,050 --> 00:03:05,650 are two or three exercises, and you get to do all of them 58 00:03:05,650 --> 00:03:06,560 if you want. 59 00:03:06,560 --> 00:03:11,010 You can choose to do one or the other. 60 00:03:11,010 --> 00:03:15,340 I'm going to have office hours every day from 1:00 to 2:00. 61 00:03:15,340 --> 00:03:18,400 I don't plan on putting solutions up to the exercises. 62 00:03:18,400 --> 00:03:21,390 The solutions to the puzzles themselves, 63 00:03:21,390 --> 00:03:23,350 they'll be shown mostly in lecture 64 00:03:23,350 --> 00:03:26,410 and put up on the Stellar website, 65 00:03:26,410 --> 00:03:28,920 but the solutions to the exercises, 66 00:03:28,920 --> 00:03:30,070 I'm not going to put up. 67 00:03:30,070 --> 00:03:32,290 But if you ever get stuck, well, that's 68 00:03:32,290 --> 00:03:33,880 what office hours are for. 69 00:03:33,880 --> 00:03:36,960 And if you can't solve the exercises, 70 00:03:36,960 --> 00:03:39,410 I'll help to solve them. 71 00:03:39,410 --> 00:03:42,070 So with that, without further ado, 72 00:03:42,070 --> 00:03:45,280 let's dive in and talk about puzzles 73 00:03:45,280 --> 00:03:50,050 and solving puzzles using algorithms and then programs. 74 00:03:50,050 --> 00:03:52,030 I'd really like this to be interactive, 75 00:03:52,030 --> 00:03:58,420 so please ask questions and suggest solutions 76 00:03:58,420 --> 00:03:59,510 that I haven't thought of. 77 00:03:59,510 --> 00:04:00,250 That'd be great. 78 00:04:00,250 --> 00:04:02,300 In my second edition, whenever that is, 79 00:04:02,300 --> 00:04:04,810 you'll get credit for that. 80 00:04:04,810 --> 00:04:14,490 So the first puzzle, I tried to have, I don't know, 81 00:04:14,490 --> 00:04:18,250 funny titles for all of these puzzles-- 82 00:04:18,250 --> 00:04:19,370 intriguing. 83 00:04:19,370 --> 00:04:22,900 And so the first puzzle is called "You Will All Conform." 84 00:04:22,900 --> 00:04:25,240 This is really a warm-up puzzle. 85 00:04:25,240 --> 00:04:27,867 As you'll see-- this is true for any class-- 86 00:04:27,867 --> 00:04:30,200 things are going to get more complicated as we go along. 87 00:04:30,200 --> 00:04:33,370 So we'll probably do 10 or 12 puzzles in the next two weeks. 88 00:04:33,370 --> 00:04:39,860 And by the end, you're going to see things like memoization 89 00:04:39,860 --> 00:04:41,620 and dynamic programming and things 90 00:04:41,620 --> 00:04:44,390 like that towards the end of next week. 91 00:04:44,390 --> 00:04:46,990 And if you don't know what those mean, well, 92 00:04:46,990 --> 00:04:50,320 that's great because hopefully, you 93 00:04:50,320 --> 00:04:52,630 will know by the end of the two weeks. 94 00:04:52,630 --> 00:04:56,570 And a lot of these things are algorithmic insights, 95 00:04:56,570 --> 00:05:02,390 are insights that will help you in Course 6 classes, for sure, 96 00:05:02,390 --> 00:05:10,080 and perhaps even if you follow a career outside of Course 6. 97 00:05:10,080 --> 00:05:16,820 So this particular puzzle is, as I said, a fairly simple puzzle, 98 00:05:16,820 --> 00:05:18,470 at least to describe. 99 00:05:18,470 --> 00:05:22,170 And the setting is as follows. 100 00:05:22,170 --> 00:05:25,004 So you're a gatekeeper at a baseball game. 101 00:05:25,004 --> 00:05:26,420 We'll just call it a baseball game 102 00:05:26,420 --> 00:05:28,100 because baseball players wear caps, 103 00:05:28,100 --> 00:05:33,019 and most people are watching games with caps on. 104 00:05:33,019 --> 00:05:35,060 And so you're a gatekeeper, and there are a bunch 105 00:05:35,060 --> 00:05:37,820 of people standing in line. 106 00:05:37,820 --> 00:05:41,390 Let's just say each of them knows their number. 107 00:05:41,390 --> 00:05:43,520 And this is Python, so the number 108 00:05:43,520 --> 00:05:46,790 starts at 0 as opposed to 1. 109 00:05:46,790 --> 00:05:48,410 And there are a whole bunch of people 110 00:05:48,410 --> 00:05:54,050 standing in line waiting to get in, and they all have caps. 111 00:05:54,050 --> 00:05:57,430 And some of them are wearing their caps forward, 112 00:05:57,430 --> 00:06:00,305 so with the-- 113 00:06:00,305 --> 00:06:02,090 I guess, what do you call it? 114 00:06:02,090 --> 00:06:05,150 What's the front of the cap called? 115 00:06:05,150 --> 00:06:09,940 The shade-- the thing that gives you shade up front. 116 00:06:09,940 --> 00:06:13,350 And so we just say-- 117 00:06:13,350 --> 00:06:14,870 let me try and draw this out. 118 00:06:14,870 --> 00:06:18,920 So this person is wearing his cap like that, 119 00:06:18,920 --> 00:06:23,820 and this lady here is wearing her cap like this. 120 00:06:23,820 --> 00:06:27,200 So that's forwards, and that's backwards. 121 00:06:29,990 --> 00:06:37,740 So your job here is straightforward. 122 00:06:37,740 --> 00:06:42,500 You can only let all of these people into line-- 123 00:06:42,500 --> 00:06:49,930 sorry-- into the stadium who are in line if they all conform. 124 00:06:49,930 --> 00:06:52,490 So they all have to wear their caps 125 00:06:52,490 --> 00:06:55,640 in a particular orientation, and you don't particularly 126 00:06:55,640 --> 00:06:57,980 care which one. 127 00:06:57,980 --> 00:07:00,200 And so they all have to be forwards, 128 00:07:00,200 --> 00:07:03,920 all, let's say, 13 of them. 129 00:07:03,920 --> 00:07:06,590 Or they all have to be backwards. 130 00:07:06,590 --> 00:07:11,330 Now, all of them know their position on the line. 131 00:07:11,330 --> 00:07:14,630 So this person knows that his position is 0, 132 00:07:14,630 --> 00:07:16,670 this lady here knows that her position 133 00:07:16,670 --> 00:07:19,640 is 1, et cetera, et cetera. 134 00:07:19,640 --> 00:07:24,830 And so obviously, you'd like to minimize the amount of work 135 00:07:24,830 --> 00:07:30,560 that you do, and you could certainly choose-- 136 00:07:30,560 --> 00:07:32,720 let's say you want everyone to be forwards. 137 00:07:32,720 --> 00:07:36,740 You could say, hey, lady in position 1, flip your cap. 138 00:07:36,740 --> 00:07:39,350 Oh, I should mention something that is important. 139 00:07:39,350 --> 00:07:41,240 So people have a different definition 140 00:07:41,240 --> 00:07:42,860 of forwards and backwards. 141 00:07:42,860 --> 00:07:47,060 It's sort of what's natural and what's unnatural to them. 142 00:07:47,060 --> 00:07:53,090 So we think that this person has his cap on forwards. 143 00:07:53,090 --> 00:07:55,160 But for all you know, he thinks he's got his cap 144 00:07:55,160 --> 00:07:57,050 on backwards or vice versa. 145 00:07:57,050 --> 00:08:00,830 So you can't assume that the definition 146 00:08:00,830 --> 00:08:04,880 of "forwards" and "backwards" is identical for all of the people 147 00:08:04,880 --> 00:08:09,170 in line and really is the same as your definition. 148 00:08:09,170 --> 00:08:11,090 It seems kind of unreasonable. 149 00:08:11,090 --> 00:08:17,677 Hey, this is a puzzle, so let's not argue about that. 150 00:08:17,677 --> 00:08:19,760 We can argue about other things, like how to write 151 00:08:19,760 --> 00:08:22,790 Python programs properly. 152 00:08:22,790 --> 00:08:24,860 So what you have to do now is you 153 00:08:24,860 --> 00:08:30,020 have to call out commands that correspond to saying, 154 00:08:30,020 --> 00:08:34,549 person in position 0, flip your cap. 155 00:08:34,549 --> 00:08:35,900 That's all you can say. 156 00:08:35,900 --> 00:08:38,690 You can just say, flip your cap. 157 00:08:38,690 --> 00:08:41,780 You can obviously see how these caps are oriented, 158 00:08:41,780 --> 00:08:43,850 and you can ask-- 159 00:08:43,850 --> 00:08:45,870 let's say that you had something like that. 160 00:08:45,870 --> 00:08:49,640 I'm just making this up as I go along, in terms of I'm 161 00:08:49,640 --> 00:08:52,160 not going to draw all the caps here. 162 00:08:52,160 --> 00:08:55,950 But this is what it looks like. 163 00:08:55,950 --> 00:09:01,010 And so according to you, you see F, B, B, in terms 164 00:09:01,010 --> 00:09:02,540 of Forwards and Backwards. 165 00:09:02,540 --> 00:09:06,230 And let's say you decide that you want everyone 166 00:09:06,230 --> 00:09:10,290 to have their cap on forwards. 167 00:09:10,290 --> 00:09:14,870 Then you could say, person in position 1, flip your cap. 168 00:09:14,870 --> 00:09:17,240 Person in position 2, flip your cap. 169 00:09:17,240 --> 00:09:21,230 And then person in position 4, 7, et cetera. 170 00:09:21,230 --> 00:09:23,900 And you want to make it easier on yourself 171 00:09:23,900 --> 00:09:30,260 because people do know their indices, their positions 172 00:09:30,260 --> 00:09:31,310 in line. 173 00:09:31,310 --> 00:09:33,560 And so to save yourself some trouble, 174 00:09:33,560 --> 00:09:37,160 you could say, people in positions 1 through 2-- 175 00:09:37,160 --> 00:09:40,910 and the implication is that it's inclusive-- flip your caps. 176 00:09:40,910 --> 00:09:44,540 And so that takes care of these two. 177 00:09:44,540 --> 00:09:53,930 And perhaps 8 here and 9 had their caps on backwards, 178 00:09:53,930 --> 00:09:57,950 and you could say, people in positions 7 through 9, 179 00:09:57,950 --> 00:09:59,540 flip your caps. 180 00:09:59,540 --> 00:10:01,220 So in this particular example, assuming 181 00:10:01,220 --> 00:10:05,630 that things ended with 10 people in line, 0 through 9, 182 00:10:05,630 --> 00:10:10,610 you could get away with three commands. 183 00:10:10,610 --> 00:10:14,180 You could say, 1 through 2-- 184 00:10:14,180 --> 00:10:18,180 and the implication, as I said, is this is inclusive-- 185 00:10:18,180 --> 00:10:19,910 flip. 186 00:10:19,910 --> 00:10:25,040 And then you could say, 4, flip. 187 00:10:25,040 --> 00:10:32,870 And then you could say, 7 through 9, flip. 188 00:10:32,870 --> 00:10:36,620 And if you did it the other way, you 189 00:10:36,620 --> 00:10:39,290 could also say, person at 0, flip, 190 00:10:39,290 --> 00:10:41,050 and so this would go backwards. 191 00:10:41,050 --> 00:10:43,190 Person at 3, flip. 192 00:10:43,190 --> 00:10:45,020 Obviously, you can't say, 0 through 3 193 00:10:45,020 --> 00:10:46,760 because that would be wrong. 194 00:10:46,760 --> 00:10:51,540 And then you could say 5 through 6 here. 195 00:10:51,540 --> 00:10:57,980 So you would get three commands in that case, as well. 196 00:10:57,980 --> 00:11:03,170 But if in fact, for argument's sake, let's 197 00:11:03,170 --> 00:11:08,950 just say that I'm going to just turn this into 10 198 00:11:08,950 --> 00:11:12,630 and put an F down here. 199 00:11:12,630 --> 00:11:17,190 Then these three commands would still 200 00:11:17,190 --> 00:11:24,300 work if you wanted to focus on the B's, on the Backwards 201 00:11:24,300 --> 00:11:27,300 people, and make them make them go forwards. 202 00:11:27,300 --> 00:11:29,580 But if you wanted to make all of the forward people 203 00:11:29,580 --> 00:11:38,300 go backwards, you would need 1, 2, 3, 4, four commands. 204 00:11:38,300 --> 00:11:39,960 So in this particular case, you're 205 00:11:39,960 --> 00:11:43,950 better off doing that as opposed to doing four commands. 206 00:11:43,950 --> 00:11:51,000 So first straightforward question is-- 207 00:11:51,000 --> 00:11:53,150 and I'm not talking about code yet-- 208 00:11:53,150 --> 00:11:56,610 algorithmically, just in terms of pseudocode-- 209 00:11:56,610 --> 00:12:00,060 and I'm happy with English-- 210 00:12:00,060 --> 00:12:05,340 how would you determine the minimum set of commands given 211 00:12:05,340 --> 00:12:07,520 a particular set of people? 212 00:12:07,520 --> 00:12:09,960 There's an arbitrary set of people. 213 00:12:09,960 --> 00:12:14,010 You want to make sure that you have the absolute minimum set 214 00:12:14,010 --> 00:12:18,007 of commands, and you're going to have to use these intervals. 215 00:12:18,007 --> 00:12:19,590 So you definitely want to look for all 216 00:12:19,590 --> 00:12:21,381 the contiguous intervals because obviously, 217 00:12:21,381 --> 00:12:24,540 if you say 1 followed and then that's a separate command, then 218 00:12:24,540 --> 00:12:28,170 you say 2 and that's a separate command, 219 00:12:28,170 --> 00:12:32,670 you end up having more commands than necessary. 220 00:12:32,670 --> 00:12:35,830 So anyone want to tell me I guess roughly, 221 00:12:35,830 --> 00:12:41,280 in terms of pseudocode, how this would work? 222 00:12:41,280 --> 00:12:42,462 Yeah, go ahead. 223 00:12:42,462 --> 00:12:45,062 AUDIENCE: Well, you could go down the line 224 00:12:45,062 --> 00:12:48,205 and look at the groups. 225 00:12:48,205 --> 00:12:51,187 So start with the 0. 226 00:12:51,187 --> 00:12:52,675 You've got to write 0. 227 00:12:52,675 --> 00:12:53,175 Group them. 228 00:12:53,175 --> 00:12:55,570 And then whatever the second one is-- 229 00:12:55,570 --> 00:13:00,990 so whatever the second group is, if it's F or B, 230 00:13:00,990 --> 00:13:03,066 those are the ones that need to be flipped 231 00:13:03,066 --> 00:13:06,210 because that's going to be the minimum number of commands. 232 00:13:06,210 --> 00:13:10,300 And then so from what you pass through, 233 00:13:10,300 --> 00:13:13,765 whenever you get to those, you just tell them to flip. 234 00:13:13,765 --> 00:13:14,890 SRINI DEVADAS: Sounds good. 235 00:13:14,890 --> 00:13:16,150 Do you have anything to add to that? 236 00:13:16,150 --> 00:13:16,691 AUDIENCE: No. 237 00:13:16,691 --> 00:13:19,391 I was going to say, you find the backwards interval 238 00:13:19,391 --> 00:13:20,510 or forward interval. 239 00:13:20,510 --> 00:13:23,615 And whichever is the lower, then-- 240 00:13:23,615 --> 00:13:24,490 SRINI DEVADAS: Lower. 241 00:13:24,490 --> 00:13:25,000 That's good. 242 00:13:25,000 --> 00:13:25,240 Good. 243 00:13:25,240 --> 00:13:25,740 Excellent. 244 00:13:25,740 --> 00:13:27,280 And so both of you had it right. 245 00:13:27,280 --> 00:13:31,140 So let me explain what these two gentlemen-- what was your name? 246 00:13:31,140 --> 00:13:31,890 AUDIENCE: Ganatra. 247 00:13:31,890 --> 00:13:32,960 SRINI DEVADAS: Ganatra? 248 00:13:32,960 --> 00:13:33,643 Yours? 249 00:13:33,643 --> 00:13:34,510 AUDIENCE: Fadi. 250 00:13:34,510 --> 00:13:35,664 SRINI DEVADAS: Fadi? 251 00:13:35,664 --> 00:13:36,490 AUDIENCE: Yeah. 252 00:13:36,490 --> 00:13:39,650 SRINI DEVADAS: So Ganatra and Fadi said-- 253 00:13:39,650 --> 00:13:43,390 so basically, this is, as I said, 254 00:13:43,390 --> 00:13:47,470 the natural algorithm that you would use. 255 00:13:47,470 --> 00:13:49,600 The natural algorithm would be that you 256 00:13:49,600 --> 00:13:53,500 walk through this list, and you start 257 00:13:53,500 --> 00:13:55,420 computing what I would call-- you called it 258 00:13:55,420 --> 00:13:56,200 "groups," Ganatra. 259 00:13:56,200 --> 00:13:59,470 But I'd call them "intervals," and an interval 260 00:13:59,470 --> 00:14:01,750 is something that is unbroken. 261 00:14:01,750 --> 00:14:02,860 It's contiguous. 262 00:14:02,860 --> 00:14:05,380 It's a contiguous set of people who 263 00:14:05,380 --> 00:14:08,650 all have their caps in the same orientation, 264 00:14:08,650 --> 00:14:10,530 be it forward or backwards. 265 00:14:10,530 --> 00:14:16,720 And what you would do in this case is you would compute the-- 266 00:14:16,720 --> 00:14:19,810 you would say, I want to look at the forward intervals. 267 00:14:19,810 --> 00:14:21,390 And the forward intervals would be 0, 268 00:14:21,390 --> 00:14:24,340 0 because that's essentially what you have in here. 269 00:14:24,340 --> 00:14:27,730 And going through that list, you would also say, 270 00:14:27,730 --> 00:14:30,010 I'm going to be computing the backward intervals. 271 00:14:30,010 --> 00:14:35,110 And in this case, you discover 1, 2 as the backwards interval. 272 00:14:35,110 --> 00:14:37,150 So I'm going to write them out like that. 273 00:14:37,150 --> 00:14:39,850 And in general, in the mathematical notation, 274 00:14:39,850 --> 00:14:44,640 when you put square brackets, these are closed intervals. 275 00:14:44,640 --> 00:14:46,630 So 0 is included. 276 00:14:46,630 --> 00:14:48,252 And we're going to see a puzzle where 277 00:14:48,252 --> 00:14:50,210 you might see something a little bit different, 278 00:14:50,210 --> 00:14:51,650 so I wanted to point that out. 279 00:14:51,650 --> 00:14:54,610 So 1, 2 are both inside this interval. 280 00:14:54,610 --> 00:14:57,730 And these two you would generate as you 281 00:14:57,730 --> 00:14:59,380 would go through the list, and then you 282 00:14:59,380 --> 00:15:03,010 would generate 3, 3 over here. 283 00:15:03,010 --> 00:15:05,224 And then you would generate 4-- 284 00:15:05,224 --> 00:15:06,390 yeah, that's right, just 4-- 285 00:15:06,390 --> 00:15:08,890 I'm sorry, 4, 4 over here, if you 286 00:15:08,890 --> 00:15:10,660 want to call it an interval. 287 00:15:10,660 --> 00:15:12,670 You could represent this differently. 288 00:15:12,670 --> 00:15:14,950 There's nothing that stopping you in Python 289 00:15:14,950 --> 00:15:20,590 to have these slightly more complicated representations 290 00:15:20,590 --> 00:15:23,434 where you just have 0 here as a number. 291 00:15:23,434 --> 00:15:24,850 And if it's just a number, then it 292 00:15:24,850 --> 00:15:28,360 represents an interval of length 1, 293 00:15:28,360 --> 00:15:31,090 but let's just be uniform about this. 294 00:15:31,090 --> 00:15:33,160 Usually, when you have special cases 295 00:15:33,160 --> 00:15:35,700 and if you do things heterogeneously, 296 00:15:35,700 --> 00:15:37,550 then you have more code to write. 297 00:15:37,550 --> 00:15:40,000 It might get more efficient, but there's usually 298 00:15:40,000 --> 00:15:41,200 more code to write. 299 00:15:41,200 --> 00:15:42,850 So you do 4, 4 here. 300 00:15:42,850 --> 00:15:47,680 And then you'd go up, and then you'd have 5 comma 6. 301 00:15:47,680 --> 00:15:50,500 And then you would do 7 comma-- 302 00:15:50,500 --> 00:15:52,890 I'm sorry, 7 comma 9. 303 00:15:52,890 --> 00:15:55,030 So this is the first time you actually 304 00:15:55,030 --> 00:15:59,590 have something interesting, in the sense that the interval has 305 00:15:59,590 --> 00:16:02,230 a representation that only has two numbers in it, 306 00:16:02,230 --> 00:16:05,620 whereas you actually have three people in that interval. 307 00:16:05,620 --> 00:16:07,840 And obviously, this could be arbitrarily 308 00:16:07,840 --> 00:16:13,470 large in the context of people getting into a baseball game-- 309 00:16:13,470 --> 00:16:18,640 and so 7 through 9 and then finally here 10 through 10. 310 00:16:18,640 --> 00:16:21,744 And so now you go ahead, and you count 311 00:16:21,744 --> 00:16:24,160 and you realize that there's four intervals here and three 312 00:16:24,160 --> 00:16:25,270 intervals here. 313 00:16:25,270 --> 00:16:27,820 And then you say, I'm going to go ahead and go 314 00:16:27,820 --> 00:16:33,640 with the backwards and asking the people who are-- well, 315 00:16:33,640 --> 00:16:36,460 according to you-- backwards to flip their caps so we're all 316 00:16:36,460 --> 00:16:36,960 good. 317 00:16:39,310 --> 00:16:44,710 So I'm going to show you code that implements 318 00:16:44,710 --> 00:16:46,910 exactly this algorithm. 319 00:16:46,910 --> 00:16:50,050 And while you see the code, I want 320 00:16:50,050 --> 00:16:52,540 you to think about this harder question. 321 00:16:52,540 --> 00:16:55,690 This code is going to do exactly what we describe. 322 00:16:55,690 --> 00:17:01,490 It's going to go compute all of these things, 323 00:17:01,490 --> 00:17:04,770 and as you can imagine, he's going 324 00:17:04,770 --> 00:17:07,200 to make a pass through this entire Python 325 00:17:07,200 --> 00:17:13,230 list, this group of people, this queue of people, 326 00:17:13,230 --> 00:17:15,210 and is going to do this computation. 327 00:17:15,210 --> 00:17:19,380 Then it's going to say, 4 is greater than 3. 328 00:17:19,380 --> 00:17:23,970 And then it's going to go through and start calling out 329 00:17:23,970 --> 00:17:26,400 commands for each of the backward intervals. 330 00:17:26,400 --> 00:17:32,160 So in some sense, it's going to make two passes over the list. 331 00:17:32,160 --> 00:17:35,340 So the first pass is to get all of the intervals together. 332 00:17:35,340 --> 00:17:36,540 Then there's a check. 333 00:17:36,540 --> 00:17:38,040 And then the second pass is to take 334 00:17:38,040 --> 00:17:41,880 those backward intervals, in this case, 335 00:17:41,880 --> 00:17:43,650 and call out those commands. 336 00:17:43,650 --> 00:17:45,810 So that's what I mean by two passes. 337 00:17:45,810 --> 00:17:47,379 Yeah, please. 338 00:17:47,379 --> 00:17:49,504 AUDIENCE: You don't necessarily need to count them, 339 00:17:49,504 --> 00:17:56,240 the 4 and 3 because whichever orientation interval comes 340 00:17:56,240 --> 00:17:57,450 second is always going-- 341 00:17:57,450 --> 00:17:58,491 SRINI DEVADAS: Brilliant. 342 00:17:58,491 --> 00:18:01,180 Brilliant. 343 00:18:01,180 --> 00:18:03,250 So I was going to say-- 344 00:18:03,250 --> 00:18:05,060 if you didn't understand what Ganatra 345 00:18:05,060 --> 00:18:10,930 said, wonderful because then you can think about the question 346 00:18:10,930 --> 00:18:15,250 I'm going to ask and ignore what he said. 347 00:18:15,250 --> 00:18:20,360 And then we'll get to, I guess, the more efficient code. 348 00:18:20,360 --> 00:18:24,610 But what I was going to ask was, is there a way that I'm looking 349 00:18:24,610 --> 00:18:27,580 at this, and I'm just going-- and I'm going to just start 350 00:18:27,580 --> 00:18:29,830 calling out by-- 351 00:18:29,830 --> 00:18:34,730 the moment I see that there's an interval, the moment I see-- 352 00:18:34,730 --> 00:18:36,100 this is an interval. 353 00:18:36,100 --> 00:18:40,000 And I'm going to make a call with respect 354 00:18:40,000 --> 00:18:45,040 to whether I'm going to call out a command or not. 355 00:18:45,040 --> 00:18:50,830 And I'm going to do this in one pass through this array. 356 00:18:50,830 --> 00:18:53,410 I want to do this in one pass through the array. 357 00:18:53,410 --> 00:18:58,750 I want to look at this, and I say, I see the interval 0, 0. 358 00:18:58,750 --> 00:19:01,810 Is that going to be something that I 359 00:19:01,810 --> 00:19:04,360 need to worry about in terms of that person 360 00:19:04,360 --> 00:19:08,350 having to flip his cap? 361 00:19:08,350 --> 00:19:13,189 And then I see B, B. And I say, oh, the interval is 1 comma 2. 362 00:19:13,189 --> 00:19:14,980 Is that something I'm going to have to deal 363 00:19:14,980 --> 00:19:17,140 with in terms of a command? 364 00:19:17,140 --> 00:19:21,580 And so someone else other than Ganatra, 365 00:19:21,580 --> 00:19:24,790 tell me if there's a one-pass algorithm. 366 00:19:24,790 --> 00:19:30,040 And explain to me why you can do this in one pass 367 00:19:30,040 --> 00:19:31,280 through the array. 368 00:19:31,280 --> 00:19:34,930 And just in terms of code, I'll preview this. 369 00:19:34,930 --> 00:19:37,540 The first algorithm needs-- 370 00:19:37,540 --> 00:19:40,060 according to my coding, which, isn't great-- 371 00:19:40,060 --> 00:19:41,600 26 lines of code. 372 00:19:41,600 --> 00:19:43,810 The second one needs eight lines of code. 373 00:19:43,810 --> 00:19:45,520 So yeah, go ahead. 374 00:19:45,520 --> 00:19:48,732 AUDIENCE: So after you see the first interval, 375 00:19:48,732 --> 00:19:50,890 you know that the second interval at the very least 376 00:19:50,890 --> 00:19:54,620 is going to have the same number of commands as the first one. 377 00:19:54,620 --> 00:19:56,750 So you might as well always go with the second one. 378 00:19:56,750 --> 00:19:58,600 So once you've identified what type 379 00:19:58,600 --> 00:20:01,900 the first interval is, you iterate through the list 380 00:20:01,900 --> 00:20:03,020 seeing-- 381 00:20:03,020 --> 00:20:05,695 and once you identify the first and second intervals, 382 00:20:05,695 --> 00:20:08,750 you iterate through every type of the second interval 383 00:20:08,750 --> 00:20:10,298 and do a command for that. 384 00:20:10,298 --> 00:20:11,290 SRINI DEVADAS: That's absolutely right. 385 00:20:11,290 --> 00:20:11,890 What was your name? 386 00:20:11,890 --> 00:20:12,556 AUDIENCE: Kevin. 387 00:20:12,556 --> 00:20:13,470 SRINI DEVADAS: Kevin? 388 00:20:13,470 --> 00:20:15,130 So you had it right. 389 00:20:15,130 --> 00:20:17,500 And Kevin has it right, as well. 390 00:20:17,500 --> 00:20:21,220 So the observation here is actually-- 391 00:20:21,220 --> 00:20:23,740 it was said a little bit differently by Kevin, 392 00:20:23,740 --> 00:20:26,290 but I'm going to say it a little bit differently. 393 00:20:26,290 --> 00:20:31,030 The observation is simply that if you 394 00:20:31,030 --> 00:20:36,860 look at the very first orientation, 395 00:20:36,860 --> 00:20:41,500 the very first orientation is something which, 396 00:20:41,500 --> 00:20:47,390 at best, is going to be a tie. 397 00:20:47,390 --> 00:20:53,450 So if you had it ending with 10 people, 0 through 9, 398 00:20:53,450 --> 00:20:55,910 then the number of forward intervals 399 00:20:55,910 --> 00:21:00,350 is the same as the number of backwards intervals. 400 00:21:00,350 --> 00:21:03,020 And if you went here, obviously, the number of forward intervals 401 00:21:03,020 --> 00:21:05,570 is greater than the number of backwards intervals. 402 00:21:05,570 --> 00:21:10,956 So you really only have to look at the first person in line not 403 00:21:10,956 --> 00:21:12,580 to determine the intervals because when 404 00:21:12,580 --> 00:21:13,954 you see the first person in line, 405 00:21:13,954 --> 00:21:16,115 you have no idea what the intervals are 406 00:21:16,115 --> 00:21:18,129 that are coming after. 407 00:21:18,129 --> 00:21:19,670 You have to generate those intervals, 408 00:21:19,670 --> 00:21:22,160 so you have to make your pass through the array. 409 00:21:22,160 --> 00:21:25,040 But the first person in line gives it away 410 00:21:25,040 --> 00:21:28,490 in terms of what the final result is 411 00:21:28,490 --> 00:21:33,230 going to be with respect to your decision as to what 412 00:21:33,230 --> 00:21:37,070 set of commands you're going to call up. 413 00:21:37,070 --> 00:21:42,890 And so because this is an F, you basically say, I'm going to go, 414 00:21:42,890 --> 00:21:49,400 and I'm going to make the people with the B's flip their caps. 415 00:21:49,400 --> 00:21:59,090 And that's a small observation in terms of its insight. 416 00:21:59,090 --> 00:22:02,150 But obviously, it's potent, in the sense 417 00:22:02,150 --> 00:22:05,330 that it's going to give you a one-pass algorithm 418 00:22:05,330 --> 00:22:06,560 versus a two-pass algorithm. 419 00:22:06,560 --> 00:22:08,600 And as I mentioned, it's going to give you 420 00:22:08,600 --> 00:22:13,790 a substantial reduction in the amount of code that you write. 421 00:22:13,790 --> 00:22:17,219 So I'm going to show you a bunch of code now. 422 00:22:17,219 --> 00:22:19,010 So this is usually how this is going to go, 423 00:22:19,010 --> 00:22:22,880 by the way, this entire class. 424 00:22:22,880 --> 00:22:25,850 And this is kind of my way of teaching, 425 00:22:25,850 --> 00:22:28,340 at least this type of material that's algorithmic and has 426 00:22:28,340 --> 00:22:30,330 data structures and so on. 427 00:22:30,330 --> 00:22:33,080 I like explaining to people what they're 428 00:22:33,080 --> 00:22:36,500 going to see in the code without having to deal with Python 429 00:22:36,500 --> 00:22:39,770 syntax and worrying about whether it's while loops 430 00:22:39,770 --> 00:22:42,890 or for loops and things like that and tuples or arrays 431 00:22:42,890 --> 00:22:43,970 and things like that. 432 00:22:43,970 --> 00:22:47,330 So let's get into that. 433 00:22:50,400 --> 00:22:53,530 I don't need this. 434 00:22:53,530 --> 00:22:55,900 Ah, good. 435 00:22:55,900 --> 00:23:00,270 So the naive algorithm first-- 436 00:23:00,270 --> 00:23:04,560 so what you see here is an input. 437 00:23:04,560 --> 00:23:09,310 So "caps" is simply an input Python list that has, 438 00:23:09,310 --> 00:23:12,510 as you can see from our examples, the F's and the B's. 439 00:23:12,510 --> 00:23:14,640 And so F is Forwards, and B is Backwards. 440 00:23:14,640 --> 00:23:17,100 And there are a couple of different Python lists 441 00:23:17,100 --> 00:23:19,400 so you can run them with different things. 442 00:23:19,400 --> 00:23:22,200 And all of this hopefully is not at all surprising to you 443 00:23:22,200 --> 00:23:23,670 because we went through all of this 444 00:23:23,670 --> 00:23:25,860 in terms of the pseudocode. 445 00:23:25,860 --> 00:23:28,960 So the first initialization-- 446 00:23:28,960 --> 00:23:31,980 and I can just highlight that to make it easy. 447 00:23:31,980 --> 00:23:34,050 So that's initialization. 448 00:23:34,050 --> 00:23:35,910 And this part here-- 449 00:23:35,910 --> 00:23:37,800 the comment sort of gives it away-- 450 00:23:37,800 --> 00:23:41,610 is you're making a pass through the array, 451 00:23:41,610 --> 00:23:44,160 computing the intervals. 452 00:23:44,160 --> 00:23:47,620 And so how do you actually get the intervals? 453 00:23:47,620 --> 00:23:52,240 And there's one line of code that does that. 454 00:23:52,240 --> 00:23:54,750 And oh, by the way, if there are any questions about Python 455 00:23:54,750 --> 00:23:57,590 syntax, just don't feel shy. 456 00:23:57,590 --> 00:24:00,180 Just tell me. 457 00:24:00,180 --> 00:24:02,890 Ask me a question, and I'm happy to explain it. 458 00:24:02,890 --> 00:24:06,210 I don't want to explain things that you all know, obviously. 459 00:24:06,210 --> 00:24:10,300 But if any one of you doesn't know any particular thing, 460 00:24:10,300 --> 00:24:12,810 please don't feel shy. 461 00:24:12,810 --> 00:24:15,870 Syntax is something that sometimes you even forget. 462 00:24:15,870 --> 00:24:17,460 I tend to forget things. 463 00:24:17,460 --> 00:24:21,210 So this thing here is essentially 464 00:24:21,210 --> 00:24:26,400 something that decides on what the intervals are. 465 00:24:26,400 --> 00:24:28,710 And the insight here is simple. 466 00:24:28,710 --> 00:24:32,370 You know that this interval ended when you see something 467 00:24:32,370 --> 00:24:36,440 here that is different from what the previous one is. 468 00:24:36,440 --> 00:24:37,440 So that's when you know. 469 00:24:37,440 --> 00:24:45,240 So you generate the interval when you go and find 470 00:24:45,240 --> 00:24:49,530 something that is different from the current location 471 00:24:49,530 --> 00:24:50,850 that you're pointing to. 472 00:24:50,850 --> 00:24:53,730 So that's really what's going on out here. 473 00:24:53,730 --> 00:24:59,950 In this line, you say, you're setting a "start" here. 474 00:24:59,950 --> 00:25:02,400 "Start" is your counter, and remember, "start" 475 00:25:02,400 --> 00:25:04,860 is getting set again here. 476 00:25:04,860 --> 00:25:06,519 Initially, it was set to 0. 477 00:25:06,519 --> 00:25:09,060 And if you ever get to the point where you're looking at "i," 478 00:25:09,060 --> 00:25:10,643 it's the next thing you're looking at, 479 00:25:10,643 --> 00:25:13,140 and if "caps start," which is the start of the interval, 480 00:25:13,140 --> 00:25:15,570 is different from "i," it meant that the interval that 481 00:25:15,570 --> 00:25:18,390 began with "start" ended. 482 00:25:18,390 --> 00:25:20,310 And so you essentially say, well, 483 00:25:20,310 --> 00:25:23,751 that needs to end at i minus 1 because obviously, "caps start" 484 00:25:23,751 --> 00:25:25,000 is different from "caps size." 485 00:25:25,000 --> 00:25:27,990 So this is the end of the interval right here. 486 00:25:27,990 --> 00:25:31,080 And this particular thing, our interval, 487 00:25:31,080 --> 00:25:35,240 is something that includes both these two numbers, 488 00:25:35,240 --> 00:25:36,510 so it's not exactly that. 489 00:25:36,510 --> 00:25:39,734 But it also includes-- 490 00:25:39,734 --> 00:25:43,300 where did my chalk go? 491 00:25:43,300 --> 00:25:46,930 It also includes whether this is an F or not. 492 00:25:46,930 --> 00:25:49,909 So each of these things has-- 493 00:25:49,909 --> 00:25:52,200 I'm not going to write it out for all of those things-- 494 00:25:52,200 --> 00:25:57,270 but has the orientation inside of it. 495 00:25:57,270 --> 00:25:59,370 So that's what you have out here. 496 00:25:59,370 --> 00:26:01,810 That's why we have three of these in this tuple. 497 00:26:01,810 --> 00:26:06,090 This is a tuple because it's got round brackets around it. 498 00:26:06,090 --> 00:26:09,980 I could have made it a list if I wanted. 499 00:26:09,980 --> 00:26:12,300 And so that's essentially what we have here. 500 00:26:12,300 --> 00:26:15,420 And now, here's what happens. 501 00:26:15,420 --> 00:26:19,020 In this particular piece of code, when you get to the end 502 00:26:19,020 --> 00:26:22,980 and you fall off the end-- 503 00:26:22,980 --> 00:26:28,500 so if you just end, then this code essentially 504 00:26:28,500 --> 00:26:32,940 skips over and doesn't actually put in the last interval 505 00:26:32,940 --> 00:26:34,800 because you don't see something. 506 00:26:34,800 --> 00:26:37,920 When you come up here and you're off the end of the array, 507 00:26:37,920 --> 00:26:40,320 you fall off the edge of the array, 508 00:26:40,320 --> 00:26:44,310 you don't see a B that is different from F. 509 00:26:44,310 --> 00:26:47,100 So if you just wrote that code-- 510 00:26:47,100 --> 00:26:54,810 so it's something that I'd say many people would 511 00:26:54,810 --> 00:26:56,830 have a quote, "bug," where they wouldn't 512 00:26:56,830 --> 00:27:01,500 add this part of the code here because they didn't realize 513 00:27:01,500 --> 00:27:03,750 this particular point that I made. 514 00:27:03,750 --> 00:27:07,830 And so that last interval doesn't get added in. 515 00:27:07,830 --> 00:27:09,990 And so you have a bit more code here 516 00:27:09,990 --> 00:27:13,470 that decides on the last interval. 517 00:27:13,470 --> 00:27:19,330 And then you count, and then you go ahead and call the commands. 518 00:27:19,330 --> 00:27:21,230 So this all looks good? 519 00:27:21,230 --> 00:27:23,220 Yeah, we're good with this? 520 00:27:23,220 --> 00:27:27,580 Is there a way that I could somehow 521 00:27:27,580 --> 00:27:29,515 eliminate these four lines of code which 522 00:27:29,515 --> 00:27:34,660 are a little bit annoying and just do things in the array? 523 00:27:34,660 --> 00:27:37,180 How could I, with a little trick, 524 00:27:37,180 --> 00:27:41,500 eliminate those four lines of code? 525 00:27:41,500 --> 00:27:45,610 I might need a little bit more in, quote, "pre-processing," 526 00:27:45,610 --> 00:27:46,920 but how would I eliminate that? 527 00:27:51,560 --> 00:27:52,364 Someone else? 528 00:27:52,364 --> 00:27:53,030 I'll get to you. 529 00:27:53,030 --> 00:27:53,530 Yeah. 530 00:27:53,530 --> 00:27:55,011 Go ahead. 531 00:27:55,011 --> 00:27:56,970 AUDIENCE: One way is you can check thoroughly 532 00:27:56,970 --> 00:27:59,260 you've reached the end of the-- 533 00:27:59,260 --> 00:28:00,856 the forward is equal to the backwards. 534 00:28:00,856 --> 00:28:02,070 SRINI DEVADAS: You could have an extra check. 535 00:28:02,070 --> 00:28:02,380 What's your name? 536 00:28:02,380 --> 00:28:03,250 AUDIENCE: Kanishka. 537 00:28:03,250 --> 00:28:04,249 SRINI DEVADAS: Kanishka? 538 00:28:04,249 --> 00:28:10,306 So Kanishka says that before you reach the end of the array 539 00:28:10,306 --> 00:28:11,930 or when you reach the end of the array, 540 00:28:11,930 --> 00:28:15,591 you go ahead and do a check that you've reached the end 541 00:28:15,591 --> 00:28:17,465 and generate the interval inside of it, which 542 00:28:17,465 --> 00:28:21,830 is kind of like moving this code inside of it. 543 00:28:21,830 --> 00:28:23,210 So that's reasonable. 544 00:28:23,210 --> 00:28:26,810 I'm not sure that's going to be as good as the way that I want 545 00:28:26,810 --> 00:28:29,000 and which I coded. 546 00:28:29,000 --> 00:28:31,970 Think about pre-processing. 547 00:28:31,970 --> 00:28:33,783 Think about taking the array-- yeah? 548 00:28:33,783 --> 00:28:37,010 AUDIENCE: I guess you could add a wrong interval at the end. 549 00:28:37,010 --> 00:28:38,090 SRINI DEVADAS: You could add on a wrong interval. 550 00:28:38,090 --> 00:28:38,881 What was your name? 551 00:28:38,881 --> 00:28:39,660 AUDIENCE: Kevin. 552 00:28:39,660 --> 00:28:40,800 SRINI DEVADAS: Kevin, too? 553 00:28:40,800 --> 00:28:44,090 Just how many Kevins do we have here? 554 00:28:44,090 --> 00:28:47,650 So you could do this. 555 00:28:47,650 --> 00:28:51,960 So let me show you something that's a little bit more-- 556 00:28:51,960 --> 00:28:55,620 so that was 26 lines of code. 557 00:28:55,620 --> 00:28:57,330 And so this says-- 558 00:28:57,330 --> 00:28:59,100 this is the line that's interesting. 559 00:28:59,100 --> 00:29:03,780 So I had F and B, and so I don't want to add F or B there. 560 00:29:03,780 --> 00:29:06,750 But what is convenient to do, as it turns out, 561 00:29:06,750 --> 00:29:08,880 is to just have something that essentially says, 562 00:29:08,880 --> 00:29:09,910 there's an ending point. 563 00:29:09,910 --> 00:29:14,160 So you have an explicit end to the array that is actually 564 00:29:14,160 --> 00:29:17,640 not something that would crash if you tried to access it. 565 00:29:17,640 --> 00:29:20,340 You had n people in line, and now you have effectively 566 00:29:20,340 --> 00:29:21,720 n plus 1 people in line. 567 00:29:21,720 --> 00:29:25,300 But that n plus one person is a dummy, 568 00:29:25,300 --> 00:29:27,660 or you can call them "end." 569 00:29:27,660 --> 00:29:30,600 And then if you do that, then that's it. 570 00:29:30,600 --> 00:29:33,150 The previous code works. 571 00:29:33,150 --> 00:29:35,190 You can just remove those four lines, 572 00:29:35,190 --> 00:29:39,510 and it'll all just work because your F or your B 573 00:29:39,510 --> 00:29:41,430 is not equal to "end." 574 00:29:41,430 --> 00:29:45,240 So whatever you had at the end-- 575 00:29:45,240 --> 00:29:46,440 I'm sorry. 576 00:29:46,440 --> 00:29:48,510 I'm overloading terms here. 577 00:29:48,510 --> 00:29:53,400 Whatever you had at the last element-- 578 00:29:53,400 --> 00:29:57,530 whether it was a B because it ended here or F-- 579 00:29:57,530 --> 00:30:00,150 when you equate that to "end," you're 580 00:30:00,150 --> 00:30:02,440 going to get an inequality. 581 00:30:02,440 --> 00:30:05,340 And so that last interval gets generated-- 582 00:30:05,340 --> 00:30:06,810 so small optimization. 583 00:30:06,810 --> 00:30:10,380 Tony Hoare was a very famous computer scientist-- 584 00:30:10,380 --> 00:30:12,960 said that "inside every program, there's 585 00:30:12,960 --> 00:30:15,860 a smaller program waiting to get out." 586 00:30:15,860 --> 00:30:18,690 So this is kind of one of the themes 587 00:30:18,690 --> 00:30:23,670 that I'd like to harp on in this class, which is it's 588 00:30:23,670 --> 00:30:25,620 nice to write compact code. 589 00:30:25,620 --> 00:30:28,300 Usually, if you can write compact code, 590 00:30:28,300 --> 00:30:29,502 there are fewer bugs in it. 591 00:30:29,502 --> 00:30:30,960 And you don't want to go overboard. 592 00:30:30,960 --> 00:30:33,360 You don't want too many subtleties, 593 00:30:33,360 --> 00:30:36,280 but it's nice to write compact code. 594 00:30:36,280 --> 00:30:39,210 And so this is a little bit more compact. 595 00:30:39,210 --> 00:30:45,000 And then finally, here's the one-pass algorithm. 596 00:30:45,000 --> 00:30:49,240 So the whole thing, the "pleaseConformonepass," 597 00:30:49,240 --> 00:30:55,560 is the smarter algorithm that essentially says, 598 00:30:55,560 --> 00:30:59,010 look, if I just look at the very first thing, 599 00:30:59,010 --> 00:31:03,540 I'm going to be able to skip that and then move on. 600 00:31:03,540 --> 00:31:07,230 So this is fairly complicated. 601 00:31:07,230 --> 00:31:09,030 You know the algorithm. 602 00:31:09,030 --> 00:31:11,890 Trying to map that to this code is non-trivial, 603 00:31:11,890 --> 00:31:14,640 so we'll spend a minute or two on it. 604 00:31:14,640 --> 00:31:21,570 But here's how this works. 605 00:31:21,570 --> 00:31:23,700 And by the way, just to make sure-- 606 00:31:28,480 --> 00:31:30,280 so I've repeated things here. 607 00:31:30,280 --> 00:31:34,950 So the optimized algorithm for that particular example 608 00:31:34,950 --> 00:31:36,930 produced these first three commands. 609 00:31:36,930 --> 00:31:40,320 And then the one-pass algorithm produced 610 00:31:40,320 --> 00:31:42,090 exactly the same commands. 611 00:31:42,090 --> 00:31:44,765 So this is good to do. 612 00:31:44,765 --> 00:31:46,140 It's always nice to have a couple 613 00:31:46,140 --> 00:31:48,780 of different ways of solving a problem 614 00:31:48,780 --> 00:31:51,990 because then you can verify things. 615 00:31:51,990 --> 00:31:55,980 Anyway, so this piece of code is essentially 616 00:31:55,980 --> 00:32:01,020 something that does a similar trick to what we had before, 617 00:32:01,020 --> 00:32:07,800 in terms of adding to the original list, 618 00:32:07,800 --> 00:32:09,480 adding an element. 619 00:32:09,480 --> 00:32:11,700 But we're not using "end" here. 620 00:32:11,700 --> 00:32:14,719 We're actually saying, what we want 621 00:32:14,719 --> 00:32:17,260 to do because we're going to go ahead and skip this, anyway-- 622 00:32:17,260 --> 00:32:19,160 we know we're going to skip the F. 623 00:32:19,160 --> 00:32:25,020 So whatever that is, we could just sort of add up here. 624 00:32:25,020 --> 00:32:29,560 And so that makes it easy. 625 00:32:29,560 --> 00:32:33,810 You don't have to worry about what the actual characters are 626 00:32:33,810 --> 00:32:36,060 and cooking up this "end," which is different 627 00:32:36,060 --> 00:32:38,910 from the F or the B because hey, it's 628 00:32:38,910 --> 00:32:41,880 possible that people might use whatever 629 00:32:41,880 --> 00:32:45,150 they want to represent a forward cap or a backward cap. 630 00:32:45,150 --> 00:32:46,710 So this is very clean. 631 00:32:46,710 --> 00:32:48,840 You go ahead and put exactly that over here. 632 00:32:48,840 --> 00:32:51,810 You know you're going to skip that interval because you're 633 00:32:51,810 --> 00:32:56,880 going to skip the first interval, effectively, 634 00:32:56,880 --> 00:33:01,050 because that is what the algorithm allows you to do. 635 00:33:01,050 --> 00:33:06,690 And then this part here is doing what we had before. 636 00:33:06,690 --> 00:33:08,510 We're not even generating the intervals. 637 00:33:08,510 --> 00:33:11,340 We're just directly making the commands. 638 00:33:11,340 --> 00:33:15,390 So there are no tuples in terms of the tuples 639 00:33:15,390 --> 00:33:17,880 and the appending of the intervals data structure 640 00:33:17,880 --> 00:33:18,450 that we had. 641 00:33:18,450 --> 00:33:20,040 It's all gone. 642 00:33:20,040 --> 00:33:23,760 I'm just going to go ahead and fire off these commands. 643 00:33:23,760 --> 00:33:30,540 And those commands are written in kind of a funny way 644 00:33:30,540 --> 00:33:35,070 because I'm going to go ahead and if I 645 00:33:35,070 --> 00:33:36,450 wanted to print these things out, 646 00:33:36,450 --> 00:33:38,520 you'd have to do this in this funny way. 647 00:33:38,520 --> 00:33:40,960 If you're willing to wait and collect up the intervals, 648 00:33:40,960 --> 00:33:42,390 you can certainly do that. 649 00:33:42,390 --> 00:33:45,270 But this is absolutely the most compact code 650 00:33:45,270 --> 00:33:49,350 that I could think of, and I'm printing a command 651 00:33:49,350 --> 00:33:51,510 in two different parts. 652 00:33:51,510 --> 00:33:54,270 I'm printing the first part of the command that says, 653 00:33:54,270 --> 00:33:56,970 people in positions. 654 00:33:56,970 --> 00:34:00,450 And that's the start of the interval "i," 655 00:34:00,450 --> 00:34:02,710 and I'm just using a Python construct. 656 00:34:02,710 --> 00:34:07,590 This "end" here is something that the print command 657 00:34:07,590 --> 00:34:08,429 can recognize. 658 00:34:08,429 --> 00:34:10,560 And this simply says, don't give me a new line. 659 00:34:10,560 --> 00:34:11,909 I want to print it exactly. 660 00:34:11,909 --> 00:34:14,130 As you saw from when I ran the code, 661 00:34:14,130 --> 00:34:18,810 the printing was exactly the same as the original algorithm. 662 00:34:18,810 --> 00:34:21,780 And so this "end" simply says, don't print a new line 663 00:34:21,780 --> 00:34:24,590 at the end of people in positions, 664 00:34:24,590 --> 00:34:25,650 whatever this number is. 665 00:34:25,650 --> 00:34:26,969 Call it 7. 666 00:34:26,969 --> 00:34:28,800 And you don't print the new line. 667 00:34:28,800 --> 00:34:32,520 And then you have a space here because you didn't 668 00:34:32,520 --> 00:34:34,770 print a new line or a space. 669 00:34:34,770 --> 00:34:37,770 And you go through i minus 1, which is exactly the same 670 00:34:37,770 --> 00:34:38,940 as we had before. 671 00:34:38,940 --> 00:34:42,449 You only discover that the end of an interval after you 672 00:34:42,449 --> 00:34:46,889 see the person that comes after the interval. 673 00:34:46,889 --> 00:34:48,909 So you have to go back to i minus 1. 674 00:34:48,909 --> 00:34:50,790 So this makes sense? 675 00:34:50,790 --> 00:34:53,250 Any questions about this code? 676 00:34:53,250 --> 00:34:54,296 Yeah, go ahead. 677 00:34:54,296 --> 00:34:55,670 AUDIENCE: So the first line, like 678 00:34:55,670 --> 00:34:57,980 you said, if we're going to move the first-- 679 00:34:57,980 --> 00:35:00,249 SRINI DEVADAS: Not move, duplicate-- 680 00:35:00,249 --> 00:35:01,540 AUDIENCE: Duplicate the first-- 681 00:35:01,540 --> 00:35:02,373 SRINI DEVADAS: Yeah. 682 00:35:02,373 --> 00:35:05,030 So the plus there is a concatenation, 683 00:35:05,030 --> 00:35:05,990 and you have two lists. 684 00:35:05,990 --> 00:35:07,310 "Caps" is a list. 685 00:35:07,310 --> 00:35:11,170 And when you use a plus operator in Python, 686 00:35:11,170 --> 00:35:14,420 you can only add things that are of the same type. 687 00:35:14,420 --> 00:35:17,990 And so "caps" is a list, and "cap 0" 688 00:35:17,990 --> 00:35:19,710 is an element of the list. 689 00:35:19,710 --> 00:35:21,500 And so you need to make it a list in order 690 00:35:21,500 --> 00:35:23,342 to use the plus operator. 691 00:35:23,342 --> 00:35:25,550 There are also other things you could do using a pen, 692 00:35:25,550 --> 00:35:26,574 for example. 693 00:35:26,574 --> 00:35:28,990 So you could take that line, and you could do "caps start" 694 00:35:28,990 --> 00:35:30,229 at "pen" "cap 0." 695 00:35:30,229 --> 00:35:32,270 And you wouldn't need all of the square brackets, 696 00:35:32,270 --> 00:35:34,330 but that's just neither here nor there. 697 00:35:34,330 --> 00:35:36,820 But I'm obviously not answering your question, so go ahead. 698 00:35:36,820 --> 00:35:37,320 Yeah. 699 00:35:37,320 --> 00:35:39,248 AUDIENCE: So I was going to say that we 700 00:35:39,248 --> 00:35:40,435 skip the first interval. 701 00:35:40,435 --> 00:35:43,134 And then we flip all the second-type orientation. 702 00:35:43,134 --> 00:35:44,300 SRINI DEVADAS: That's right. 703 00:35:44,300 --> 00:35:46,210 AUDIENCE: But here, we're focusing on the first element. 704 00:35:46,210 --> 00:35:46,710 Why-- 705 00:35:49,190 --> 00:35:52,640 SRINI DEVADAS: Ah, but that's OK because remember, 706 00:35:52,640 --> 00:35:57,830 the if statement is going to skip this one, too. 707 00:35:57,830 --> 00:35:59,690 So if I had two F's in the beginning-- 708 00:35:59,690 --> 00:36:01,220 I think your question is, what would 709 00:36:01,220 --> 00:36:04,905 happen if I had two F's or three F's in the beginning? 710 00:36:04,905 --> 00:36:07,280 So I'm going to go ahead, and first thing I'm going to do 711 00:36:07,280 --> 00:36:09,530 is I'm going to put an F at the end here, 712 00:36:09,530 --> 00:36:11,310 and then maybe there's a bunch of stuff. 713 00:36:11,310 --> 00:36:14,750 But then the nice thing is that I'll skip this F, too, 714 00:36:14,750 --> 00:36:20,780 because the not equal to is not going to fire. 715 00:36:20,780 --> 00:36:25,220 The next line, the "caps i not equal to i minus 1," 716 00:36:25,220 --> 00:36:27,512 this is going to be equal to. 717 00:36:27,512 --> 00:36:29,720 So I'm going to go ahead and go to the next iteration 718 00:36:29,720 --> 00:36:30,770 of the loop. 719 00:36:30,770 --> 00:36:31,910 That makes sense? 720 00:36:31,910 --> 00:36:34,770 Did people understand Fadi's question? 721 00:36:34,770 --> 00:36:36,740 It was a good question. 722 00:36:36,740 --> 00:36:41,630 So the question was, you skipped the first one. 723 00:36:41,630 --> 00:36:43,970 But what is making you skip this one because you want 724 00:36:43,970 --> 00:36:46,280 to skip the first interval? 725 00:36:46,280 --> 00:36:50,580 And so that if statement is making you do that. 726 00:36:50,580 --> 00:36:51,080 Good. 727 00:36:51,080 --> 00:36:53,587 So as you can see, even a fairly straightforward puzzle-- 728 00:36:53,587 --> 00:36:55,670 this is the simplest puzzle we're going to do here 729 00:36:55,670 --> 00:36:57,610 is the first one. 730 00:36:57,610 --> 00:37:01,830 And there are nuances associated with how you solve it 731 00:37:01,830 --> 00:37:03,980 but also how you code it. 732 00:37:03,980 --> 00:37:06,080 And this is kind of-- 733 00:37:06,080 --> 00:37:12,960 like I said, this was my eureka moment a few years ago, 734 00:37:12,960 --> 00:37:15,380 where I said, I think the way you 735 00:37:15,380 --> 00:37:17,790 want to teach programming, at least 736 00:37:17,790 --> 00:37:21,560 some aspects of programming, is in this fashion. 737 00:37:21,560 --> 00:37:22,550 Anyway, good. 738 00:37:22,550 --> 00:37:25,100 So we're done with this. 739 00:37:25,100 --> 00:37:27,540 Any questions about this puzzle? 740 00:37:27,540 --> 00:37:28,040 All right. 741 00:37:28,040 --> 00:37:29,590 Good.