Perl Weekly Challenge 122: Average of Stream

by Abigail

Challenge

You are given a stream of numbers, @N.

Write a script to print the average of the stream at every point.

Example

Input: @N = (10, 20, 30, 40, 50, 60, 70, 80, 90, ...)
Output:      10, 15, 20, 25, 30, 35, 40, 45, 50, ...

Solution

This is a pretty simple task. We will be reading numbers one by one, keeping a running sum of the numbers, and the amount of numbers read so far — updating those values for each number read. We then print the quotient of the sum and amount of numbers.

We will be assuming the numbers are separated by new lines (so, one number per line).

Unless indicated otherwise, our solutions will use the following variables:

Perl

We will be using the -p and -l flags. -p makes that the program is executed for each line of the input, with the line available in $_. Afterwards, the content of $_ is printed. The -l strips off the newline of the input, and adds a newline when printing.

Instead of using a counter to count the amount of numbers read, we will make use of the special variable $., which contains the current line number.

$_=($;+=$_)/$.

We keep the running sum of the numbers read so far in the variable $;. Each number read will be added to it ($; += $_); this sum we then divide with $. and assign back to $_, which is then printed due to the -p flag.

Find the full program on GitHub.

AWK

AWK executes its program for each line of input, splits the line on whitespace, making the fields available in $1, $2, etc. Since we just have a number per line, all we need is $1.

Just like in Perl, there is a special variable which contains the current line number — NR (number of records). This leads to the following one-liner:

{print ((s += $1) / NR)}

Find the full program on GitHub.

Bash

In Bash we have another one liner. No special variables here.

while read n; do echo $(((s += n) / ++ c)); done

Find the full program on GitHub.

Basic

In our Basic solution, we assume the input is terminated with a 0.

100 INPUT n
110 IF n = 0 THEN END
150 s = s + n
160 c = c + 1
170 PRINT s / c
200 GOTO 100

Find the full program on GitHub.

bc

Just like in our Basic solution, we expect the input to be terminated with a 0:

while (1) {
    n = read ()
    if (n == 0) {break}
    (s += n) / ++ c
}

Find the full program on GitHub.

Befunge-93

Befunge-93 does not have any variables. It has a stack, and we can write values into the 80x24 grid which makes up the program.

We keep the sum of numbers at the bottom of the stack, while we track the amount of numbers read so far at position (8, 8).

088p 0 >>>>>>>>>>>>>>>>>>>>>>>>>>>v
& :1+!#@_ + : 88g1+ :88p / . 55+, >

The first line is used to do some initializations. We write a 0 to position (8, 8) (088p), then put a 0 on the stack, indicating the sum of numbers seen so far.

The second line of the program is the main loop. We start by reading a number, and putting it on the stack (&). If we have reached the end of input, -1 is put on the stack. So we start by checking for that condition, and if it is -1, we terminate: :1+!#@_. This works as follows:

So, if have reached the end of the input, we have -1 on top of the stack. Adding 1 leaves 0 on top of the stack, which due to the ! becomes a 1. We first skip over the @, but then the _ sends us back to the @, terminating the program. If, on the other hand, we have read a number, we continue with the rest of the program, leaving the read number on top of the stack.

So, we now have two numbers on the stack: the sum of the numbers, up to the previous number read, and the new number read. We first add the two numbers (+), then duplicate the result (:).

We now have to increment the amount of numbers read: first we fetch the current amount and put it on the stack (88g), then we add 1 to it (1+). We then write the new amount back, leaving a copy on the stack (:88p).

At this moment, we have three values on the stack: the amount of numbers on top of the stack, then twice the sum of the numbers. We replace the top two numbers on the stack by their quotient (/), and print this value (.). We then have to print a newline; a newline has ASCII value 10, so we have two 5s on the stack, add them (+), and print the top of the stack (which is now 10) as an ASCII character (,).

Find the full program on GitHub.

C

The C program is pretty straight forward. Simple enough we don't even need malloc:

int main (void) {
    int n;
    int s = 0;
    int c = 0;

    while (scanf ("%d", &n) == 1) {
        printf ("%d\n", (s += n) / ++ c);
    }

    return (0);
}

Find the full program on GitHub.

Go

The Go program is similar to the C program. A bit more verbose because we cannot use += or prefix ++ as part of an expression.

func main () {
    var n, s, c int;
    s = 0
    c = 0
    for {
        var _, err = fmt . Scanf ("%d", &n)
        if (err != nil) {
            break
        }
        s += n
        c ++
        fmt . Printf ("%d\n", s / c)
    }
}

Find the full program on GitHub.

Java

Just like in C and Go, we scan for integers to read the next number:

public class ch1 {
    public static void main (String [] args) {
        Scanner scanner = new Scanner (System . in);
        int s = 0, c = 0;
        while (scanner . hasNext ()) {
            System . out . println ((s += scanner . nextInt ()) / ++ c);
        }
    }
}

Find the full program on GitHub.

Lua

In Lua, we have explicitly convert strings to numbers:

for n in io . lines () do
    s = s + tonumber (n)
    c = c + 1
    print (s / c)
end

Find the full program on GitHub.

Node.js

Conversion from strings to numbers in Node.js is done with unary +:

  require ('readline')
. createInterface ({input: process . stdin})   
. on              ('line', n => {console . log ((s +=+ n) / ++ c)})

Find the full program on GitHub.

Pascal

Nothing special here:

begin
    while not eof () do begin
        readln (n);
        s := s + n;
        c := c + 1;
        writeln (s div c);
    end
end.

Find the full program on GitHub.

Python

for n in fileinput . input ():
    s = s + int (n)
    c = c + 1
    print (s // c)

Find the full program on GitHub.

R

In R, assignment is done using the <- operator:

repeat {
    n <- readLines (stdin, n = 1)
    if (length (n) == 0) {
        break
    }
    cat ((s <- s + as.integer (n)) / (c <- c + 1), "\n")
}

Find the full program on GitHub.

Ruby

ARGF . each_line do
    |n|
    s += n . to_i
    c += 1
    puts (s / c)
end

Find the full program on GitHub.

Scheme

Scheme doesn't have loops, but it has recursion. And its operators are all prefix operators.

(define (main)
    (define n (read))
    (if (not (eof-object? n))
        (begin
            (set! s (+ s n))
            (set! c (+ c 1))
            (format #t "~d\n" (/ s c))
            (main)
        )
    )
)

(main)

Find the full program on GitHub.

Tcl

while {[gets stdin n] >= 0} {
    set s [expr $s + $n]
    set c [expr $c +  1]
    puts  [expr $s / $c]
}

Find the full program on GitHub.


Please leave any comments as a GitHub issue.