Monday 4 July 2011

Counting the Elements

As for counting the number of elements in a sequence without using count or writing a loop - the best I could come up with before my lunch break concluded was to use a lambda (fn [x] 1) that turns everything to one, map this onto the sequence to get a load of ones, and then use reduce and plus to add these ones together:-


#(reduce + (map (fn [n] 1) %))


hmm

Adding the elements of a list of numbers is easier than this - you can use reduce and the plus operator.  To get the odd numbers from a list of numbers you user the function filter with the predicate function odd?

The the examples seem to be out of sequence here.  Anyway, the next one is to produce the reverse of a sequence without using the functions reverse or rseq.

This took a bit more thought.  In the end I changed the original sequence to a list of pair vectors where the first element is an increasing number, like this:

Starting with this list:


user=>'(:a :b :c :d)
'(:a :b :c :d)


Use a map to insert numbers in each one:


user=>(map (fn [x y] [x y]) (iterate inc 1) *1)
([1 :a] [2 :b] [3 :c] [4 :d])


Now sort this using a function that compares those numbers we added:


user=>(sort (fn [x y] (> (first x) (first y))) *1)
([4 :d] [3 :c] [2 :b] [1 :a])


Finally extract the elements by mapping second onto the result:


user=>(map second *1)
(:d :c :b :a)


So the full solution looks like this:


#(map second
 (sort
  (fn [x y] (> (first x) (first y)))
  (map (fn [x y] [x y])
  (iterate inc 1)
  %)))


But surely there is a simpler way?

No comments:

Post a Comment