Round To 5

August 13, 2019

We begin by creating a random list of speed readings, biasing it so the round-to-5 speed will be 50:

(define speeds
  (do ((n 100 (- n 1))
       (xs (list) (cons (+ (random 19.0) 40) xs)))
      ((zero? n) xs)))

The actual average of the speeds we generated is 49.6 mph:

(define (average xs) (/ (apply + xs) (length xs)))
> (average speeds)
49.59251941983793

Now we need a function to round a number to the nearest 5:

(define (round5 x) (inexact->exact (* (floor (/ (+ x 2.5) 5)) 5)))
> (round5 (average speeds))
50

A simple solution to a simple problem. You can run the program at https://ideone.com/wqc57b.

Advertisements

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 Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: