Code Kata Answers to Calculating averages

Following on from Code Kata friday

I know John's works (C#) and mine (Ruby) - The good doctor's I assume does (F#) - So that gives you a solution in C# Ruby and F# (I found  the # key on a mac - its [alt-3]!) 

Enjoy 

 

John's solution 

decimal[] CalculateAverages(IEnumerable<decimal?> series)
{
  return series.Select((d, i) => new {D = d.GetValueOrDefault(), I = i/2})
                       .GroupBy(arg => arg.I)
                       .Select(grouping => grouping.Average (arg => arg.D))
                       .ToArray();
}

my solution

(I'll post the full file at the bottom as Pascal didnt help me out with the random list generator - I had to write my own) 

def calculate_averages()
    @results = []
    #make all the nulls 0
    @working_array.each{|item| if(item == nil)
                                    @working_array[@working_array.index(item)]=0
                               end}
    #if we are odd length add last again so not to skew avge
    if(@working_array.length.odd?)
         @working_array << @working_array.last
    end
    #I think this is cool tho !!
    1.step(@working_array.length, 2) {|i| @results << ((@working_array[i] + @working_array[(i-1)])/2.00)} 
    puts "Results = #{@results}"
end

The good doctors solution



let swap f x y = f y x
 
let rec avgRec x acc =
    let avg a  =
        match a with   
            | Some x,Some y -> (x + y) / 2.0
            | None, Some y -> y /2.0
            | Some x, None -> x /2.0
            | _ -> 0.0
    match x with
        | f::s::t ->  avgRec t (acc @ [avg (f,s)])
        | _ -> acc
 
let Average  : float list= swap avgRec [] 
 
let src = [for i in 1 .. 20 -> if i % 3 <> 0 then Some(float(i)) else None]
let res = src |> Average



 

And for anyone interested the rest of the ruby class with the list generator

class BuildAndAveragePairs
  #accepts the beginning array length and the max random number allowed
  def initialize(array_length, max_random_number)
    @array_length = array_length
    @max_rand = max_random_number
  end

  #generate a 10 digit array with a nil inserted in a random place 25% of the the places?
  def random_array_with_null
    @working_array = []
    (1..@array_length).each do |x|
      if((rand(100)) > 75)
        @working_array << nil
      else
        @working_array << rand(@max_rand)
      end
    end
    @start_array = @working_array
    puts "Working array is #{@working_array}"
    calculate_averages()
  end

#calculate averages def goes here 

end

myCalc = BuildAndAveragePairs.new(10, 100)


(1..5).each do |x|
  myCalc.random_array_with_null
end

hope you enjoyed it :-) I'll post the next one when we have it

August 16 2011

First Code Kata Post

So - We have a code Kata email every friday - usually posed by the boolean frog (pascal.nationality == french)

I think the interaction on our list around these is awsome so I think it is worth sharing - and here is why 

most Friday's Pascal posts a problem and we all attempt to solve it - Mostly in C Sharp but sometimes in F sharp ruby etc (Am on a mac and do you think I can find the effing sharp key :-( ) 

 

Anyway 

This weeks puzzle was 

Excel can solve this Kata very easily, wonder how easy it is in C#/Ruby/F#/JS.

Shortest (correct) answer wins!


/*
Given a list of nullable decimals, calculate the average of each consecutive pair of decimal values.
Example:
 
{6, 2, 0, 4, 3, null, 2, 6, 8, 4}        =>            {4, 2, 1.5, 4, 6}   
{6, 2, 0, 4, 3, null, 2, 6, 8, 4, 99}    =>            {4, 2, 1.5, 4, 6, 99}
 
*/
void Main()
{
       var rand = new Random();
       int max = rand.Next(0, 48);
       IEnumerable serie = Enumerable.Range(1, max).Select (i => (decimal?)rand.Next(0, 10));
 
       var result = CalculateAverages(serie);
 
       result.Dump();
}
 
decimal[] CalculateAverages(IEnumerable serie)
{
       // YOUR CODE HERE
       return new decimal[]{};
}

So the question is how do you solve it??

Being the resident ruby geek my solution was - ahem - in ruby there were some nice other solutions but how do you solve it???

Before you try some things to note

  1. Null values are treated as 0 in the list passed in as parameters.
  2. The list passed in can be made of either integers, decimals (floats in Ruby) or null values.
  3. If all values are null, then 0 will be the average for all 2 consecutive value pairs.
  4. The list can have 0, 1 or more numbers.
  5. The list can have either an even or odd count.
  6. The result should not contain any null values.

I'll post some of the answers here tomorrow - But if you want to try to win (Remember the shortest answer to the Calculate average method is what we are after) then feel free to leave a comment and if you win you will get - ummm - some kudos - -)

good luck and answers here (Not quite the quoted tomorrow - Ah well )

Mal 

5-08-2011

 

 

August 6 2011
Older Posts