12.8 Exercises
12.8 Exercises
1. (Easy: Documentation Reading)
Read the Perl documentation on subroutines in Perl by running the following.
%perldoc perlsub
2. (Easy: Recursion)
How are parameters passed to a Perl subroutine? What are your comments on the mechanism of parameter passing in Perl? How will you pass two arrays to a Perl script? Write a script that takes two arrays as actual parameters, and returns a hash where the elements of the first array are keys and elements of the second array are values. The two arrays that are passed to the function are of the same length although the length can be arbitrary. Use statically scoped variables.
3. (Easy: List Processing)
The operators ++ and -- increment and decrement a number by one, respectively. Write a recursive function add for adding two numbers without using + explicitly. Use ++ and --.
4. (Easy: List Processing)
Define a function removeIf that takes a reference to a list and a reference to a predicate as argument, and returns reference to a list that contains elements of the original list that satisfy the predicate. A predicate is a subroutine that takes a scalar input and returns either true or false.
Write the function removeIf in three ways:
(a) using iteration,
(b) using recursion, and
(c) using map.
5. (Easy: List Processing)
Write a function filter that takes a reference to a predicate function and a list as argument. It returns the elements of the list that satisfy the predicate.
filter (\&numberP, 1, 2, "a", 3, "b")
returns
(1, 2, 3)
Here, numberP is a function that takes a scalar and returns true if it is not.
6. (Easy: List Processing)
Define a function group that takes an integer n and reference to a list as argument, and returns a list where the elements have been grouped into sublists of length n. The last sublist may have fewer than n elements. For example, if @list contains qw(a b c d e f g), the call
group (2, \@list)
produces the following list as result.
(["a", "b"], ["c", "d"], ["e", "f"], "g")
7. (Easy: List Processing)
Define a function flatten that takes a predicate and an anonymous list as an argument and returns a list that flattens the internal lists. For example, the call
flatten (["a", ["b", "c"], "[[d","e"], "f"]])
returns
("a", "b", "c", "d", "e", "f")
8. (Easy: List Processing)
Write a function prune that takes a reference to a predicate function of one argument and an anonymous list with embedded lists in it, and returns a list after removing all leaf-level elements that satisfy the predicate. It keeps the structure of the list intact.
prune (\&evenP, [1, 2, [3, [4, 5], 6], 7, 8, [9]])
returns
(2, [[4], 6], 8)
Here, evenP is a function that takes an argument and returns true if it is an even number.
9. (Easy: List Processing)
Write a function before that takes two elements and a reference to a list and returns true if the first argument occurs before the second argument in the list.
before ("b", "d", ["a", "b", "c", "d"])
returns true. Modify it to return ("b", "c", "d"), the part of the list starting from the point where the before requirement holds. Write two versions, using iteration and using recursion.
10. (Easy: List Processing)
Write a function duplicate that returns those elements of a list that are duplicated. For example,
duplicate ("a", ["a", "b", "c", "a", "d"])
returns
("a", "d")
In other words, it returns the part of the list starting from where the duplication occurs. Write two versions, using iteration and recursion, respectively.
11. (Easy: List Processing)
Define a function splitIf that takes a list and splits it if a predicate is satisfied.
splitIf (sub { $_[0] > 4}, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
returns something like
([1, 2, 3, 4], [5, 6, 7, 8, 9, 10])
12. (Easy: List Processing)
Write a function most that takes a scoring function and a list and returns the element with the highest score. In case of ties, the element occurring first wins. For example,
most (sub{return $#_ + 1},
[["a", "b"], ["a", "b", "c"], ["a"], ["e", "f", "g"]])
returns
("a", "b", "c")
Here, the scoring function returns the length of a list given as argument.
13. (Easy: List Processing)
Write a function best that takes a function and a list. The function is a predicate of two arguments. It returns the elements which according to the predicate, beats all others. For example,
best (sub{$_[1] > $_[2]}, (1, 2, 3, 4, 5))
returns 5.Here, the function compares two elements given to it as argument and returns true if the first element is larger than the second element. This call results in sorting in ascending order.
14. (Easy: List Processing)
Write a function sqrtL that takes a list as argument and returns a list containing the squares of all elements that are numeric. It removes any non-numeric elements from the result list. Use map.
15. (Easy: List Processing)
Write a function mapS that takes an anonymous subroutine as the first argument, and a list of references to lists. It applies the first function to every element of the list.
mapS (\$sqrt, $list1, $list2, ...)
Here, $sqrt is is a reference to a function. $list1, $list2, etc., are references to lists.
16. (Medium: List Processing, Recursive)
Write a function rmap that takes one list as argument. It stands for recursive map. For example,
rmap (sub{$_[0] + 1}, [1, 2, [3, 4, [5], 6], 7, [8,9]])
returns
[2, 3, [4, 5, [6], 7], 8, [9 ,10]])
17. (Medium: List Processing, Recursive)
Write a function copyTree that takes a reference to a list that contains embedded lists. A list containing embedded lists can be considered a tree. It makes a new copy of the original tree and returns a reference to it.
18. (Medium: List Processing, Recursive)
Write a function rFindIf that generalizes findIf for trees, that is, for lists with embedded lists in them. For example,
rfindIf (fint (\&numberP, \&oddP), [2. [3, 4], 5])
returns 3. Here, fint is the function discussed in the Chapter. numberP and oddP are predicate functions of one argument each.
19. (Easy: Closure)
Write a function toggle such that successive calls to it alternately returns 1 and 0, respectively. Use closure. Do not use a global variable. Make the function self-contained.
20. (Medium: Closure)
Write a function greatest that takes one argument, a number, and returns the greatest argument passed to it so far in many calls. Use closure. Do not use a global variable or a file.
21. (Medium: Closure)
Write a function greater that takes one argument, a number, and returns true if it is greater that the argument passed to the function the last time it was called. The function returns an undefined value the first time it is called. Use closure. Do not use a global variable or a file.
22. (Medium: Closure)
Suppose factorial is a function of one argument. It takes an integer between 0 and 100 inclusive, and returns the result n!. Define a function frugalFactorial that returns the same answer, but only calls factorial when the given argument has not been seen before.
Write two versions of a function that computes the nth Fibonacci number. Do not use a global variable or a file. Use closure.
