Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-

how do I average in scheme?

Name: Anonymous 2010-12-26 21:31

im learning scheme and im not very good its my first languages what am i doing wrong

(define (average nums)
   (/ (+ (car nums) (average (cdr nums))) 2))

then i do (average (list 2 3 4 5 6)) but it doesnt work
also how can i do that (average 2 3 4 5 6) gives me the average without doing a list?

please help

Name: Anonymous 2010-12-26 21:43

You need to write a loop that checks if the next element of your list is not null. Dividing by 2 won't really work either, seeing that the lenght of your list can vary, keep a counter the counts the elements in your list or use length if you want to make it less performant...

Name: Anonymous 2010-12-26 21:55

how do i do that? its my very first language i dont know how to do that pls help

Name: Anonymous 2010-12-26 22:16

In Scheme I'd just write:

(define (average . numbers) 
  (/ (apply + numbers) (length numbers)))

(average 1 2 3)
2


If you insist on using recursion even when there are better ways to handle it, you can write:


(define (average . numbers)
  (letrec ((loop
            (lambda (total nrs count)
              (if (null? nrs) (/ total count)
                  (loop (+ total (car nrs)) (cdr nrs) (+ count 1))))))
    (loop 0 numbers 0)))

However, I find the second kind of code kind of long-winded for such simple tasks, but I guess that's why I'm more of a CLer than a Schemer

In CL, I'd just write:

