Vsub()
Description
FUNCTION: vsub(vector0, vector1[, delimiter, [output delimiter]])
Vector0 and vector1 are lists of numbers, also known as vectors. If the list only contains one element, it is treated as a scalar (just a plain number).
An overview of the behavior you can expect:
Vector0 Vector1 Scalar Scalar - Acts like sub() Scalar Vector - Each entry of the vector is replaced with the scalar minus that entry. Vector Scalar - Each entry of the vector is subtracted by the scalar. Vector Vector - Each entry of Vector1 is subtracted from the corresponding entry of Vector0
PennMUSH 1.8.1p3 and older versions of MUX do not support mixed scalar/vector cases. That is, vector0 and vector1 must have the same number of elements.
Related Topics: vadd() vmul() vdot() vcross() vmag() vunit() vdim()
Examples
> th vsub(3.2,2.1) 1.1 > th vsub(10,1 2 3) 9 8 7 > th vsub(1 2 3,10) -9 -8 -7 > th vsub(6 5 4,1 2 3) 5 3 1
Nifty tricks
At first vsub() may appear as only useful in strictly computational cases, but it can be used in unexpected ways.
Nifty trick #1
Consider if you wanted to compare a list of numbers (perhaps someone's stats) to a another list (perhaps a base line) and only display those stats which are over a certain amount.
For example:
Str Dex Int Sta 10 30 20 30 compared to Str Dex Int Sta 10 40 15 20
I can use this code to tell me which stats exceed these limits:
> th elements(Str Dex Int Sta,matchall(vsub(10 40 15 20,10 30 20 30),-*)) Int Sta
Or more generally:
elements(stat names,matchall(vsub(limits list,stats list),-*))
Amazingly enough, you can have as many items in the lists as you want (in recent MUX versions), but only three function invocations will ever occur.
Nifty trick #2
Another problem that occurs is picking the longest word out of a list. There is no good way to do this, however you can again fix the number of function invocations required by using vsub(). The first step in finding the longest word in a list is knowing how long each word is. The typical solution would be to visit each word and use strlen(). However, observe that if we know where each delimiter character is (usually a space), then we can take the difference between the next delimiter position and this one to find how long the word inbetween is. This is best demonstrated with an example:
the orange slayed the rake ^ ^ ^ ^ 3 10 17 21 \___/ \____/ \/ 7 7 4
However, this over-counts by one, and we need to know where the beginning and ending places are. Shooting two birds with one stone, we end up with this snippet of softcode:
vsub(lpos(%0%b,%b),lpos(%b%0,%b))
Again, a fixed number of function invocations, despite how large the list may be.
--Ian