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, ...

• Average of first number is 10.
• Average of first 2 numbers (10 + 20) / 2 = 15.
• Average of first 3 numbers (10 + 20 + 30) / 3 = 20.
• Average of first 4 numbers (10 + 20 + 30 + 40) / 4 = 25 and so on.

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:

• n for the current number read from input.
• s the sum of the numbers read so far.
• c the count of the numbers read so far.

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: • :: Duplicate the top of the stack. • 1: Push 1 on the stack. • +: Pop the top two numbers of the stack, and push back the sum of those. • !: Pop a number from the stack. If that number is 0, push 1, else push 0. • #: Skip over the next command. • @: Terminate the program. But initially, we skip over this command. • _: Pop a number from the stack. If the number is 0, continue to the right. Else, continue to the left. 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.