## Session 25

### Quick Exercise: Homework 10

Now that Homework 10 is in the books, answer me questions three:

• Which problem was the easiest to solve?
• Which problem was toughest to solve?
• Which problem's answer -- or code -- do you most want to see?

### Quick Exercise: Happy Numbers

Choose a two-digit number. Square each digit. Add the squares together to get a new number. Repeat this process until you reach 1 or until you see a number repeat itself.

If you reach 1, then the number you started with is a happy number. If you hit a cycle, then the number you started with is unhappy.

For example, 13 is happy, because 13 → 12 + 32 = 10 → 12 + 02 = 1. 4 is unhappy, because it generates the sequence 4, 16, 37, 58, 89, 145, 42, 20, 4, which repeats.

Write a Python function is_happy(n) that returns True if n is happy and False otherwise.

You may assume that we have already written the function sum_of_digits_squared(n). (You should try to write it yourself, as a study problem.)

Hint: A list might be handy...

### Review of Homework 10

Easy. If you were looking for ways to save time or energy, reading all the problems ahead of time was worth the effort. Puzzles (g) and (j) were gimmes! And we had already solved Puzzle (k) back in Session19.

Hard. Puzzle (b) challenged me. When I saw the same idea pop up in Puzzles (f) and (i), I was glad to be able to use what I'd learned before -- as well as the code.

Curious (answer). I like word puzzles, so these all seemed interesting. For me, Puzzles (b) and (h) held a bit more interest, I suppose.

Curious (code). I like word puzzles, so these all seemed interesting. For me, Puzzles (b) and (h) held a bit more interest, I suppose.

I started off with a short file that had basic functions and a solution to Puzzle (a). Eventually, I grew an solution for all the puzzles, plus a little machinery.

Some observations:

• Sometimes, a problem leads to code that may surprise us. Puzzles (d) and especially (e) were pretty simple in code.

• I wrote helper functions to make my solutions say what I was thinking.

• In at least one case, str_remove, I was able to use the same function again, with a small twist.

Puzzle (a) created an interesting problem. It was easy to express a simple solution that everyone can understand immediately. But it ran s-l-o-w-l-y.

Why?

How can we make solve the puzzle more efficiently?

The problem is that the new code is much harder to write and debug. My first attempt was faster, but not fast enough. Eventually, I solved the programming puzzle by realizing that startswith() cut our search time drastically.

The final solution is much harder to understand than the simple solution. Is it worth it?

... algorithms, data structures, efficiency. Much to learn!

### Other Assignments

Any questions about Exam 2? Chapters 5-7, minus a few sections, plus today's reading. Files, functions, and lists, with more problem decomposition. As you study, you can follow the same advice I gave for Exam 1.

Return Homework 9. We looked at my solution last week. Version 1 is the simplest.

### Image Credits

The image of Will Shortz comes from FamousDude.com. Like me, Shortz is a native Hoosier. He once played himself on an episode of How I Met Your Mother. If that isn't cool enough, he majored in enigmatology in college.

### An is_happy(n) Function

The process requires repeatedly evaluating a number and finding a next number. We don't know when the process will end. That sounds like a while loop.

```    while true,
if we are done, return an answer
compute next number
```

How will we know if we have seen a number before? We can store every number see in a list.

```    list starts empty
while true,
if we are done, return an answer
put the number in the list
compute next number
```

Each of these lines is implemented in a line of Python -- except for "if we are done", because there are two ways to be done!

```    numbers_seen = []                  # list starts empty
while True:                        # while true,
if n == 1:                     #   if we are happy,
return True                #      return an answer
if n in numbers_seen:          #   if we are happy,
return False               #      return an answer
numbers_seen.append(n)         #   put the number in the list
n = sum_of_digits_squared(n)   #   compute next number
```

And there is a solution.

This works fine when testing one number. But when we call it repeatedly in a loop, as in print_happy(), it repeats the process more often than it needs to. (If we have checked 4, then we already know the answer for 37 and 42!) Can you think of a way to make our function more efficient?

I recently came across this puzzle again after many years, via The Happy Numbers Kata, by Kevin Rutherford. His blog is one of my favorites, full of good advice on programming, object-oriented design (which you will study in CS 2530), and the Ruby programming language (which is like Python).

### Wrap Up

• Code -- today's code file

• Reading -- No new reading. Review Chapters 5-7, today's reading, the lecture notes, and your homework assignments. Recall that we skipped some sections, such as Section 7.8.

• Homework -- Homework 10 was due today. We are taking a week off from programming assignments for the exam.

• Exam -- Exam 2 is next session.

Eugene Wallingford ..... wallingf@cs.uni.edu ..... November 18, 2014