// P02 (*) Find the last but one element of a list. // Example: // scala> penultimate(List(1, 1, 2, 3, 5, 8)) // res0: Int = 5 object P02 { // Again, with builtins this is easy. def penultimateBuiltin[A](ls: List[A]): A = if (ls.isEmpty) throw new NoSuchElementException else ls.init.last // But pattern matching also makes it easy. def penultimateRecursive[A](ls: List[A]): A = ls match { case h :: _ :: Nil => h case _ :: tail => penultimateRecursive(tail) case _ => throw new NoSuchElementException } // Just for fun, let's look at making a generic lastNth function. // An obvious modification of the builtin solution works. def lastNthBuiltin[A](n: Int, ls: List[A]): A = { if (n <= 0) throw new IllegalArgumentException if (ls.length < n) throw new NoSuchElementException ls.takeRight(n).head } // Here's one approach to a non-builtin solution. def lastNthRecursive[A](n: Int, ls: List[A]): A = { def lastNthR(count: Int, resultList: List[A], curList: List[A]): A = curList match { case Nil if count > 0 => throw new NoSuchElementException case Nil => resultList.head case _ :: tail => lastNthR(count - 1, if (count > 0) resultList else resultList.tail, tail) } if (n <= 0) throw new IllegalArgumentException else lastNthR(n, ls, ls) } }