Browse the notebook

Category: binary

Haskell Inspired zipWith() Function

initOperators();

trace(zipWith("-", [1,2,3], [1,2,3]));
trace(zipWith("+", [1,2,3], [1,2,3]));
trace(zipWith("*", [1,2,3], [1,2,3]));
trace(zipWith("+", [1,1,1,3], [4,5,6,7]));
trace(zipWith("<<", [2, 4], [1,1]));
/*
outputs:

0,0,0
2,4,6
1,4,9
5,6,7,10
4,8
*/

function zipWith(op:String, a:Array, b:Array):Array{
    var aLeng:int = a.length;
    var bLeng:int = b.length;
    var leng:Number = (aLeng < bLeng) ? aLeng : bLeng;
    var zipped:Array = [];
   
    if (!this[op])return [];
   
    for (var i:int = 0; i<leng; i++){
        zipped[i]=this[op](a[i], b[i]);
    }
    return zipped;
}

function initOperators():void{
    this["+"]=function(a:Number, b:Number):Number{ return a + b };
    this["-"]=function(a:Number, b:Number):Number{ return a - b };
    this["/"]=function(a:Number, b:Number):Number{ return a / b };
    this["*"]=function(a:Number, b:Number):Number{ return a * b };
    this["%"]=function(a:Number, b:Number):Number{ return a % b };
   
    this["&"]=function(a:Number, b:Number):Number{ return a & b };
    this["<<"]=function(a:Number, b:Number):Number{ return a << b };
    this["|"]=function(a:Number, b:Number):Number{ return a | b };
    this[">>"]=function(a:Number, b:Number):Number{ return a >> b };
    this[">>>"]=function(a:Number, b:Number):Number{ return a >>> b };
    this["^"]=function(a:Number, b:Number):Number{ return a ^ b };
}

This snippet is basically like the haskell zipWith() function. It can combines two arrays into one array given a single function. In this case I defined a bunch of operator functions, but it would work with any kind of function that takes two arguments and returns a value. You could extend this to work with strings and do other strange things I guess.

If you have yet to go play with haskell … go do it now.

Read snippet: Haskell Inspired zipWith() Function

Bitwise OR | and Variable Function Arguments (bitwise flags)

const A:uint = 1;
const B:uint = 2;
const C:uint = 4;
const D:uint = 8;
const E:uint = 16;

function orArgs(args:uint):void{
	if (args & A){
		trace("A");
	}
	if (args & B){
		trace("B");
	}
	if (args & C){
		trace("C");
	}
	if (args & D){
		trace("D");
	}
	if (args & E){
		trace("E");
	}
}

// test out the function: 
orArgs(A | B);
trace("--");
orArgs(A | C | E);
trace("--");
orArgs(B | E | D);
trace("--");
orArgs(C | A);

/* outputs: 
A
B
--
A
C
E
--
B
D
E
--
A
C
*/

If you’ve every used Array.sort(Array.NUMERIC | Array.DESCENDING) you should have at least a vague idea about what this snippet is doing. It shows how you can pass a variable number of arguments to a function using | (bitwise OR) and & (bitwise AND). I believe the correct term for these kind of arguments is “bitwise flags”. This snippet works by having a series of constant values… in this case A – E. Each constant is assigned an unsigned integer… now you may not see the significance of the values 1, 2, 4, 8 and 16 until you see them in binary… get ready this is a pretty cryptic description…

A = 00001 = 1
B = 00010 = 2
C = 00100 = 4
D = 01000 = 8
E = 10000 = 16

If we OR all these together we get: 11111… If we do:

A | E
00001 | 10000

we end up with 10001…

…we can then check which values are stored in the resulting unsigned integer by using AND:

check for A… 10001 & 00001 = 00001 = true
check for E… 10001 & 10000 = 10000 = true
check for C… 10001 & 00100 = 00000 = false

That’s it… I just guessed at the way this was being done… if you have another way to do the same thing, feel free to post it in the comments….

Read snippet: Bitwise OR | and Variable Function Arguments (bitwise flags)