Vsub()

From TinyMUX
Revision as of 06:06, 17 January 2006 by Ian (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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