 I'll come back to 105. So we're done all the content for the midterm. Yay, we're a week ahead of other people. So good, I guess that's good. So today we'll be doing some more practice, we'll be solving a larger program. And then next week we can do all midterm review so we get a lot of practice and we can all do very, very good on the midterm. So we'll have like three lectures to go through it. So again, use the discord, post questions, go through the old exams, look at them, the old midterms. Let me know if there's anything in particular you want me to pay special attention to. Otherwise we'll just go through them in reverse chronological order and we will figure it out from there. But we can breathe a sigh of relief now. So as a detour, let's try and write a bigger program. So there is this thing called the gold box conjecture and some very, very smarter than me person, like 200 over 280 years ago, apparently just came up with this and he just said for every even integer greater than two, this it is the sum of two prime numbers. And this is still to this day unproven. It seems to be true. People have tested it up to very, very, very large numbers that it is true, but no one can actually prove that it is indeed true. But today we'll write a program to see if it actually holds and actually be able to go ahead and test this conjecture that has not been proven. So we are starting from absolute scratch. So nothing here, there's just an empty main, returns exit success, doesn't do anything. So this is a very daunting position to be into because well, I don't know where to start. So given this problem, anyone want to tell me where I should start? What is the first thing I should think about if I want to write a program that will go ahead and test this for us? Yeah, yeah, maybe how to find a prime number. I also should probably be concerned about getting some input from the user. Maybe I want to verify that it's, I can actually get the input. What about in terms of solving the problem? Well, I should probably, the easiest thing to do is just not even worry about how to program this in C. Just think about how I would solve it if I was on paper because basically programming is the art of explaining all of the steps to solve the problem to a very, very stupid machine. So computers, really dumb, you have to guide them through solving all of this. So if I were, sometimes it's nice just to write it out by hand, so if I were to do this by hand, how would I prove this conjecture is true. So just so we have it, let us just write. So every even integer greater than two is, all right. So given that conjecture, if I just give you an old, just some number, so let's say an even number greater than two. So let's say I give you the number, I don't know, 44. How would you come up with proving that this is true or at least that it hold, not prove because then you'd be smarter than 300 years collectively of humans, but showing me that 444, this conjecture does hold. Yeah, yeah, so 44, it isn't, so it is an even number. It is greater than two, so this is a valid input. So after I have the number 44, how should I see if this conjecture does hold or not? So for this one is not a prime number. So try three, so I try three, how do I try three? Okay, so the other number is like 44 minus three, so 41. So I could try that and then see if they are both prime numbers. So how do you come up with three? Why wouldn't I be able to use two? So I will counter that, so that's a good thought of like, okay, well, if I start with two, then if I minus the other number, well, it'll be even and that will not be a prime number. What about if my input is simply four? Yeah, so you're being a bit too clever already. So always good just to start with the first prime number. So maybe I should check that or maybe that's not two, but in this case, yeah, if I did two plus 42, that's not it, so I could just cross it off the list. Thanks, go to the next one, three plus 41, oh, they both happen to be prime. But what would I do if this was not actually the sum of two primes? What would be my next step if for some reason that was not true? Yes, yeah, so I could try five, which is the next prime number. So when we're solving this and we have to explain it or like write it in C, any of the terms we use that like, we take the number and we get another number certainly sounds like a function. If we can give a name to an input and an output, probably gives us an idea of something we should write. So you said, if that wasn't true, I should go to the next prime number and then subtract it. So I probably need a function called next prime, which would probably take an integer and return an integer. All right, so that's good. We're already breaking the problem up into steps. What other function would be useful? So what did I say? So I took 40, so like I would take three, then figure out, okay, whoops, the other number is 42. What did I ask about 42? If it was prime, right? So maybe I need a function called bool is prime. And then other than that, this is good enough to get me going. I can kind of see it. So I can ask for some number. So let's say I was asked to use it for some input and all I get is a single integer. So might be nice to just write your function like this because I don't need any, whoops, and this needs an int, sorry. So don't need any input to the function. I'll just ask the user to input a number and make sure it holds true. And well, I don't have to deal with pointers because I'm just returning a single value, so I should probably just use a function. So with that, that seems to be enough to get going. So let us turn to C. So first function we should probably write is the user input one, user input, whoops. So we're returning an int and we don't need any arguments. So if I want the user to input a number so I can test it, I should probably tell them what they have to input, right? So let's say enter a integer greater than two and it's an even integer. And then I have to do scan F. Oh, okay, I need, it needs to be an integer. So it's a percent D format specifier. Oh, okay, right, I need to give it a variable. So let's just call it input. I'll just initialize it to zero just to be safe. In this case, it doesn't matter. And then scan F, so now through that pointer, it goes ahead and sets that value for me. That matches the user input and then I just return that input. And in the main, I'll use it. So I'll just say num equals user input. All right, is that a good user input function? Looks good, all right, let's see it. So usually when we test our program, we assume the worst case that our user is an absolute jerk. So if I go ahead and run this, enter an even number greater than two. Sure thing, hmm, should probably do a bit, something a bit better than that. How would we do something a bit better than this? Yeah, yeah, okay. So maybe have a while loop that the user, that doesn't let the user input something that's not greater than two. So while the input is what? So while the input is what? Less than or equal to two? So while the input is less than or equal to two, maybe I, maybe I cost the user a little bit. All right, maybe I do something like that. And maybe if you want to be clever, the more times the user gets it wrong, the meaner you get. So that could be an extension to our program. We'll just be a little bit of a jerk for now. So let's see, we enter one, we get hey jerk, enter a number greater than two. We say two, tells us we're a jerk again. Okay, three. Was that an even number? All right, what else do I have to put on here? Yeah, or if it's odd, odd equals zero. Like that, maybe, okay. So looking at that, so that should continue asking the user if they enter something that is less than or equal to two or it's not an even number, right? Either one of those that fails, so this should do the trick. So let's say I enter a one, okay? I enter zero, okay? No, enter a two. No, okay, three, five. Seems to not let me enter an even number and then some number greater than two that is even 10. So that seems to be good for our user input. Any thoughts about that or does that seem good now? Seems relatively decent. All right, so what is, or the other one? So maybe we want to just write all the function prototypes we thought of up here. So we had this one, we had next prime, and then we had is prime, bool is prime. And then we used a bool, so we need this. And let's move this to the end just for argument's sake. Which one should we write next? If it's prime? All right, so let's write bool is prime. We'll just be clever and call it an x. So how do we know if a number is prime or not? Yeah, so if it's prime, it's only divisible by one and itself, right? So if it's divisible by any number between two and less than itself, then it is not a prime number. So what would that look like? So what should I write here if I have to write it in C? First I could check if the number is even, yes? So if the number is even, then it is not prime. Oh, I had a question also in the discord if I enter a or nothing or a large number, we're assuming that user inputs at least an integer for this course because like I said before, scanf's hard to use, so it doesn't actually do good. So this starts us off so like this, if the number is divisible by two, then it's not a prime number, unless it is two. Hmm, and if I kept going with this, in general it's like up to how big the number is, right? So I would have to be like, well, if the number is divisible by three, then it's not prime. If the number is divisible by, well, four maybe, then it's not prime, although I could skip that one because it's not prime. Yeah, this looks like loop territory, right? Every time through I'm going up by one and for the sake of this course, like sure, if I don't really have, well actually, I would have to check if it's divisible by four, but we have this pesky situation where I shouldn't do this for the number two because the rule is you're prime if you can't divide by like more than one and yourself, right? So two is itself, so that doesn't count. So probably there's like a bound what number I should go up to here, right? So I shouldn't go up to myself and I should also start at two. So if I should start at two and this number, so this is like X divided by something, right? All right, if I want to give the something a good name, if you do like number divided by something, what's the end something actually called? Anyone remember their math, the divisor? Yeah, we'll call it the divisor. All right, so yeah, we can do a loop divisor so we can start it at two maybe. So we start at two, doing it by one, pretty useless. So we can let the divisor go up till less than X because that's our input. So if my input is let's say two, it wouldn't try and divide it by two, it would stop before that and guess what, it wouldn't even try anything. So we would do plus, plus divisor and then we can kind of move this in. So instead of checking if X is divisible by just some number, we can do if it's divisible by the divisor and then here we have a few choices of what to do. So if we find that it is not like if this is divisible, so it's a factor and we know for sure if we go inside this if statement, we know for sure that it is not a prime number. So two strategies here, maybe I just have a Boolean that I keep track if it's prime or not and then I set it equal to false but usually the good thing to do in functions is if you already know the output of it, you can do a return and it will just immediately end that function and it wouldn't even try bothering trying to divide anything else. So I can just immediately return false and then functions done, wouldn't have to try anything. I know it is not a prime number. All right, anything else with this function? So I return true at the end. So if the thing is prime, then it, yeah, so I have to return true if it is prime. So how do I know it's prime here? Yeah, so X can just be any integer. So we're just assuming it can be anything right now because we're writing just as function, just as a little helper function because we know we'd need to ask, hey, is some number prime or not? Yeah, yeah, exactly. So if I go through this entire for loop and I never go into this if statement, so it never returns anything and eventually I've tested literally every single divisor and it's not divisible. So at the end of this for loop, we know for sure that, well, it wasn't divisible by anything that was two or less than itself. So it must only be divisible by one in itself. So we can just immediately return true and we're all good. So just to test it, yeah. So we do have to return true in this case because if you just leave it out and you compile it, C will say something like non void function does not return a value in all control pass, which basically just means it's possible for this function that returns a value to end without you calling return. And for the purposes of this course, there is usually it returns zero. So usually the default value it returns is a zero, which is not what we want. We want to say if it makes it to the end, it's true. So, but that's a new error. I don't think we have seen that one yet. Well, it's a warning. So it still compiles. The compiler will do something, but it would have been a complete pain to debug. So now we can go ahead, C, okay, I'm a jerk. How about four? Okay, I can enter that. So maybe we test in our program. Let's just see what the result is of just making sure that it is prime work. So we can do is prime two. Let's make sure that we can say that two is an even number or a prime number. So it doesn't matter what input I give it, and it says, yep, it's prime. So that's good. Maybe when they test it, we don't care about the user input. So maybe we try a bunch of values. So one is technically not prime. So, oops, we screwed that up. So maybe we have to fix that because that's kind of a bit of an edge case where I even think they considered one as a prime number before, but then they've changed their minds. I don't know, math people are weird. So we can just make sure that if x equals one, we can just special case that. We'll just say it's not prime. And that's fine. And we'll assume that this works for integers one or greater. So we won't bother to deal with negative values because it has slightly weirder rules. And yeah, we just won't bother, won't test it, and doesn't really matter because our input are going to be always positive. So don't have to deal with negatives. All right. So now we got some user input and a prime function. So how did we say, oh wait, we need another function. We need next prime. Okay, so we need next prime. All right, how do I go about next prime? So my x is just going to be some integer that I assume is prime and I should give you the next prime number. Yeah, so I could probably use next or is prime. So how would I use this prime? So we can think of it in little steps, yeah. Yeah, well, we can just check, right? If computers are basically just really, really stupid things I can do stupid things really fast. So if it works, it works. So for next prime, what we could do is just take the number, add one to it and see if it's prime. If it's prime, great. If it's not prime, do it again. Okay, we try it, we increment it again and it's prime, great. If it's not, we do it again. So if I was to translate what I just said into code, how would we do that? Yep. Yeah, a loop, what kind of a loop? For loop. So if we do a for loop, we have to know where to start. So where would I start with a for loop? So we're assuming X is just some random number we get. We, all we can assume is that it's probably prime. In I equals X? Or like that, we start with X. I guess we can. So remember we should use for loops when we like know how many times we do something. So in this particular problem, do we know how many times we're gonna say, oh, this one's not prime. This one's not prime. No, so for loop, what's our other option? While loop. So there's also like a do while and a while. So in this case, well, let's think about each time we need to go through it, we just said we increment X, right? Yeah. Oh, so we're going back to the for loop, so you want a for loop. All right, so if we want a for loop in I, so what's it start at? X plus one. Okay, and the condition you want is just that X. So you want I is not prime, which is like. Not. Uh-huh, and then how far do I go up? Plus I? So you don't want me to write anything here? Cause this is like normally where I do like plus plus. Okay, so that. All right. So if I do this, then how do I know when it stopped? And what's the next prime number in this case? So X, so X we didn't actually change. So, and like if I do, you might be thinking, I can kind of see where you're going here. Like at the end of that for loop, I is a prime number, right? So I can do return I, get a red line, error. Can you fix that? Yeah, so the I is only in scope between these brackets, other than that, we can't access it. In this case, yeah, if we want to, we could just do in I over here and then get rid of this. So now I is in scope even after that. So I create I immediately and it is in scope for the duration of the function. So I could do something like that. So that seems like that's a good solution. Let's see. So let's just, we can test it by printing a few results. So let's say the next prime of some number equals some number. So let's say next prime of three. All right, so what is the next prime of three? Do we actually know the result of or what that should be? Five, right? So let's see if we get a five. Oops, I did not comment, yeah, five, so it seems to work. So the only slight comment I would have to this is like a for loop with nothing in it. It's a bit strange. So it like just converting it to it's loop equivalent might be a bit, might be a bit cleaner. And we could also like, we get a copy of X. So we can just modify that. We don't actually have to create another variable. We can just change X if we want. So we could do something like plus plus X and then check if that's prime. So we always do that. So if we always have to do an operation no matter what, we can do a do while loop. So we could just like do plus plus X while not, while I can't type, not is prime X. And then we can return X. But mean the same thing. Oh, I can get rid of this. So mean the same thing. Some people pride themselves in using as little variables as possible, but means the same thing, last one, perfectly acceptable. But some people might find this a bit easier to read. Again, some things are up to taste. Usually people don't like when for loops have nothing in them. But like we saw, a for loop is basically just a fancy while loop. All right, so now we're looking pretty decent. So how would we test this now? So remember when we, so this we probably have to go back and when we did by hand, right, we started with two and then we took that and we subtracted whatever the number was and then checked if the result of our subtraction was a, was prime and then if it was prime, then we're good, we're done. So we can do the same thing here. So let's go back. So we can pick a first number. Two was our first number because that's the first prime and our second, well, that would be num minus the first. And then I could go ahead and just iterate on this a few times. I don't know when I have to stop asking about when a prime number is, but we can just kind of see. So we can write the body first of like what we have to do every single repetition. So all we have to do is check is like if the second, whoops, sorry, if is prime second, then we're done. And then if that's not true, then we have to, you know, go through it over and over again. And kind of seems like we're also doing another boolean and it's kind of messy if we have to like just finish this loop or break out of it. So that might tell us that, oh, we should probably just write another function. So like boole, conjecture holds for some x. So let's start writing that. So we'll just take our input and or our solution and put it there. So maybe we have here if conjecture holds num and then if it's false, we can just say else. If it doesn't hold, then we win like millions of dollars, we broke math, cool. All right, so I called this num. All right, so if the second number is prime, right, we can just say the conjecture does hold, we can return true. Otherwise, well, what we just do is the first number, when we did this just goes to the next prime, right? So if I were to say that, I update first to be the next prime of first, right? Something like that. So if the input, if my first is two, then I get a three out of it. If it's a three, then I get a five, then five is seven, and then after seven is 11, oh no, that's like my limit. And then here I would have to go ahead and recalculate second. So second is equal to num minus first. All right, and then kind of like looking for primes, we should probably figure out when we should stop this. So if we do this, let's say we have to go on and on and on. So we get up to like, say we get up to the number 22, and then we do like 22 plus 22. So if we get up to that, there's no use going to the next prime number because, well, I would have already done it on this side. So I can stop as soon as these numbers are like equal to each other, or there at least this number should always be smaller than this number, otherwise I'm going the other order. So I can just say that while first is less than or equal to second, then I do all this. And then if I go through that and I run out of numbers, then I know that this whole thing is false and we broke math. So that same reasonable, yep, yep. So equals two is included in this case. So the first case that we would probably want to check is make sure this works for four because four holds because it's two plus two, right? So let's go ahead and run that. So four holds. All right, and then we can try it with, let's say, let's try it with 45. Oh, I can't do that, right? Jerk, all right, 46 holds. We can do, I don't know, 60 holds. Seems to hold. And then last thing to do, maybe I just super-functionize this whole thing and be like, okay, well, this kind of looks like a logical thing where I'm just outputting information about the conjecture. So maybe I just do avoid conjecture output. Wow, why can't I type? Put put is not a thing. So maybe I make this a function, maybe I have it overkill where I just move it in and then conjecture output of num. All right, so now my main looks like super simple, right? Take the input, give it an output. One of our goals to make our main, like make our functions just do one thing and then whenever we read the code, it becomes a lot easier to read, right? I can kind of understand, okay, I take a number and then I give an output. Can't really get much simpler than that. So 44 holds. All right, let us make this better. So looking at this program, if I just give you like some giant number, so say I give you that and say it holds, wouldn't be more interesting if I like said what numbers that was true? All right, so if we wanted to make this program better and say what numbers did this actually apply for? Like what numbers did I find that are both prime that sum together to give the original number? How would I do that? So the function where I figured it out was this conjecture holds one, right? So I already figured out the first and second, but this function already gives a value that I'm using as part of my logic and I kind of want to like output three things, right? I kind of want to output whether it holds or not and then what the first number is and what the second number is. So how would I do that? I want to like return three things. Yeah, pointers, this is one, oh shit. It's like scan F, right? Scan F can use multiple values. If you need to give multiple outputs, then you have to use pointers. So we can say, okay, well, we need to use pointers. So we can say a pointer to int called first, pointer to int called second, and then these are the things that I'm going to change so the user can get that as input. So we have to change a few things around. So my argument for that becomes this and then here. Okay, well, I should probably, I need to create variables here so that I can essentially get their inputs or let this function, this conjecture holds function actually update the values for me. So maybe I just do int first equals zero and second equals zero. I'll just initialize them to something just so I feel better about myself. And now this looks like scan F where I have to give it the pointer to that integer. So I'll give it the pointer to first and the pointer to second. So luckily for us, the compiler helps us out a bit here because while we declared them before because we needed two integers, but now we're being supplied two integers that we get to update. So we can get rid of the declaration but here we do need to set them. So how would I change this to, so if I just delete the int, is that all I need to do? So first is a pointer, right? So if I say first equals to two, what does that mean? So that means first, like a pointer is just an address, right? So I say first is address two. Is that likely to be good? Probably not. So what do I need to do to actually update the value that first points to? Yeah, yeah, I have to dereference it first and dereference it, all I have to do is put a star. And then that little underline that the compiler was telling me that I'm silly goes away. So if you see that little yellow underline or compiler warnings when you compile, well, then you should just get rid of it. So turns out before when I wrote this, each time I used first and second, they were integers, now they're pointers. So anytime I see first and second, I should just dereference it first because I'm still just using integer values if I dereference it, well, it's still an integer value. So I'll just go ahead and change all of them, which is fun. So I'll just put an ampersand in front of all of them and including these ones, whoops, and including this one. All right, and now all my compiler warnings went away. So now if I compile it, no warnings, thankfully I didn't miss them all. Hopefully C would give me some help. If I missed one, but in this case, it doesn't look like I did. So now if I wanted to print off the two values that function set, what do I do in this print statement? So I can just say the numbers are d and d. So what's the first number called? Is it first, is it star first, is it ampersand first? Just first, right? So that was the actual integer. I gave this function the address of that integer and it just constantly updated the value. And while whenever it returned, first was a prime number and also second was a prime number. So here I can just simply say first and second. So now, whoops. So now my program looks a bit more interesting. So yeah, cool. And because I wrote this one way, too, I can actually test it a lot of time. So now let's say I wanted to just test it a whole bunch of times and I wanted to see, hey, does this hold for the numbers up to, I don't know, 10,000 or something like that? That turns out to be easy because I can just do like four in x, I don't know. So the first valid number was an even number greater than two, right? So it was four. See, I go all the way up to x equals, or x is less than a thousand, sure. And then, well, I could do plus plus x here but that's not part of the conjecture because it's every even number. So I could just do x plus equals two instead. So each time through instead of incrementing it by one, I increment it by two. So I just go to the next even number. And here, I can just go ahead and say, print off the conjecture output and then I don't need any user input. So I can just test numbers up to, and let's say including a thousand. So if I run that, boom, I can look through it. Maybe I want to also print off and hear what my original number is. It holds for d and that would be called x. So maybe I do that so I can actually verify it. So it holds for a thousand, numbers are three and 997. I can scroll all the way up and see that seems like we haven't broken math and it has figured it out. There's some weird patterns that math people probably love explaining. Ooh, there's a cool one, it goes up to 31, wow. Let's see, we can go all the way up. We didn't see, we broke anything, oops. And it makes it easy, right? We wrote it in a function, testing it up to like thousands was easy. If I want to test more numbers, I can just increase that number until, my computer takes too long to actually do it. All right, whoo, that was a whirlwind. All right, any questions about that? All right, cool, we developed a whole program together that's probably bigger than your next lab and we did it in an hour. And I didn't actually really do that much except type and I typoed most things. So you can do it faster, maybe. Yeah, and then again, so ask on Discord if there's any particular midterm questions you want me to go over. We'll be doing midterm practice all next week so we can all do super well in the midterm. All right, so just remember, pulling for you, we're all in this together.