(defun average (&rest numbers)
  (/ (reduce #'+ numbers) (length numbers)))
;; or
(defun average (&rest numbers)
  (/ (loop for n in numbers summing n) (length numbers)))

Name: Anonymous 2010-12-26 22:32

>>1,3
I've done it for you:
((((((λ(d)(λ(p)(λ(e)(λ(i)(λ(n)(d(n e p)(n i)))))))/)+)5)4)((((((((((λ(a)(λ(r)(λ(d)(λ(m)(λ(p)(λ(g)(λ(vr)(λ(v)(λ l((λ(j)((λ e((λ(f)(λ(z . o)(a(vr f z)o)))(a v e)))(λ(a)(set! j(+ j 1))(set! l(m l a)))(λ()(r l))(λ()(d l))(λ()(p j l))(λ()j)(λ(f)(a f l))))(g l)))))))))))apply)car)cdr)cons)(λ(j l)(or(zero? j)(null? l))))length)vector-ref)vector)1 2 3 4 5))

Name: Anonymous 2010-12-27 0:39

>>4

What's the point of loop/letrec in your recursive example? Why not just something like this:


(define (average . numbers)
  (define average' (nums count)
    (if (null? nums) (/ nums count)
        (+ (car nums) (average' (cdr nums)))))
  (average' numbers (length numbers)))

Name: Anonymous 2010-12-27 0:45

>>6
I guess that works. I just tend to use letrec's more than inner define's, it's not that much of a difference.

Name: >>7 2010-12-27 0:49

>>6
However, there is one slight disadvantage to your version, you're just passing the length around without actually making use of it, so your average' is nothing more than a sum (apply + nums) which divides at the end. You also traverse the list twice making it take longer than the recursive version which measures the length while both adding the total. I'm guessing your version is similar in speed to my first example, while my second example being faster as the list is only traversed once. In real code, I never consider writing such explicit adding/summing unless it's some code which needs to be optimized (only done after seeing the results of profiling).

Name: Anonymous 2010-12-27 0:52

Oh nvm, just remembered what letrec means, was a bit confused there for a moment. Also i meant to write this ofc:

(define (average . numbers)
  (define average' (nums acc count)
    (if (null? nums) (/ nums count)
        (average' (cdr nums) (+ (car nums) acc) count)))
  (average' numbers 0 (length numbers)))

Name: Anonymous 2010-12-27 0:56

You're right ofc. So the final version would be this:

(define (average . numbers)
  (define average' (nums acc count)
    (if (null? nums) (/ nums count)
        (average' (cdr nums) (+ (car nums) acc) (+ count 1))))
  (average' numbers 0 0))

Name: Anonymous 2010-12-27 1:09

Correctly:

(define (average . numbers)
  (define (average' nums acc count)
    (if (null? nums) (/ acc count)
        (average' (cdr nums) (+ (car nums) acc) (+ count 1))))
  (average' numbers 0 0))

Name: Anonymous 2010-12-27 6:24

>>9-11
You can't have ' in symbols.

The SATORI way to do it (other than >>5):

(define average
  (lambda ns
    (let loop ((ns ns)
               (i 0)
               (r 0))
      (if (null? ns) (/ r i)
          (loop (cdr ns)
                (+ i 1)
                (+ r (car ns)))))))

Name: Anonymous 2010-12-27 11:09

do it in haskell, faggots

Name: Anonymous 2010-12-27 12:17

let average (x:xs) = "I'm a faggot"

Name: Anonymous 2010-12-27 12:28

>>13
Do it in a language that isn't a child's plaything language.

Name: Anonymous 2010-12-27 14:14

>>4

apply is recursion, faggot

Name: Anonymous 2010-12-27 15:14

(/ (foldr + 0 nums) (length nums))

Name: Anonymous 2010-12-27 15:17

You type the numbers and pray.  If the Great Suss has heard your honest words, you will get your answer the next time you press the "Enter" key.

Name: Anonymous 2010-12-27 16:29

>>17
(/ (apply + nums) (length nums))

Name: (o,ø) 2010-12-27 17:19

average = (\(o,ø)->ø/o).foldr(\c(o,ø)->(o+1,ø+c))(0,0)

Name: (o,ø) 2010-12-27 17:20

average = (\(o,ø)->ø/o).foldr(\c(o,ø)->(o+1,ø+c))(0,0)
Forgot my [code] tags... I feel so silly now!

Name: HAXUS 2010-12-27 20:57

BEGIN average (list::List[Int]) :: Float
    val sum::Int <- list->foldl(Operator->PLUS, 0)
    val length::Int <- list->length()
    sum / length
END

Name: Anonymous 2010-12-27 21:17

sub prefix:<r/+> (@_) { reduce &(-> $x, $y { $x + $y }), @_ }
r/+(1, 2, 3, 4 ,5) # => 15
sub prefix:<//?> (@_) { (r/+@_) / $(@_) }
//?(1, 2, 3, 4, 5) # => 3


An operator for everything!

Name: Anonymous 2010-12-27 21:29

>>23
Better:

sub prefix:<r/+>(@_){reduce &infix:<+>, @_}
sub prefix:<//?>(@_){(r/+@_)/$(@_)}
//?(1,2,3,4,5)

Name: Anonymous 2010-12-27 22:44

>>24
sub prefix:<//?>{([+]@_)/@_}
//?(1,2,3,4,5)

Name: Anonymous 2010-12-28 0:40

>>25
An operator for everything!

Name: Anonymous 2010-12-28 0:41

I do it in simple declarative point-free style, like this:

average xs -> [l:@!len]:[s:@!sum]:xs s%l

"[s:@!sum]:" binds `s` to the result of applying hypothesis, that `xs` can be represented as sum of its elements
"[l:@!len]:" does same for length
"s%l" divides sum by length

Name: Anonymous 2010-12-28 1:01

The EXPERT FIOC PROGRAMMER ONLY ONE WAY TO DO IT:
from math import average
average([1,2,3,4,5])


Everything else is unpythonic

Name: Anonymous 2010-12-28 1:24

>>28
Now try rounding.  (to the nearest 0.5 if possible)

Name: >>4 2010-12-28 5:41

>>16
Doesn't have to be. It depends on implementation. Internally, it will always be a loop...

Don't change these.
Name: Email:
Entire Thread Thread List