Round To 5

August 13, 2019

Every morning when I drive to work the highway signs display commute information: 7 minutes to Manchester Road, 11 minutes to Olive Blvd, speed ahead 55 mph. That’s little comfort when I’m sitting still on the highway. The “speed ahead” calculation is always rounded to the nearest 5 mph; the Department of Transportation takes a bunch of speed readings from sensors buried in the pavement and averages them.

Your task is to take a list of speed readings and average them to the nearest 5 mph. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

Pages: 1 2

4 Responses to “Round To 5”

  1. chaw said

    Here is a slightly more general solution in standard R7RS Scheme (and
    a couple of SRFI helpers only for testing). It allows rounding to
    non-integer values too, e.g., the nearest multiple of 25, as the demo
    illustrates.

    (import (scheme base)
            (scheme write)
            (only (srfi 1)
                  list-tabulate)
            (only (srfi 27)
                  random-integer))
    
    (define (rounded-average delta nums)
      (* delta (round (/ (apply + nums)
                         (length nums)
                         delta))))
    
    ;; only demo/testing below
    
    (define (demo/nums nums)
      (display (rounded-average 5 nums))
      (display (rounded-average 0.25 nums))
      (display (inexact (/ (apply + nums) (length nums))))
      (newline))
    
    (define (demo1)
      (demo/nums (list-tabulate 20 (lambda (_) (random-integer 100)))))
    
    (define (call-times n proc)
      (let rec ((i 0)
                (r #f))
        (if (>= i n)
            r
            (rec (+ i 1)
                 (proc i)))))
    
    (define (demo)
      (call-times 10 (lambda (_) (demo1))))
    
    (demo)
    

    Output:

    55 56.25 56.25
    45 47.25 47.15
    45 45.5 45.45
    45 47.25 47.3
    40 41.75 41.8
    60 59.0 59.1
    50 52.25 52.2
    50 50.75 50.7
    50 47.75 47.75
    55 54.5 54.5
    

  2. Klong version: 10 iterations

    Code:
            rnd5::{5*_(x+2.5)%5}; test::{[l]; l::[]; {~x>10}{l::l,40+_19*.rn(); x+1}:~1; .p("avg = ",avg::(+/l)%#l); .p("avg5 = ",rnd5(avg))}; {x<10}{test(); .p(""); x+1}:~0; ""
    
    Run:
    [avg =  47.4]
    [avg5 =  45]
    
    [avg =  46.9]
    [avg5 =  45]
    
    [avg =  49.6]
    [avg5 =  50]
    
    [avg =  47.1]
    [avg5 =  45]
    
    [avg =  46.7]
    [avg5 =  45]
    
    [avg =  49.3]
    [avg5 =  50]
    
    [avg =  45.0]
    [avg5 =  45]
    
    [avg =  48.4]
    [avg5 =  50]
    
    [avg =  48.0]
    [avg5 =  50]
    
    [avg =  50.1]
    [avg5 =  50]
    
    ""
    
  3. Daniel said

    Here’s a solution in Python.

    def round5(l):
        avg = round(sum(l) / len(l))
        offset = [0, -1, -2, 2, 1]
        avg += offset[avg % 5]
        return avg
    
    l = [51, 68, 45, 41, 44, 68, 80, 52, 45]
    print(round5(l))
    

    Output:

    55
    
  4. Bill Wood said

    Rust version

    fn main() {
        let x = vec!(12.1,25.2,27.4,32.1,21.5,1.7,5.6,88.,42.0,19.12,);
        let avg = x.iter().sum::<f64>()/x.len() as f64;
        let answer = (avg/5.0 + 0.5) as usize * 5;
        println!("{}", answer);
    }
    

Leave a comment