 So, we will continue our discussions on building iterative solutions. Last time we saw a glimpse of how a counted number of iterations could be implemented. While we could do so by using a counting variable, initializing it ourselves and then incrementing it within the while, and also checking for the count remaining within the prescribed boundaries as a part of the while condition, we could do all of that, but we saw a separate instruction made available in C++ called FOR statement. We shall look at FOR statement in some greater details today. We will use it to build a solution for estimating the value of log of A. We will also look at another interesting computational problem, which has a iterative as well as recursive solution. We have not heard the term recursion so far, we shall define it later in the course. This is about Hemchandra numbers. We will end the lecture by looking at an alternative form of conditional evaluation called a question mark operator. So, here is the theme, which we looked at briefly in the last lecture. Namely, we want to execute a block of statements, a fixed number of times. So, how do you do that easily? We had said that we need something to count, and that could be a separate variable. Let us say count, we could initialize this variable to 1, for example, outside the body of iteration, that is to be executed repeatedly, and then every time we execute the iteration, we can increment this count by 1. This way, count will go from 1, 2, 3, 4, 5, etc., as many number of times as you want to iterate the block, and therefore a condition should be checked every time you execute the iterative block, whether the iterative block should be continued to be executed or we should stop. So, we specify that we would like to continue iteration only if count is within limit. This repetitive execution by counting is facilitated in C++ by a separate statement altogether. This is a curious statement because in a single statement, there are three different specifications. While these specifications are given at a single place, wherever you write the four statement, all the three specifications are given there. However, the implication of these three specifications does not occur at the point where they are written, and that is why it is important to understand what these three actions stipulate and where these actions are executed. First, the statement, if I want to execute some body of iterative block, say five times, then I could specify it by saying 4, count equal to 1, semicolon, count less than equal to 5, semicolon, count++. Observe that in a single parenthesis, we are actually giving three independent statements. All these three are part of the four specification. After that, like in a high loop, we write an opening curly bracket, write the statements within the iterative block below that, and end the curly bracket. So, rest of it is very similar in syntax to why, where the difference is in the specification of the foresight. The implication of these three statements is important to understand. This statement says initialize the count before beginning the first iteration. That means the first action that we have stipulated in form is not executed here. It is executed before the body is entered into. In fact, not only that, then at the beginning of each iteration, the condition is checked, which is stipulated by the second specification. The second statement will have a condition which will be checked. Like the wild statement, if the condition is true, you will enter the iterative block. If the condition is false, you will get out. But what the fourth statement additionally does is, after completing the execution of statements within the iterative block, it will execute the last instruction which is the increment. So, it will change the count by what? And then come back again to check this condition. So, for example, if you were to write while, you would have written while count less than equal to five, all of this. That's all you would have written because you would write only a condition there. But in the fourth statement, you also stipulate the initial value of the count and you also stipulate an additional action which is done over and above the statements within the iterative block, which is after executing these statements, additionally execute the last instruction here, which is count plus plus. This then is a program which will find out the maximum of five numbers. Observe that when I have to find out maximum of five numbers, I need to iterate my block which I had identified earlier. Namely, read a number, compare it with max and if it is better than max, replace max with that number. This is the body of statements that I wish to iterate. So, this I want to iterate five times. I start by defining the variables x, max and additionally count. This was not required in our earlier implementation. I start with an artificial value of max equal to zero. That is because if you recall, we had said that this is a program which will find out maximum of given five positive integers and therefore zero is unlikely to be a value and in fact it would be the lowest value. So, it is all right to start with the artificial value of max which is zero. Observe this statement. For count equal to one, count less than equal to five, count plus plus. The iterative block then starts which says enter the next positive integer, input x and if x is greater than max, max is equal to x. The closing curly bracket ends the false statement. So, this is the scope of the false statement. After this, if I come out, I will execute this statement which is just an output saying maximum is so and so. There are some modifications that we can do. For example, the reason why we had introduced this max equal to zero was because we wanted a starting point. That is first time when you execute the iteration and compare x greater than max, max should have some value. Remember that that time, this statement was at the beginning of the loop. However, with this arrangement of my iterative block where I am reading a number and comparing it with max, this does not appear to be necessary. I can, for example, read the first number separately outside the iteration block and set that to max and then execute this iteration only four times. It will still correctly give me the result. As an added attraction, there is now no limit on the numbers. It need not be only positive integers. It could be any value because max is not being set to any artificial value. It is being set to the first value that I read. This incidentally is the flow chart for the for loop that we saw. It is instructive to look at what this statement does. For count equal to one, count less than equal to five, count plus plus. This is the specification. So let us look at the flow chart once again. This flow chart very much looks like the wild statement. While count is less than equal to five, keep on doing this. And the moment count becomes greater than five, come out. That was the implication in our wild statement. But the three specifications that you have included in the for statement work as follows. The first specification says count equal to one. Observe that count equal to one is executed as an additional instruction before the for statement begins. This condition is where it would be in the wild statement also. This is the loop termination condition. So I was telling you about the three specifications in the for statement. Count equal to one is executed even before anything related to for is done. That is the initial action. This condition is exactly like the wild condition. And it is the second part of the for specification. It is the third part which is interesting, which did not exist in wild at all. This is the iterative block. Input a value of x is x greater than max, set max to x, otherwise do nothing. Ordinarily we would have come back. In the for statement, an additional statement is inserted by the compiler at the end of this iterative block. And this statement says count is equal to count plus one. So this is the increment action which happens every time the iteration is executed. I have said count equal to count plus one, but there is no harm if you wanted to increment count by two for example. In fact it is up to you to decide what is the initial value you choose. What is the increment that you choose and what is the condition that you choose. All three together will determine how many times the iterative block is executed. And you have to be very careful in describing those conditions appropriately as one of the three specifications. As long as you do that, that's fine. Suppose I want to generalize this further by reading a number. So I say c in greater, greater number, max is equal to number. And then for count is equal to one, count less than equal to four, count plus plus. I read another number and check that against max. So this is what I said. If I have five numbers from which I have to calculate the maximum, I need not run the iteration five times. I will read the first number separately, artificially assign it to max because that is indeed the maximum so far. I have read only one number so that is the largest amongst one number. So that is also correct. In fact, if you give only one number to this logic, it will still find the correct maximum. You can extend this very easily if you are given say n numbers. Where do these things occur? Requirement of specifying, find out the maximum or average or something of n specified values. I think I have given you an example. Take the mid-same exam of this course itself. There are some 574 or so students. Let's say two or three students don't appear for the exam for some emergency. So there are 571 students who take the exam. Now I have marks of those students and I want to find out what are the maximum marks scored by anyone. So I would know in advance that I am giving marks for 571 students. As a result, instead of putting artificial condition of when the input ends etc., I would like to write a program which will read marks for specified number of students. In general then I would like to find out maximum of n given numbers. And using this counting iteration control, I can very easily do so. This is the program for doing that. Find out maximum of n given integers. In fact, they need not be positive integers. They need not even be integers. They could be floating point values as well. Notice that if there are marks, then somebody will score let's say 25.5 out of 30. Somebody will score 17.5. So there could be fractional marks. And to account for that, you would not like integers to be specified. Here is the main program. Apart from number which I am reading and n which is the number of numbers and max which will contain the final maximum value found, I am additionally declaring count. You must note that while I am going to use count in the for specification, it is exactly like any other variable. And I must declare that variable to be integer, float or whatever. Ordinarily for counting purposes, floating point values don't make sense because they rarely match the exact decimal integer values. And therefore you will always use integer for counting. So look at this specification. How many numbers I input n? Then the program says give first number. I input a number. I assign that to the maximum because that is the maximum found so far. Now I set up an iteration which goes from 1 to n minus 1. Observe this specification carefully. In fact, I could have been more candid and said for count equal to 2 to count less than equal to n. Specifying that the first number has already taken in and second to n are the numbers that I am reading. However, the serial number of the number itself which is being read is not very relevant. As long as I read n numbers and find out the maximum, so this will work alright. Within the iteration block, I am asking you to give me next number. I read that number and if number is greater than max, I set max to number. So very simple algorithm, very simple program. At the end, this is the end of the fall loop, which is exactly like the violet. So I hope you have understood how to use the fall statement. Whenever you have anything to count, you will do that. Last time I had also suggested possible usage of such counting and I had taken an example of if I want to add areas of say large number of rectangles where each rectangle has different area, differing area. But if I know how many rectangles I want to add areas of, then I could set up a counting mechanism. We will now look at a numerical problem which precisely does that. Before looking at the problem, this is the general specification for the fall statement. I don't know how many of you are aware of the word semantics. Semantics actually means meaning. Syntax is the grammatical way in which you write these statements. So where to put semicolon, where to put comma, where to put the word for, where to put violet, where to put brackets, braces. This is called syntax. So your program must be syntactically correct. Otherwise the compiler will throw it out giving errors. However, if your program is syntactically correct, that means compiler compiles it and translates it to a.out, it does not mean that it will behave correctly. For that, the meaning of individual statements must be correctly understood and that meaning must be correctly implemented. Because C++ compiler understands one specific meaning of every statement and as long as you have understood that meaning, then your programs will be correct. So this is the meaning or semantics of the fall statement. This is the most general form. But then these three specifications as xxx, yyy, zzz. As we can see later, these could actually be very general statements. Although we will mostly be using them in the context of counting. Z, www represents the body of the... It could be one statement in which case I don't need to write the opening curly bracket and closing curly bracket because that one statement will be taken to be the body of the fall loop. In general, as we have stipulated, it would be a good idea always to write these brackets so that the body is isolated from other things. So this is a comment along the first line. It says three independent loop specification statements. These are the three independent loop specification statements. And www is statements in the body of the loop. This is precisely what happens. So I have tried to put in words the general flow chart that we have seen in the context of that particular problem in the context of this generalization now. The 0th action is execute xxx. Note that while the program is executing, the fall statement physically appears somewhere later but xxx is executed just before the fall statement. That is the initialization like count equal to r. This is called loop initialization. Then when the fall statement is encountered, only condition yyy is evaluated. This is called the loop test. And the semantics is if true, continue with step 2. If false, execution of false statement ends, control goes to step 5. Step 5 is the next statement after the body of the fall has ended. If the continuation is what is dictated by the loop test, then you will execute www which is the loop body. So you will come here and execute it. And after executing this, but before going back, you will execute zzz which is the increment condition called loop increment. And after doing that, you will go back and repeat from what. I hope it is crystal clear how the for loop works. Here is another program to find out some of n natural numbers. When I am summing up n natural numbers, I don't require any input because I know natural numbers 1, 2, 3, 4, 5, 6. There actually exists a very cute, simple formula for finding out the sub. So you will get n into n plus 1 by 2. However, since you have a computer at our disposal, we will let it do some Godagiri and work it out the harder way. So we start with sum equal to 0 because we are finding your sum. So initial sum is 0 and we keep adding to it the natural numbers. If I have to sum n natural numbers, I will read the value of n and I will simply set up a loop for 1 to n. I have used i equal to 1, i less than n, i equal to i plus 1. Will this give it correctly? Yes, some people are attentive, some others are taking it for granted that everything written here is right. How many times will this loop execute? Sum is equal to sum plus i, n minus 1. So this sum of n natural numbers is incorrect. It will find sum of n minus 1 natural number. If I want to find out for n natural numbers, what I must do? I must say i less than equal to n or i less than n plus 1. This is important because invariably the mistakes in specifying your form are not in multiple places. They are only about either missing one iteration or executing one extra iteration. 90% of the mistakes in using form happen there. Either you do one extra iteration or you do one less iteration. So you should be very, very careful in examining that based on the initial value that you have given, based on the increment that you have given, and based on the condition that you have given, is your loop executing proper number of times or not? And that should be manually sort of checked. If there are variables like n, you can give some value of n. I mean this is a straightforward case where all of you by inspection can say this is wrong. But there could be situations where you have some very odd initialization, some very odd incrementing action, and some complex condition. The condition, by the way, need not be only in terms of n. The condition could be i less than n and x not equal to 0 or y equal to something. That is perfectly fine. That is the general form of false statement. The second specification is the condition. As long as that condition is valid, iteration will be continued. The moment condition is false, you will get out. And there is no reason to believe that condition can be only in terms of counting. So this is another important message that you should carry. While the false statement is primarily intended for controlling iteration by counting, the conditions need not be related only to counting. We shall see some examples later where we can combine such conditions. But further time being, we will use it for counting. And there we note that we have to be very careful in ensuring that the iteration is executed correct number of times. So here is the problem that I wanted to discuss. Find out natural logarithm of a number. All of you know the definition? Everybody knows integration 5. So integral 1 upon x dx between the limits 1 to a is the definition of logarithm, natural logarithm, log of a to the base e. Either you should know integration. That means you should have well formed expression equation inside, not equation, well formed function definition inside the integral. Or you could attempt to find this out numerically. If we are going to use a computer, since it cannot integrate, we must use arithmetic operations. Now there is a method of estimating this value of this integral by realizing that this integral is nothing but area under this curve between x coordinate 1 and x coordinate a. You are familiar with this notion integral represents the area under the curve between the two limits. If that is so, can I estimate the area? Now this curve is 1 by x, it is well behaved curve. But in general there could be any arbitrary curve. And it would not be easy to estimate that area. So we do that by dividing the area under the curve in a number of rectangles. Because rectangle area is easier to calculate, height in two ways. Now suppose we divide the area under equal width rectangles, in equal width rectangles. So we take 100 rectangles in this interval and calculate the area of each rectangle. The width is same, the height will depend on what? The height will depend upon the function. Because one of the edges of the top edges of the rectangle will be at the function point. Because that is what is the approximation. With this approach then we proceed to evaluate an estimate for the value of log a. This incidentally is known as Riemann integral. So the Riemann integral, the process is that you divide the area under the curve in number of rectangles and find out the sum. I have shown here the number of rectangles like this. There are only five there but there could be as many as you wish. And what do you do now? For each rectangle you estimate the area of that rectangle. If you add them up, the sum of these areas will be a fair approximation of the area under this curve between one and a. Notice that in this magnified diagram you will see such butting triangular portions at the top of the rectangle. These are obviously not part of the area that we want to estimate. We conclude two things. One, our estimate will be wrong. In fact it will be less than the final value because of the nature of this curve. And that is happening because of these triangular areas which are... Oh sorry, more, more, not less. Very good. It will be more than the correct value because of the extra areas that we are counting as part of our area estimation. However, we can reduce the area of each such portion by making the width smaller and smaller and smaller. If we do that, then our estimate will be more accurate. So rather than taking five rectangles, I may take fifty. I may take five hundred. I may take even thousand. With that approach now, I try to estimate the areas. First I have to calculate what will be the area of any one rectangle. So I notice that if I have divided the area in equal width rectangles, the width w of any rectangle, if there are n rectangles, will be equal to a minus one by n. a is this value on x axis. What is this value? a minus one divided by n is the width of every rectangle. Further, let us say this is the ith rectangle. Now what will be the height of this rectangle? The height of this rectangle will be equal to the value of this function at this point. So I need to know the x coordinate of the leftmost corner of any rectangle. Note that we have to write a generalized statement because we want to build an iteration. An iteration requires a generalized statement. Therefore, I will always consider in a series of rectangles of varying sizes an ith rectangle as a representative rectangle. And I will determine the necessary coordinates, height, width, etc. for the ith rectangle. If this is ith rectangle, then I claim that the value of the x coordinate of the bottom left corner is one plus i minus one w. I can verify this. This is the first rectangle. It begins at one. This is the second rectangle. It begins as one plus w. If there is a third rectangle, it will begin at one plus two w. That means if it is an ith rectangle, it will begin at one plus i minus one w. Note that you are looking at a sort of solution which is being presented to you. But in general, when you are attacking a problem, you will have to construct this formula. This formula will not be ready made. So you will have to figure out what is the x coordinate. And why are you finding out x coordinate? Because the value of the function at this x will give you this point. So what is the height of this rectangle? The height of the rectangle is the function value at x. And that is one upon x. And that is nothing but one upon one plus i minus one w for ith rectangle. So now I got ith rectangle height. I got ith rectangle width. I multiplied these two. I got some. If I do that for every rectangle, for i equal to one to one thousand, and sum up every area in a variable called sum, I will get the final value. So we now consolidate all of our reasoning. The problem is estimate the value of log a. We are using Riemann integration. So we start with how many rectangles? More than a year I have said, thousand. This choice is not forced by the statement of the problem. And this is another important thing I would like to mention very specifically. In general, in the high school, the kind of problems that you have solved are well specified problems. Most of them have unique answers. You have to apply some formula, do some calculations, whatever. In engineering and applied science, the real life does not present you with opportunities to come up with exact answers ever. Every real life problem, therefore, will not have unique answers. There will be multiple answers possible. And these multiple answers will come about because of different assumptions that different people will make. I have made the assumption thousand. One of you might say, no, no, no, this thousand does not seem appropriate. Let me use ten thousand. Somebody else may say, let me sum up one million rectangle areas. What should be the correct value? Is there any notion of the correct number? There is none. And therefore all such assumptions made will be correct assumptions provided they can be justified on the basis of logical common sense which is what you have to use in applied science and engineering where approximation is the order of the day. No computational problem has exact solutions. Now you will all agree that if I say, I will use seven rectangles. You will agree that it will not give you the best of the results and therefore there is something wrong with the way somebody has made that assumption. You will also agree that if somebody said, I will use 222 billion rectangles. What could be the problem? Well, I know the limitation of my machine. In a four byte integer, I can't count up to 220 billion. But then I will say, let me use floating point counter. The point is, forget the counting. The accumulation of sum that you are doing will not change at all after certain terms because the floating point errors that will happen in the representation of mantis and exponent. So those values will be trivial and therefore they will not be useful. Anyway, the point being made is that you will have to make such assumptions and you will have to state those assumptions with justification in any solution that you find out for computational problem. So we say 1000. All right. The width of all rectangles taken together is A minus 1. The width of individual rectangle is A minus 1 by 1000. X coordinate of the bottom left corner of Ith rectangle is X is equal to 1 plus I minus 1W. Height of the Ith rectangle is 1 by X which is 1 upon 1 plus I minus 1 into W. And area of this rectangle is therefore height into width which is this into this. So far so good. Please note again that you will have to construct this logic yourself. In this case, you are being presented with this logic. Suppose the function was different, not log X. You will agree that you can apply this Riemann integration technique to find out integral of any function between limits because the same technique will work. As a matter of fact, if you use it for arbitrary functions which might have undulating curves, then the positive and negative portion of those rectangular areas might negate themselves and you may automatically get a much more accurate result. So these are some of the things that you should keep in mind. The point is that whatever is the function, you have to accordingly calculate the height because height is determined by the function value at that point X and then calculate this area. Here is the program to compute logarithm. Notice how simple the program is actually. So I defined A as float because the value A could be a floating point value. I defined area also as float and initialized it to 0 because I am going to accumulate the sum of the areas in this variable area. I have W which replace the width. I asked the user to give number whose logarithm is to be found and read the value of A. I calculate the common width which is A minus 1 by 1000. I could, by the way, parameterize this program further by saying give number of rectangles which you want to use in your estimation and read another number say L and I could divide this by L. So that generalization is trivial extension of whatever has been written. Just one extra statement. Having done that, I have this famous for loop. For I equal to 1, I less than equal to 1000, I equal to I plus 1. Notice again that where I have written I equal to I plus 1, you could write I plus plus or plus plus I. This is in fact one of the most valid usage of the post and pre increment and you will notice that it doesn't matter whether you use plus plus or I plus plus because anyway this entire specification is going to be executed only after one iteration is over, second iteration is over and so on. And the net impact will be to increment I before you come back to check this condition. The loop itself is a simple statement, just one statement. Area is equal to area plus W star 1 by 1 plus I minus 1 into W etcetera. And at the end I say log of A is this area. In a simple program of less than 10 lines, you are able to calculate Riemann integral and therefore estimate logarithm A. And whether you make the machine work million iterations or thousand iterations, the length of the program does not change. So the number of instructions that you have to write to make the machine do lot of work do not increase in proportion to the work that you are making the machine do. That is the beauty of iterative controls. If you can't build iterations, then you can't really make concise programs, smaller programs to make computer do more work. So this is clear, yeah. Sir while assigning the area, float A comma area equal to 0, if I write only float A comma area comma W, then after this statement is executed area equals to area plus something something, what will be the error in that case? Yes, he is saying that if I don't initialize the value of area, actually let me generalize the question. In any question where I am accumulating some or product or any such thing, if I don't start with the initial value, what will happen? The machine will come here. For the first time when it comes here, it will try to calculate this expression. This expression on the right hand side says area plus something. That plus something is well calculated, but area plus something means use the present value of area. Suppose the memory that is allocated to area contains 50,000 other value, then the first statement executed will be 50,000 plus this and to that you will keep on adding other things. In fact, one of the cardinal principles of programming is I shall never use a variable in an expression, never unless that variable has been assigned a value. Either that value would have been assigned by previous assignments such as this or they should have been initialized by me. If that is not done, the program is erroneous. As a matter of fact, its behavior would be different every time you run it. You compile it and keep it. Today you run it, you will get some value. Tomorrow you run it, you will get some other value. At the cost of a minute, I will quote a very funny incident when we had a man-fram Russian machine and a PhD scholar who did not believe in Russian equipment and used to constantly get errors in his programs, used to complain bitterly till people told him the errors in his program which then he would correct and again run the program and whenever he won't get results, he would shout at the computer and the people who run it, namely me and my colleagues. One fine day he came and he says, see Fadak I told you these Russian machines you should not put faith on. Say what has happened? Now this time I am correct. I have not changed my program, but I run it yesterday, I get one result, I run it today, I get another result. This is black magic, this is not computer. He had a 3009 photon program and it took quite some time to figure out that he had not initialized the value. So the machine was picking up whatever trash value was there in that location and obviously between his first run and second run there were many programs which were executing and possibly using that memory location, he got funny results. So net result, never ever do that. So what will happen is a good question out of curiosity but if that happens the programmer is to be blamed because he is using some variables in an expression which have not been previously assigned values and that is programmer's responsibility to ensure that. And so this program is of integration 1 by x. So how you will find log? That is the definition of log. The definition of logarithm of A is integral 1 by x between the limits 1 to A. This is another program which finds out the factorial of a number. All of your familiar factorial I suppose, 1 into 2 into 3 into 4 into so on up to n. The main difference is that while finding out some of n natural numbers or any summation for finding out any summation I usually initialize the accumulated sum in a variable which is initialized to 0. Then I am accumulating a product. I can't start with 0. So I start with 1. That is the difference here. n factorial which is a variable which will accumulate the factorial value by continuously multiplying itself with 1, 2, 3, 4, 5, 6, etc. I can't start with n factorial equal to 0. I must start with n factorial equal to 1 which happens to be the factorial of 1. And then I set up an iteration which moves from 2 to less than equal to n. n factorial is equal to n factorial into r. When I come out, I say factorial of n is n factorial. You agree that this program will work correctly? Now people are looking at it. Find out errors in this program. One at a time please. No errors? I claim that the program will not compile at all. Semicolon is there after curly bracket. Is that the only reason? Yes. Somebody said n. I am saying factorial of n. I have not declared this as a variable. See compiler is case sensitive. This n is not same as this n. So two errors located, but there is a logical error. The two errors are this n should be small n and the second one, the semicolon should not be here. Actually the semicolon is not harmful. You can try and write several semicolons in succession. See compiler will usually treat that as a series of null statements. But that's okay. It is still incorrect to write it that way or improper to write it that way. So I take it as a correct observation. Okay. So the only two errors program will work correctly. n should not be negative. Okay. So I should actually check n itself when I read n. But suppose n is not negative. Will it always work correctly? Okay. n is not 0 also. Then it will work correctly. Okay. No. What if n is 1? i is equal to 2. i is less than equal to n. If n is equal to 1, this condition will be false at the initial time itself. So it will work correct. So we note one additional logical insertion program that we must make. Namely, validation of the input. If somebody has given n as input and if the problem is of finding out n factorial, it does not make sense if I have n as negative. However, if n is 0, it is still okay because factorial 0 is defined as 1. So I will still get the correct answer. In fact, factorial 0 and factorial 1 are both 1. So that does not carry a problem. But n must be checked for being non-negative. If we don't check it, the program will apparently give wrong results. We now come to another interesting computational problem. As I mentioned to you, this problem actually can also be used to introduce the notion of recursion. A word which we will not discuss till the mid-same exam. We will discuss recursion only later, although it happens naturally in real life. But we will look at this problem from the point of view of building an iterative solution. Here is the problem. I have to build a wall with length 8 feet and I have bricks. One is 2 feet long and one is 1 foot long. Just 2 types of bricks I have. Nothing more. The question that is being posed, it's a mathematical question. In how many ways can I lay the bricks so that I can fill the 8 feet? Now if I have a length 8 feet to be filled by bricks of 2 types, there are various possibilities. I can use 4 bricks of 2 feet length. I can use 8 bricks of 1 foot long. I can use 3 bricks 2 feet long and 2 bricks 1 foot long. The issue is how many such combinations exist which are possible. This problem was actually, Ben Chandler was a mathematician 12th century AD and the problem that he looked at was actually a problem on musical beats. Suppose I am designing a poetic meter with 8 beats. Now poetic meters are made out of short syllables and long syllables, much like a short brick and a long brick. The short syllable is 1 beat, long syllable is 2 beats. In how many ways can I prepare this meter of 8 beats? By the way, I don't understand music as much as many of you would. So this example is constructed by Professor Abhiram Ranade and I am just using those slides. It's a very interesting way of looking at a mathematical problem in a poetic way. So here, given this example of a rather well-known Sanskrit poem of Ya Kundendu Tushar Haardavla and shown that these are the poetic symbols that will be used there. In any case, the mathematical problem is very simple. Mathematical problem is how many ways can I construct a poetic meter which has 8 beats? Some short, some long. And what he contended is that by using the method of Pingala it is enough to observe that the last beat is longer short. He says it does not matter what the earlier beats are. The total number of classes is divided upon by just looking at the last beat. And he attributes this solution to a sutra which was given by a mathematician who lived in 500 AD called Pingal. So this is now, these are known as Hemchandra-Pingala numbers. These are the Indian mathematicians of repute who have actually worked out this sum. What is important and I agree entirely with Abhiram, I mean Professor Ranade, illustrates the point that Hemchandra is giving credit to someone who lived hundreds of years before him. Moral for us, copy if necessary and if permitted. But always give credit. We rarely do that. You might be tempted in your stay in IIT to copy an assignment from a friend because you don't have time. But you should have decency to write at the end. Copy from so and so. The keyword in this dialogue is not copy if necessary. You might remember just this. And if permitted, that is important. Anyway, so let's go back to the Hemchandra solution. The solution says consider S to be the class of 8-bit patterns with short last beat. Remember Pingala Sutra says that you have to look at only the last beat. So now if you look at all 8-bit combinations that can occur, permutations that can occur with short and long syllable, some will have short last beat and some will have long last beat. Now, each 8-bit pattern is either in class L or class S. So I write S as all 7-bit patterns plus one short bit appended. Notice that classes can have only this. All possible 7-bit patterns and one short bit because that is the last short bit. On the other hand, the class of 8-bit patterns will be such L will be all 6-bit patterns plus long bit appended. So when I append a long bit, there can be only 6-bit prior to that. Total have to be 8. And when I have short bit appended, then there have to be 7-bit prior to that. So consequently, the number of elements in classes is the number of patterns with 7-bits plus one short bit. That means the number stays the same. So you find out the number of patterns of 7-bits that constitutes the class S, the number in classes. The number in class L is the number of patterns with 6-bits because all number of patterns with 6-bits when I append one long bit, I get L. So the number of elements in classes and number of elements in class L are clearly determined as number of patterns with 7-bits and number of patterns with 6-bits. And 8-bit patterns therefore can only be either this or this and therefore number of 8-bit patterns is equal to number of elements in classes plus number of elements in classes. Which means number of elements which have 7-bit patterns, number of elements which have 6-bit patterns. Now I can get what is known as a recursive definition. I can find out the number of 8-bit patterns if I know the number of 7-bit patterns and number of 6-bit patterns. How can I find out number of 7-bit patterns? For that I will have to know number of 6-bit patterns and 5-bit patterns. How do I find 6-bit patterns, number of 5-bit patterns and 4-bit patterns? And this way I will reduce my problem to finding out number of patterns with 1-bit and 2-bits. If I know that I can build everything upwards. In general then, algebraically, Hn is the number of patterns with n-bits. Then H8 is equal to H7 plus H6. In general Hn is equal to Hn minus 1 plus Hn minus 2. Does this help us to compute H8? Well, we can compute H8 if we know H7 and H6. But do we know H7, H6? We can compute H7 if we know H6 and H5 and so on. This then is the general algorithm idea. If I start with H1, number of patterns with 1-bit, I know how many patterns can be there, only one. If I start with H2, number of patterns with 2-bits, there can be either 2 short bits or 1 long bit. 2 short syllables or 1 long syllable. Both will qualify to be 2-bit pattern. So I have one for 1-bit pattern, 2 for 2-bit pattern. And now I can move very rapidly. So H3 can be computed as H2 plus H1, which is 2 plus 1. I have given explicitly the possible patterns that you can see. Then H4, H5, H6, H7, H8. Now, can you see an iterative pattern in this? If I have earlier so far, I had a term called X, which I was modifying. Now I have two different terms. Let me call it term 1 and term 2. In the iteration, when I add term 1 and term 2, I get term 3. If I have to iterate around it, that term 3 should now be treated as term 2 and original term 2 should be treated as term 1 to calculate the new term 3. And if I continue doing that, I will find out in this series any nth number of this kind of patterns. Here is the program to compute HN. Observe this program very carefully. It first reads n, which is what number to compute, what sequence in this sequence, which term to compute. So we want to find out the nth term of the so-called Hemchandra series. I am declaring three variables. H-preve to represent H-previous, H-current to represent present term and H-next which will be the next term. The objective is that given the two terms, the current term and previous term I should be able to compute H-next. Initially the previous term has value 1, the current term has value 2. That means this is H1 and this is H2. I will now calculate H-next which for the first time will represent the value of H3. But if I put it iteratively, it will successfully compute H4, H5, H6, etc. Since I want to run this iteration up to n times, I will start with i equal to 3, i less than equal to n, i plus plus and observe the iterative statement. H-next is equal to H-preve plus H-current. This is set forward. This will calculate H3 when the iteration is executed for the first time. Now when I want to execute the iteration next time, I want to calculate H4 which should be equal to H3 plus H2. Consequently, H-current and H-preve must represent H3 and H2 and not H2 and H1. So the preparation for next iteration is very crucial. What I do is I shift the value of H-current to H-preve and I shift the value of H-next which I have just found out to H-current and then go back into the iteration. It will be illustrative if you write down this program and execute it for n equal to 5 by actually executing each iteration and writing down the variable under some columns. Seeing at every iteration what is the value of that variable at that iteration? You will notice that there is a window sort of which is moving over H-preve, H-current and H-next and you are keeping the window moving forward and forward and forward till you reach the nth value. So this is an interesting extension of that trick that we use. Namely, we iterate around a generalized statement and the most difficult part for constructing this program is to remember to shift the values such that in the next iteration they still make sense for finding out the next step. So once you get this trick you will be able to fill up for example there could be a formula which depends upon three previous terms. Then you could say H-preve 1, H-preve 2 H-current, H-next, whatever. The names of the variables are irrelevant and you will have to shift three values for the moving window to move forward. This is the trick that you use. Professor Ranade calls it mathematics from poetry. This series obviously is very very interesting. It represents a large number of natural phenomena. The ratio of consecutive terms tends to a limit which is called the golden ratio and now you know these numbers as how many of you have heard these as Himchandra numbers? One, two, three, four. This is the sad part because most of the history of mathematical inventions that we learn are from the books which naturally indicate the inventor as the people who first wrote about it. However, recently a whole lot of literature including observations by Fibonacci himself has been discovered where Fibonacci has claimed that he learned this technique from an Arabian scholar who told him that he had learnt it from India. So this the point I am trying to make here is that while inventions will occur anywhere and everywhere quite often we are oblivious to the fact that great inventions have occurred even in our society. It is useful incidentally the person is resurrecting such strong evidences from Indian literature and presenting it in international conferences to correct the attributions is a professor in IIT Bombay Humanities Department has been doing that for a long time for various other things. So this is the this is the last point that we will discuss today which is a concise form of decision making. There are situations when I want to assign one of the two alternate values to a variable. I want to say A is equal to something if this condition is true otherwise A is equal to something else. Whenever this happens I can write an if statement of this type. For example if N is greater than 100 X is equal to n minus 50 else X is equal to n square plus N. But if such a situation happens where a single variable X is to be assigned either one value or another value based on a condition then instead of writing such a long if statement it could be written very concisely in C by using an operator called question mark operator. It is written like this X is equal to n greater than 100 question mark n minus 50 colon n square plus N. Let's just very quickly look at the syntax and semantics of this expression because although it is unreadable at first this has become the standard usage whenever such situation exists. And in most professional programs just like you will find the use of i plus plus plus i etcetera you will also find the use of question mark operators at times whenever such assignments are to be done. So let's look at the question mark operator. I have given the same example here X is equal to n greater than 100 question mark n minus 50 colon n square plus 10. First of all this is a single assignment statement so some value will be computed and will be assigned to X as is known for the assignment. The assignment statement itself contains an expression on the RHS let us interpret the expression on the RHS. The expression on the RHS begins with a question that is why it's called a question mark operator. Is n greater than 100 that's the question being asked. So the first part of the question mark operator is a condition. This condition will be evaluated if n is greater than 100 use n minus 50 as the expression if n is not greater than 100 use n square plus 10 as the expression. So in short I am specifying two independent expressions separated by colon. The first expression is this, the second expression is this and all that c plus plus does is when this statement is executed it will evaluate this condition if the condition is true it will treat this particular expression as the total expression if this condition is false it will take the second expression after colon as the expression in either case it will evaluate that expression using exactly the rules of c plus plus expression evaluation will come up with a single value and will assign that value to x. So as I have observed it only provides a short cut sort of and can be used only when a single variable is to be assigned a value. If you have a condition saying if n greater than something x is equal to so and so else y is equal to so and so this statement is useless. This statement is useful only when the same variable is to be assigned either of the two expressions as value. Is that clear? This is a cutality form but you will often come across it in some professional programs. Here is an old program which attempts to use that question mark operator. What is this program? It is trying to find out the maximum of n numbers. So as usual it reads the first number it assigns that number to max and it sets up an iteration for 1 to n minus 1 to read the remaining n minus 1 numbers. Every time it reads a number observe what we are doing. If max was greater than number we were setting max to that number. If sorry if number was greater than max we were resetting max. If number was not greater than max we are not doing anything at all. When we did not do anything it meant that max retained its original value. If I want to use question mark operator I have no such possibility of saying nothing for one of the branches of it. If some condition is true what values to be calculated if some condition is not true what values to be computed both have to be specified. So if I use the question mark operator here I will say max is equal to max greater than number question mark max colon number. What this means is if max current max is greater than the number that you have read I don't want to alter the value but I can't say don't alter the value. So I am artificially assigning the same value to itself. Effectively saying max is equal to max means take the value of max and put it back in max. One extra assignment I am doing in this. I would not have to do that if I had used it. So this particular program is artificial but it shows how the question mark operator can be used even when you have only one branch without the if statement assigning something and the other branch not assigning anything. So you assign the value itself whatever is the current value and that is fine.