 You are all back after lunch, I hope. Let us, like I said in the morning, we will use the afternoon to review the programming related questions. So, if you have any questions, you better have questions rather, for as questions may press the and raise button with you, so that I can take the question and answer it. If you do not have any questions, let me at random choose somebody and ask them to explain a particular problem. Yeah, the one of the 23 problems you have in the notes deals with Capraker's constant. I would like to know from you, how you would go about doing that particular problem. Problem number 7 in the list of problems, Capraker's constant, like to hear from you how you would go about approaching the problem. Let us see what is that, the problem 7 is trying to say. Let us say we have a 4 digit number, what is the largest number we can make out of this, what is the smallest number we can make out of this, what is the difference between them? Oh, this is finishing pretty fast still. You get 4176, what is the largest number you make out of 4176, what is the smallest number, what is the difference? Do you notice something interesting? The process has come to an end because again you are going to end up in, which will get you back to 6174. This is what the problem is talking about, take a 4 digit number, arrange the digits in ascending and descending order, giving A and D, subtract A from D is the result. Now, this is the procedure given, if you are going to write a program to do this, how will you do it? Let us take a look, the way to go about thinking about writing a program is to think in terms of high level functionality, rather than straight away writing line by line code. If we had a function to do each of the jobs, how will we do it? Let us say, you can accept the number from a user or anything, that change we will make later. First we start with given n value, now what is the next step? The next step is finding largest number that can be made by n, then the smallest that can be made with n and n should be equal to that itself and how long do we loop? We have to loop this repeatedly, so the one loop we know is this, what is the condition we have to write? We have to write something like the current value is not equal to the previous value, because that is when the, you should stop, now there is, we have set it up, copy n to current, make previous 0, the new current will be this and the new previous will be what was called current now, the numbers we tried, let us rewrite, so that we know what we are talking about. So, what is that? The program is supposed to do, we start with some n value, we assign that to current, then we produce these two, whatever you subtract, this becomes current and this becomes previous. So, 1425 will be current, n equal to 1425 we start with, then n become current also is stored as n, so current also is 1425, previous is 0, then at the next step, current becomes 4176, previous becomes 1425, at the next step, current becomes 6174, previous becomes 4176, at the next step, current is 6174, previous is also 6174, so the program will come to a stop. So, that is what we have to write. Please note, we can write it fairly simply if we write these in terms of functions, now it remains to write these functions, job is not over, so we need to then write the functions, this means we have to sort the digits of the number, but the number has the digits as does not have them separately, then only you can sort it. If you have a list 1425, that is 1425 cannot be sorted, because it is a single entity, but the program requires us to rearrange in the digits themselves, so if I had it like this, then I can sort it, so the built in functions sorted will automatically give me and we know how to get the reverse of a list. Now, I have got it in the, if I have a list, I can get the individual digits in the right order, so I need another function, which will give me the individual digits in a number, so that I can sort. I also need another function, which will give me a number from the digits, so I have to write one more function, given a number, get the digits into a list, then sort and then reverse it, so that I have then the other function, which needs to be written digits to number of D, smallest is easy to write, so now if you write the two functions, given a number, break it down into digits, then we are done, if this is the number, how do I extract a single digit from it, so n percentage 10 extracts one digit, n by 10 will give me the rest of the digits, that gives me the method to approach, so let us write, have an empty list, so this is the process we are going to use, we are going to store in another value, we will say n equal to n by 10, now this n percentage 10 gives me the second digit, n equal to n by 10, now this n percentage 10, give me the third digit, once again I do n equal to n percentage 10, n becomes 0, so this is the process I have to use, if I start with that number, n percentage 10 will give me the last digit, then I say n equal to n percentage 10, so the remaining digits alone will be left, I do another n percentage 10, this is what you have to write in code, so if it is D starts as empty, let us say take the same 1425, what will happen, 1425 is greater than 0, so D dot append, 1425 percentage 10 will append 5 to this, n becomes 142, 142 is greater than 0, D dot append 2, n becomes 14, 14 greater than 0, D dot append 4, so now D has become 525 comma 2 comma 4, n has become 1, so D dot append 1, so 5 comma 4 comma 2 comma 1 and that list is returned, because the n has become 0, now we have to write the reverse function that is given a set of digits in a list to produce a single number from it, so how do we do this reverse process, let us try and look at what is that we are trying to do, we have a, we started with this, we produce this from that using the function just now we wrote, now we need to be able to, now I have to produce the number from these four, how to do that, the logic is the way to think about writing any of this code is, if it is a single digit number, what will we do, we will just return whatever is inside the square brackets, sorry, if it is a two item list, what do we do, you take the first by, take the first multiply by 10, add to, if it is a three item list, take the first multiply by 100, the second by 10, third by 4, so this is the simplest way to produce a number from this list correct, so what is the largest power of 10 that should be multiplying, if there are four numbers, the largest power will be 1000, we can take advantage of that, so we know what is the largest power of 10 we have to use is, number of digits is known minus 1, so I can do this or this way multiply the first by this, add the next multiplied by 1 less and so on, that is one way, but that is not as elegant as the other option, what is the other option, instead of trying to use our eyesight, our eyesight says there are three numbers, so we say multiply this by 100, this by 10, instead of that you refuse to look at all of them and say I will look at one at a time, if there is only one number just return it, if there are two numbers multiply the first by 10, the second by then add, when the third number comes, multiply this whole thing by 10, then add this, multiply this whole thing by 10, add this, in other words, you produce 1 plus 245 still to be handled, then sorry, you move to and 45 yet to be handled, this is a much better way of doing the same thing, so take the first digit, multiply by 10, add the next digit, multiply the whole thing by 10, so this way you do not have to know what is the largest power of 2, do not bother, you deal with each digit one at a time, so this is a better way to program, so what we will do, we will use the same thing, so then for each digit in the list P, we know P is a list, multiply what is already there by 10 and take the, which is what we said, what is already there, multiply by 10, add the next item, multiply what is there by 10, add the next item, same thing we are saying, take one item at a time from the list P, multiply Q by 10 and add D, that is all, finally, so we have written, Python allows you to think in terms of, now we have to, we have written it, but we need to print this, so that we can see the progress, okay, let us run it and see, so we will add one more outside the loop, so it will print the ending value, we will try a different number, so this goes around in many, many more times, but ultimately ends in 6174, that 6174 is what we call perfect risk constant, I want to highlight how, if you think at a high level these problems are easy to solve, first write almost in English, the new number is the largest of the current minus the smallest, which is what it says, the problem statement is, so you give it a function, then you think of the simplest possible implementation of largest and smallest, once again think in terms of other functions, do not try to write the whole thing, think in terms of chunks, then you will be able to write the functions, remember an ideal function should do one job, only one job and do it well, a function ideal or not a function should never do any I O, a function should just return value, it should never print or never, you should never accept a value from the user from inside a function, alright. Anybody has any questions on this code, there is a question from somewhere, question number 10, getting all the Pythagorean triads in the range 1 to 100, but how to extract the primitive triads, that is the next question I want to answer, unless someone else has something else to ask about the Capricas problem, I take it nobody has a question, so we will try and write the next code, we will try and write is the triads problem, what is the triads problem, what is it asking us to do, it is asking for this is probably the best known triad you ever know, you would have seen, what is interesting about it, these three sides form the sides of a right angle triangle, apparently ancient Egyptians knew this, so they had a string of lengths 12 knotted at the right places, which they used to use in order to get right angles in their building blocks and so on. Now, what are the other triads you know of, somebody may know, of course you can produce another triad easily by multiplying the first one by two, we say that that is not the type of triad we want, we want what are called primitive Pythagorean triads, 6, 8, 10 is something that can be produced from 3, 4, 5 by multiplying each digit by 2, so we say it is not a nice triad, so we are not interested in this triad, we are interested in the primitive triads, so what is the difference between 6, 8, 10 and say 5, 12, 13, we know that 6, 8, 10 is produced from 3, 4, 5, but if you use this method to find the non primitive triads, that is check whether it is a multiple of a previous triad, our code will become very complicated because we have to take each triad, check with all the other triads before that, so if you are supposed to find 100 triads, you by the time you reach the say 60th triad, you have to check with all the 59 triads before that, whether the current one is a multiple of any of the other ones, that is not a very nice solution, it will be very, very slow, so we need to find some property of the current triad itself that tells us whether it is of interest or not, so looking at these two 6, 8, 10 and 5, 12, 13 can we say 6, 8, 10 has some property which 5, 12, 13 does not have, then we can use that property to write the primitive Pythagorean triad, there is also yet another stipulation, 4, 3, 5 is not again new 3, 4, 5, 4, 3, 5 are the same, how do we find that out, with a b values in this range 0 to 100, that is what I was looking for, actually 0 to 100 is not required, we know a will start from 3, there is nothing lower than 3, so we can say range 3, 100, this way we will avoid the 4, 3, 5 problem, by definition we consider all b's more than a automatically 4, 3, 5 would not be reported, is that understood, because by definition the b's we consider are one more than a, so 4, 3, 5 will never be reported, now if c s q is a perfect square we are done, so how do you know, how do you find out that c s q is a perfect square, take the integer, convert, since you are taking the integer part, if this happens then we know c s q was a perfect square, in which case this is the simplest way to do it, let us run it and see whether it works, it still does not do the primitives, but let us get the basic thing working first, it is working, but 6, 8, 10 is there, but one thing is working 4, 3, 5 is not there, which is good, so we have done one part of it, now what is the next step we need to do, looking at a, b, c what is that, we can look at a, b, c and say, if a, b, c have this property then it is not a primitive one, anybody wants to answer that question, simply inspecting 5, 12, 13 and 6, 8, 10, can we say 6, 8, 10 has some property which is not shared by 5, 12, 13, so I know on seeing 6, 8, 10, what is the property, 6, 8, 10 can be discarded, what property is that, please remember only looking at 6, 8, 10 you have to come to the conclusion, you cannot say 3, 4, 5, no, go ahead make a try, so you will only look for multiple of 3, so you have to look at the number and decide what to test or first time you said all are even numbers, now multiples of 3, how do I write it programmatically, you say you show it to me then write the code is it, that is not going to work, so how do you generalize, good starting point, both are good starting points, how do you generalize them, so simple, all of them have a common factor which is exactly the point, they are multiplied 3, 4, 5 multiplied by something which means all 3 have a common factor, in fact we can do a bit of analysis and say that if A and B have a common factor then itself we do not need it, why if A and B have a common factor and A square plus B square equal to C square, then C also has the same factor as common, so how do you find out whether number has a common factor, we already know it, if the GCD of A and B is greater than 1, we are not interested in, so we have not let us write GCD, I am sure you already GCD has been written for you, I like to write it in a certain way, if B divides A then the GCD is B, otherwise you will find that actually recursion is a very easy tool to think about writing many of the, yes Bhopal you had raised a question, you had asked a question that how will you find out, how will you find out that 6, 8, 10 has not to be printed when 3, 4, 5 has already been printed, yes, if we take the greatest common divisor of that particular thing then we can avoid as its greater common divisor will not be 1, but will be other than 1, wonderful, thank you, that is pretty correct, that is exactly what we have done in writing 2, if you look at the code that is exactly what we have written in code and we are making a point, we do not need to actually look at A, B, C, A and B is enough, so if GCD of A and B is 1 then only we are interested in that, then we will generate the corresponding C and go ahead and do it, thank you Bhopal, that is good. So, this is the way to do the primitive Pythagorean triad problem, K. J. So, may I, you are any questions from your end, is the idea behind the primitive triad clear? Sir, I tried the 13th problem where we have to find 5 digit amicable pairs, it was working for checking whether the pairs are amicable or not, but for 5 digit it was going in the infinite loop or something, so I am not sure how to work with it. No, it is not infinite loop, you would have written it very inefficiently, so it is very slow, so which means you have to find out the answer, why is it slow, it is 12 here on the board I have, on the list I have, a pair of numbers A and B is said to be amicable if the aliquot number of A is B and the aliquot number of B is A. Now, that is an interesting problem because it tells us something about how to understand efficiency. Let me try and write that or so just follow along, the problem is in the list problem number 13 amicable pairs, the question asks for 5 digit amicable pairs and the worry is it is hanging or something, I know it is not hanging, now the first is finding the aliquot of a given number correct and aliquot of a number is defined as finding the factors of a number and adding them and for the purpose of aliquot one is considered a factor the number itself is not considered a factor. Can you see the speed at which 5 digit is being generated, you can in fact time it to see how much time it takes to do that. So, my program took 22 seconds to generate all 5 digit amicable pairs, your program probably took that much to do the 4 digits even longer, where did the key is here, the technical problem the key is here for every factor below the square root there is a corresponding factor above the square root. So, there is no need to find factors above square root at all for every factor below the square root there is a corresponding factor above the square root in other words what do you mean by a factor of a number, if n is of the form a into b, if a is less than the square root of n b will be greater than the square root of n and if I know one factor a, if in other words if n percentage a equal to equal to 0 that is a is a factor of n then n by a is also a factor. So, each step I will get 2 factors plus I will stop looking for factors at square root of n itself, this is an enormous advantage for example, for 10000 my program will only go up to 100 looking for factors. So, what does this mean how many times is this main loop running 100000 minus 10000 is almost 100000 times let us keep math simple and on average I loop here 100 times around here I will route 300 times. So, average about 250 times let us say 200 times. So, my program will run through this loop about 100000 into 300. So, factor will aliquot will be called 100000 times this loop will be executed 100000 into 300 about times that is all. Now, if you do not use this sort of a intelligent optimization if for example, you write code like this, if you have written code like this, this loop is going to be executed n times. So, for 10000 it will be executed 10000 times. So, 10000 times you are going to do this n percentage by f and here 100000 times. So, the total number of times on average is 100000 into 100000. So, your program is going to be spending 10, 12 times more time. If I ask for 6 digit, your program will probably never even print the first one. Nested loops can be extremely slow if you do not carefully think about them and optimize them understood, Somaya. Yes sir, thanks a lot sir. Welcome. We will take a break for tea and come back. Thank you.