1. Define a function apply_twice that takes a function f and a value x, and returns the result of applying f to x two times.

     def sqr(x):
       return x * x
    
     def apply_twice(f, x):
             """apply f to x twice.
    
             >>> apply_twice(sqr, 3)
             81
             """
    
  2. Define a function applier that applies a given function f to the argument x for n times.
     def sqr(x):
       return x * x
    
     def applier(f, x, n):
             """apply f to x  n times.
    
             >>> applier(sqr, 3,2)
             81
             """
    
  3. Given an integer \(k>1\), compute the largest positive integer \(n\) smaller than \(k\) s.t. there is no other integer between 1 and \(k\) with a larger Collatz length. Use proc_seq from here. Define two versions, one with while the other with proc_seq from here.
  4. Given an integer \(k>1\), compute the largest positive integer \(n\) smaller than \(k\) s.t. there is no other integer between 1 and \(k\) with a larger Collatz length. Use proc_seq from here.
  5. Define a function argmax(f,start,end,step=1) that returns the smallest argument that maximizes f in the range [start,end] incremented in steps.