Exercise 8.1: Solve problems with map, reduce and filter
Here is a series of simple tasks which you could easily solve with a for-loop in most cases. However the challenge here is to solve the problems without using a for-loop and instead use one of the
Exercise 8.1a: Add numbers
sumup(xs) which adds up all the numbers in an iterable collection
xs. It should be usable like the builtin
sumup (generic function with 1 method)
Exercise 8.1b: Factorial
fac(n) which calculates the factorial of the number
n. The factorial of 6 is
6! = 6 * 5 * 4 * 3 * 2 * 1 = 720, while the factorial of 3 is
3! = 3 * 2 * 1 = 6.
DefaultTestSet("fac tests", Any, 3, false)
Exercise 8.1c: Find length of longest word
longest(strings) to find the length of the string in the collection of strings called
DefaultTestSet("finding longest word tests", Any, 3, false)
Exercise 8.2: Implement the zip function
zip function appears in many functional languages and also exists in the Julia standard library. It is used to combine two or more separate lists of objects into a single list of composite objects, such as a tuple.
zip can work with any number of iterable collections but we want to make a simplified version called
combine which takes two collections and combine them to one.
DefaultTestSet("combine tests", Any, 3, false)
Exercise 8.3: Implement a "zip with" function
In some functional languages there is a function called
zipwith which is a more generic version of
zip. It lets you specify the function which should combine two elements.
DefaultTestSet("zipwith tests", Any, 3, false)
Exercise 8.4: Reverse Polish Notation Calculator
Reverse polish notation is a way of expressing calculations which does not require parentesis to express the order of computations. Calculations are based on having a stack of inputs values and operations.
It is easiest to explain with some examples.
3 + 4 in reverse polish notation (RPN) would be written as
3 4 +. Basically you list the numbers you want to do something with and then you specify the operation you want to do on them. This is beneficial in complex expressions.
These expressions would in RPN turn into:
Let us look at the first expression. We read from left to right.
Start by putting 3 and 4 on the stack.
When we encounter
+ we pop the two top elements from the stack which are 3 and 4 and add them. This gives 7, which is put on the top of the stack.
Put 2 on the stack. The stack now looks like
* operator. Pop top values from the stack and multiply them.
We end up with 14 as the result.
The following functions will be useful in this exercise:
vcat vertical concatenation of arrays. Remember regular 1D arrays in Julia are column vectors, hence stitching them together is vertical concatenation.
reduce Useful whenever you are processing a list of elements and want to turn them into one value.
... splat operator. Turn an array, tuple etc into multiple function arguments.
DefaultTestSet("solve RPN tests", Any, 1, false)
Exercise 8.4b: Parse string input (tricky)
Imagine you are reading an expression directly from the command line or from a file. You will not get the input as a neat Julia array of numbers and operations. Instead you will get a string which you need to parse.
Add a method to
solve_rpn which processes string input. In this case we need to be introduced to some new Julia functions:
Meta.parse this is different from
parse which is just for parsing types.
Meta.parse can parse any Julia expression, and turn it into Julia code. Or more specifically it will turn it into expressions made up of symbols and literals.
eval will take Julia code and evaluate it. So a symbol such as
:+ will turn into the function object
+. The number literal
4 will just turn into the number
4. Strings and numbers just evaluate to themselves.
DefaultTestSet("solve RPN parsing tests", Any, 3, false)