|
| 1 | +# Fzz Buzz 2 - 200 points |
| 2 | + |
| 3 | +Oh no! Two of my keys are broken! Please help me make the same Fzz Buzz program, sans that one letter and queston marks. |
| 4 | + |
| 5 | +As a side note, use of `eval()` and `exec()` is also frowned upon and will be marked invalid. |
| 6 | + |
| 7 | +***This writeup is a python solution*** |
| 8 | + |
| 9 | +### Summary |
| 10 | + |
| 11 | +The goal of this challenge was to write a fizz buzz program without using the letter `i` or the question mark character `?`. You must read an integer `n` from stdin and print that many lines of fizz buzz. For example, if `n = 17`, output: |
| 12 | + |
| 13 | +``` |
| 14 | +1 |
| 15 | +2 |
| 16 | +Fizz |
| 17 | +4 |
| 18 | +Buzz |
| 19 | +Fizz |
| 20 | +7 |
| 21 | +8 |
| 22 | +Fizz |
| 23 | +Buzz |
| 24 | +11 |
| 25 | +Fizz |
| 26 | +13 |
| 27 | +14 |
| 28 | +FizzBuzz |
| 29 | +16 |
| 30 | +17 |
| 31 | +``` |
| 32 | + |
| 33 | +### How to get input / print |
| 34 | + |
| 35 | +In order to get user input, you must call `input()` and likewise, to print you must call `print()`. Therefore, we need some way to alias these functions without using the character `i`. |
| 36 | + |
| 37 | +**Solution:** |
| 38 | + |
| 39 | +Both `input` and `print` belong to the `__builtins__` module that is loaded automatically on startup. Therefore, we can find a reference to these functions by using `getattr` on the `__builtins__` module. |
| 40 | + |
| 41 | +```python |
| 42 | +f = getattr(globals()['__builtins__'],'input') |
| 43 | +p = getattr(globals()['__builtins__'],'print') |
| 44 | +``` |
| 45 | + |
| 46 | +Then by simply escaping the `i` character we get this: |
| 47 | + |
| 48 | +```python |
| 49 | +f = getattr(globals()['__bu\x69lt\x69ns__'],'\x69nput') |
| 50 | +p = getattr(globals()['__bu\x69lt\x69ns__'],'pr\x69nt') |
| 51 | +``` |
| 52 | + |
| 53 | +Now `f` will call `input` and `p` will call `print`. |
| 54 | + |
| 55 | +### How to loop |
| 56 | + |
| 57 | +Since the user provides the number of lines to print, we must find some way to loop from `1` to `n`. |
| 58 | + |
| 59 | +**Solution:** |
| 60 | + |
| 61 | +Let's use recursion. We will read `n` from the input and then define a function `go(k)` that prints the text for line `k` and calls itself with `k+1` if `k < n`. Finally, we will start it off by calling `go(1)` That looks like this: |
| 62 | + |
| 63 | +```python |
| 64 | +n = f() # Using our alias |
| 65 | + |
| 66 | +def go(k): |
| 67 | + # Do some print magic here |
| 68 | + if (k < n): |
| 69 | + go(k+1) |
| 70 | + |
| 71 | +go(1) # Start the chain |
| 72 | +``` |
| 73 | + |
| 74 | +### How to use conditionals? |
| 75 | + |
| 76 | +We ran into a problem in our last task: we can't use `if` since it has an `i`. Therefore, we must find some other way to get conditional behavior. |
| 77 | + |
| 78 | +**Solution:** |
| 79 | + |
| 80 | +How about short-circuiting? In python (and many other languages) a conditional will stop evaluation if one side can determine the entire expression. For example, in the following expression, the conditional inside `print` checks if `a == 1`. Since that is `False`, there is no way for the expression to be true (because `False AND x == False` regardless of `x`) Therefore, the expression `b == 1` isn't even evaluated. |
| 81 | + |
| 82 | +```python |
| 83 | +a = 5 |
| 84 | +b = 3 |
| 85 | + |
| 86 | +print(a == 1 and b == 1) |
| 87 | +``` |
| 88 | + |
| 89 | +We can use this to our advantage. How about if we put the check as the first conditional and the print as our second. Therefore, if the check succeeds, we print the line. Here is what that looks like: |
| 90 | + |
| 91 | +```python |
| 92 | +a = ((k % 15 == 0) and p('F\x69zzBuzz')) |
| 93 | +``` |
| 94 | + |
| 95 | +In the previous line, we first check if `k` (the line number) is divisible by `3` and `5` (or just `15`). If it is not, the conditional short-circuits and the right side is not evaluated. If it is, we call `p('F\x69zzBuzz')` which prints `FizzBuzz`. (The `a =` is just so that it is a valid expression). |
| 96 | + |
| 97 | +### Putting it all together |
| 98 | + |
| 99 | +Therefore, using all of these ideas, we can come up with the following program: |
| 100 | + |
| 101 | +```python |
| 102 | +# Create aliases |
| 103 | +f = getattr(globals()['__bu\x69lt\x69ns__'],'\x69nput') |
| 104 | +p = getattr(globals()['__bu\x69lt\x69ns__'],'pr\x69nt') |
| 105 | + |
| 106 | +# Get user input |
| 107 | +n = f() |
| 108 | + |
| 109 | +# Prints text for line k and calls itself with the next line |
| 110 | +def go(k): |
| 111 | + a = ((k % 15 == 0) and p('F\x69zzBuzz')) |
| 112 | + a = ((k % 3 != 0 and k % 5 == 0) and p('Buzz')) |
| 113 | + a = ((k % 3 == 0 and k % 5 != 0) and p('F\x69zz')) |
| 114 | + a = ((k % 3 != 0 and k % 5 != 0) and p(k)) |
| 115 | + a = ((k < n) and go(k + 1)) |
| 116 | + |
| 117 | +go(1) |
| 118 | +``` |
| 119 | + |
| 120 | + |
| 121 | +### External Writeups |
| 122 | + |
| 123 | +* \(none\) |
0 commit comments