#!/usr/bin/dc
#
# wam - Copyright (C) Dario Niedermann, 2017 (Released under GPLv3 license)
#
# Weighted Arithmetic Mean for `dc'
# Usage: 0 num1 weight1 num2 weight2 ... ... lwx
#
# $Id: wam.dc 100 2017-05-11 22:14:07Z ndr $
[ # macro w: (init, then call main loop)
0Sw # push 0 to w (sum of weights)
0Sp # push 0 to p (sum of products)
[ # macro a: (main)
d 0 =q # if weight is 0 (the terminator) then call q (i.e.: quit loop)
# else...
d Sw # push copy of weight onto stack w (sum of weights)
* # multiply num * weight
Lp # fetch the running sum of products
+ # add it to the latest product
Sp # store result to the running sum of products
Lw # now... fetch back the latest weight from stack w
Lw # and the running sum of weights
+ Sw # add them together and store them back to stack w
lax # loop! (actually: recurse!)
]Sa
[ # macro q: (work out final result and quit)
Lp # fetch the sum of products
Lw # and the sum of weights
/ # divide them
+ # this just gets rid of the 0 terminator left under TOS
q # quit
]Sq
lax # w: call main loop
# done: now clean up the registers we've altered (except w)
La # pop macro a (i.e.: TOS of a), push it on TOS
X # TOS is a string, so this pops it and returns 0 on TOS
+ # get rid of that 0 adding it to result
LqX+ # do the same for macro q
]Sw
# If you use me non-interactively, put your data anywhere after next line:
# (e.g.: 0 num1 weight1 ... ... numN weightN lwxp)
# Compact me with: sed 's/[ \t]*#.*$//' wam.dc | tr -d '\n \t' | sed 's/$/\n/'
“WAM macro for dc” is Copyright © Dario Niedermann —
Released with no warranty under the terms of the
GPLv3 license. Written and tested on Linux using GNU tools.