h5 Notes on correct solutions to the assignment... See also videos in the CS 151 playlist ** factorial.py ** n! = n * (n-1) * (n-2) * ... * 2 * 1 4! = 4 * 3 * 2 * 1 * Loop or recursion * total = 1 for i in range(1, 4+1): #print(i) total = total * i print(total) * Who cares? 4! is the number of ways to arrange 4 items. How many different ways to have abcd in some order: abcd, abdc, acbd, ... * binomial(5, 2) is pronounced "5 choose 2" - how many different ways to pick 2 items out of 5? How many different ways to pick two letters from abcde? ab, ac, ... * binomial(5, 2) = 5! / (2! * (5-2)!) * How many different ways to pick 5 starters from a team of 10? binomial(10, 5) ** cards.py ** card is a number from 0 to 51 0: Ace of hearts 1: Ace of diamonds 2: Ace of spades 3: Ace of clubs 4: 2 of hearts 5: 2 of diamonds 6: 2 of spades 7: 2 of clubs 8: 3 of hearts 9: 3 of diamonds 10: 3 of spades 11: 3 of clubs 12: 4 of hearts 13: 14: 15: 16: 5 ... 51: King of clubs suit is card % 4 - hearts, diamonds, spades, clubs 0 1 2 3 value is card // 4 - Ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King 0 1 2 3 4 5 6 7 8 9 10 11 12 Examples if card is 13 - 13 = 3 * 4 + 1 - card%4 is 1 so diamond - card//4 is 3 so 4 - card is 4 of diamonds if card is 26 - 26 = 6 * 4 + 2 - remainder of 2, divided and got 6 - card%4 is 2 so spade - card//4 is 6 so 7 - card is 7 of spades if card is 8 - card%4 is 0 so hearts - card//4 is 2 so 3 - card is a 3 of hearts hand = [13, 8, 26, 10] - 4 of diamonds, 3 of hearts, 7 of spades, 3 of spades flush... check if all cards are the same suit print(flush([0, 4, 12])) # Ace of hearts, 2 of hearts, 4 of hearts idea/algorithm for checking for flush - check 1st and 2nd, 2nd and 3rd, 3rd and 4th, ... * suit of 0, suit of 4 heart , heart - same! * suit of 4, suit of 12 heart , heart - same! flush([0, 4, 9]) * suit of 0, suit of 4 heart , heart - same! * suit of 4, suit of 9 heart , diamond - not same X * answer should be False for i in range(1, len(hand)): if card[i]%4 != card[i-1]: return False # if made here, never returned False, so all cards are the same suit return True pairs... check if at least two with the same number 2 of diamonds, K of hearts, 6 of hearts, 2 of spades 5, 48, 20, 6 sorted - 2 of diamonds, 2 of spades, 6 of hearts, K of hearts 5 6 20 48 is 2 of diamonds same value as 2 of spades? yes - return True Ace of clubs, 2 of hearts, 7 of diamonds 3, 4, 25 (6 remainder 1) is ace of clubs same value as 2 of hearts? no is 2 of hearts same value as 7 of diamonds? no return False Note - need to sort the cards first. ** numberFun.py ** - See video explanation Who cares? * The sieve is actually very efficient, and you can list out the primes up to large numbers this way. * Much faster than doing a prime test for every i from 1 to n. First algorithm of listing primes by checking if each is prime - too slow. * Moral of the story - designing algorithms - come with something that is correct, if it's to slow make it better/faster. n = 50 # example, for what isPrime would look like at the end # note - leaving commas out to make it look nicer # abbreviate True as T, list indexes isPrime = [ F F T T F T F T F F 0 1 2 3 4 5 6 7 8 9 F T F T F F F T F T 10 11 12 13 14 15 16 17 18 19 F F F T F F F F F T 20 21 22 23 24 25 26 27 28 29 F T F F F F F T F F 30 31 32 33 34 35 36 37 38 39 F T F T F F F T F F 40 41 42 43 44 45 46 47 48 49 F 50 ] Note: it is enough to cross out for p's with p**2 <= n, so p <= sqrt(50) = 7.071067811865475 Running time: # of p's that we checked: <= 7, <= sqrt(n) # of times crossed out: 54 (??), maybe around n?? <= n/2 + n/3 + n/5 + n/7 + … + n/(sqrt(n)) <= n/2 + n/3 + n/4 + n/5 + n/6 + n/7 + … + n/(sqrt(n)) = n * (1/2 + 1/3 + 1/4 + 1/5 + … + 1/sqrt(n)) that is <= n * sqrt(n) actually roughly n * ln(n), because the harmonic series note that ln(n) grows very slowly, so really the # of time's crossing is out is <= constant * n, maybe 20 * n note that the formula n/2 + n/3 + n/5 + … actually is even better, it's roughly n * ln(ln(n)) ** birthdays.py ** How many numbers 1-10 until we get a repeat? 9, 6, 5, 1, 7, 10, 3, 8, 3. That took 9 times. 2, 5, 4, 8, 4. That took 5 times. 5, 2, 8, 8. That took 4 times. 7, 8, 3, 4, 8. That took 5 times. How about numbers 1-50? 33, 24, 2, 50, 17, 21, 11, 7, 50. That took 9 times. 16, 44, 19, 14, 19. That took 5 times. How about birthdays - numbers from 1-365? b = [7, 8, 3, 4, 8] # are there duplicates b.sort() # then b = [3, 4, 7, 8, 8] Check b[1] versus b[0], b[2] versus b[1], b[3] versus b[2] • If any are the same, we have a duplicate • If none are the same, we do not. We ran it maybe 50 times, and had answers between 6 and 54, average somewhere in the 20s Nice explanation for what we should expect. Suppose we have 50 people. Call this K. Call N = 365 What is the chance that none of them have the same birthday? Each pair of the 50 people could have the same birthday. How many different pairs of the 50 people are there? How many ways to choose 2 people out of 50? 50 choose 2, aka binom(50, 2) = 50! / (48! * 2!) = 50*49 / 2 = 1,225, roughly K**2 / 2 For a particular pair, what is the chance they have the same birthday? 1/365 What is the expected number of pairs of people with the same birthday? It turns out: 1225 * (1/365) = 3.3562 In general, it is roughly K**2 / 2 / 365 K = 20, 20*19 / 2 / 365 = 0.5205 K = 15, 15 * 14 / 2 / 365 = 0.2877 Expected # of pairs that are the same is roughly K**2 / 2 / N, so once K gets about sqrt(2N), then there's a pretty good chance Why do we care? It's a math problem, and we can run simulations. The simulation should give a similar answer as the math.