Graal Forums  

Go Back   Graal Forums > Development Forums > NPC Scripting > Code Gallery
FAQ Members List Calendar Today's Posts

Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old 11-23-2010, 03:35 AM
WhiteDragon WhiteDragon is offline
Banned
Join Date: Feb 2007
Posts: 1,002
WhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to behold
Prelude

Here is a pack of useful functions that let you operate on arrays and integers

PHP Code:
//#CLIENTSIDE

function onCreated() {

  
/* MISCELLANEOUS FUNCTIONS */

  // Return whatever is passed in
  
this.id = function (temp.a) {
    return 
temp.a;
  };
  
  
// Return the first parameter and ignore the second.
  
this.const = function (temp.atemp.b) {
    return 
temp.a;
  };

  
// Combine two functions and return a new function which executes them in order.
  // i.e.,    compose(f, g)(x) = f(g(x))
  
this.compose = function (temp.f1temp.f2) {
    
temp.= function (temp.x) {
      
temp.f1 this.(@"freevars_"@temp).f1;
      
temp.f2 this.(@"freevars_"@temp).f2;
      return (@
temp.f1)((@temp.f2)(temp.x));
    };
    
this.(@"freevars_"@temp.f).f1 temp.f1;
    
this.(@"freevars_"@temp.f).f2 temp.f2;
    return 
temp.f;
  };
    
  
//  Flip the parameters of a function.
  //  flip(f)(x, y) = f(y,x)
  
this.flip = function (temp.f1) {
    
temp.= function (temp.atemp.b) {
      
temp.f1 this.(@"freevars_"@temp.f).f1;
      return (@
temp.f1)(temp.btemp.a);
    };
    
this.(@"freevars_"@temp.f).f1 temp.f1;

    return 
temp.f;
  };
  
  
// Until p(x) is true, x = f(x) every recursive step. Return the final x (after all the fs are applied).
  
this.until = function (temp.ptemp.ftemp.x) {
    if ((@
temp.p)(temp.x)) {
      return 
temp.x;
    } else {
      return (@
temp)(temp.ptemp.f, (@temp.f)(temp.p));
    }
  };

  
/* BOOLEAN OPERATIONS */

  // Just negates a boolean. Useful for composing.
  
this.not = function (temp.a) {
    return !
temp.a;
  };


  
/* NUMERIC OPERATIONS */

  // Negates a number.
  
this.negate = function (temp.a) {
    return -
temp.a;
  };

  
// Get the sign of a number.
  
this.signum = function (temp.a) {
    if (
temp.0) {
      return -
1;
    } else if (
temp.== 0) {
      return 
0;
    } else {
      return 
1;
    }
  };

  
// Return the remainder of an integer division.
  
this.rem = function(temp.atemp.n) {
    return 
temp.temp.n*int(temp.a/temp.n);
  };

  
// Subtract two numbers.
  
this.subtract = function (temp.atemp.b) {
    return 
temp.temp.a;
  };

  
// Checks if a number is even
  
this.even = function (temp.a) {
    
temp.temp.a/2;
    return 
int(temp.a) != temp.a;
  };

  
// Checks if a number is odd
  
this.odd this.compose(this.notthis.even);

  
// Returns the greatest positive integer that divides both x and y.
  
this.gcd = function (temp.xtemp.y) {
    
temp.gcd2 = function (temp.atemp.b) {
      if (
temp.== 0) {
        return 
temp.a;
      } else {
        return (@
temp)(temp.bthis.rem(temp.atemp.b));
      }
    };
    if (
temp.== && temp.== 0) {
      
// error
    
} else {
      return (@
temp.gcd2)(abs(temp.x), abs(temp.y));
    }
  };
  
  
// Returns the smallest integer that both x and y divide.
  
this.lcm = function (temp.xtemp.y) {
    if (
temp.== || temp.== 0) {
      return 
0;
    } else {
      return 
abs((temp./ (this.gcd(temp.xtemp.y))) * temp.y);
    }
  };
  

  
  
/* LIST OPERATIONS */

  // Take a function and a list. Return a new list that has that function applied across it.
  
this.map = function (temp.ftemp.a) {
    
temp.temp.a.size();
  
    
temp.= {};
    for (
temp.0temp.temp.stemp.i++) {
      
temp.b.insert(temp.i, (@temp.f)(temp.a[temp.i]));
    }
  
    return 
temp.b;
  };

  
// Take a function and a list. Return a list that only has elements where temp.f was True for them.
  
this.filter = function (temp.ftemp.a) {
    
temp.temp.a.size();

    
temp.= {};  
    for (
temp.0temp.temp.stemp.i++) {
      if ((@
temp.f)(temp.a[temp.i]) == true) {
        
temp.b.add(temp.a[temp.i]);
      }
    }
  
    return 
temp.b;
  };

  
// return the first element in a list.
  
this.head = function (temp.a) {
    return 
temp.a[0];
  };
  
  
// return the last element of the list.
  
this.last = function (temp.a) {
    return 
temp.a[temp.a.size()-1];
  };
  
  
// return everything but the first element in a list.
  
this.tail = function (temp.a) {
    return 
temp.a.subarray(1);
  };
  
  
// return everything but the last element in a list.
  
this.init = function (temp.a) {
    return 
temp.a.subarray(0temp.a.size()-2);
  };
  
  
// takes a list and returns a new list that in reverse.
  
this.reverse = function (temp.a) {
    
temp.aSize temp.a.size();
    
temp.= new [temp.aSize];
    for (
temp.0temp.temp.aSizetemp.i++) {
      
temp.b[temp.i] = temp.a[temp.aSize-1-temp.i];
    }
    return 
temp.b;
  };

  
// Takes a 2-parameter function, a value, and a list of values, and combines the array into a new value based on that function moving from the left to the right. 
  
this.foldl = function (temp.ftemp.inittemp.a) {
    
temp.temp.a.size();

    
temp.result temp.init;
  
    for (
temp.0temp.temp.stemp.i++) {
      
temp.result = (@temp.f)(temp.resulttemp.a[temp.i]);
    }
  
    return 
temp.result;
  };

  
// Same as foldl, but no default value (the list must not be empty in this case). 
  
this.foldl1 = function (temp.ftemp.a) {
    
temp.temp.a.size();

    
temp.result temp.a[0];
  
    for (
temp.1temp.temp.stemp.i++) {
      
temp.result = (@temp.f)(temp.resulttemp.a[temp.i]);
    }

    return 
temp.result;  
  };

  
// Same as foldl but starts from the right of the list and moves left.
  
this.foldr = function (temp.ftemp.inittemp.a) {
    
temp.temp.a.size();

    
temp.result temp.init;
  
    for (
temp.temp.s-1temp.>= 0temp.i--) {
      
temp.result = (@temp.f)(temp.a[temp.i], temp.result);
    }
  
    return 
temp.result;
  };

  
// same as foldr but with no default value (list must be non-empty).
  
this.foldr1 = function (temp.ftemp.a) {
    
temp.temp.a.size();

    
temp.result temp.a[temp.s-1];
  
    for (
temp.temp.s-2temp.>= 0temp.i--) {
      
temp.result = (@temp.f)(temp.a[temp.i], temp.result);
    }

    return 
temp.result;  
  };



  
/* sublists */
  
  // takes the first temp.num values from a list
  
this.takee = function (temp.numtemp.a) {
    return 
temp.a.subarray(0temp.num);
  };
  
  
// drops the first temp.num values from a list
  
this.drop = function (temp.numtemp.a) {
    return 
temp.a.subarray(temp.num);
  };
  
  
// splits a list into two parts at temp.num
  
this.splitAt = function (temp.numtemp.a) {
    return {
temp.a.subarray(0temp.num), temp.a.subarray(temp.num)};
  };
  
  
// keep taking elements from temp.xs until temp.p is false on that element.
  
this.takeWhile = function (temp.ptemp.xs) {
    
temp.xsSize temp.xs.size();
    
temp.= {};
    for (
temp.0temp.temp.xsSizetemp.i++) {
      if ((@
temp.p)(temp.xs[temp.i])) {
        
temp.n.add(temp.xs[temp.i]);
      } else {
        break;
      }
    }
    return 
temp.n;
  };

  
// keep dropping elements from temp.xs while temp.p is true on that element.
  
this.dropWhile = function (temp.ptemp.xs) {
    
temp.xsSize temp.xs.size();
    
temp.= {};
    for (
temp.0temp.temp.xsSizetemp.i++) {
      if (!(@
temp.p)(temp.xs[temp.i])) {
        break;
      }
    }
    for (
temp.temp.itemp.temp.xsSizetemp.x++) {
      
temp.n.add(temp.xs[temp.x]);
    }
    return 
temp.n;
  };

  
// splits an array into two based on the function temp.p. This is basically {takeWhile(p,xs), dropWhile(p,xs)}
  
this.span = function (temp.ptemp.xs) {
    
temp.xsSize temp.xs.size();
    
temp.= {};
    for (
temp.0temp.temp.xsSizetemp.i++) {
      if ((@
temp.p)(temp.xs[temp.i])) {
        
temp.n.add(temp.xs[temp.i]);
      } else {
        break;
      }
    }
    
temp.n2 = {};
    for (
temp.temp.itemp.temp.xsSizetemp.x++) {
      
temp.n2.add(temp.xs[temp.x]);
    }
    return {
temp.ntemp.n2};
  };
  
  
// span, but with a negated temp.p
  
this.break = function (temp.ptemp.xs) {
    return 
this.span(this.compose(this.nottemp.p), temp.xs);
  };

Put this in a class, e.g., prelude, then:
PHP Code:
temp.= new TStaticVar();
temp.p.join("prelude");

temp.= function (temp.x) { return temp.x*2; }
echo(
temp.p.map(temp.f, {1,2,3,4})); // returns {2,4,6,8} 
Inspired by the Haskell Prelude. Also note there is some more documentation/examples at that link for the functions I provided. (Also more functions that I haven't converted to GS yet.)
Reply With Quote
  #2  
Old 11-23-2010, 09:47 PM
DrakilorP2P DrakilorP2P is offline
Registered User
DrakilorP2P's Avatar
Join Date: Apr 2006
Posts: 755
DrakilorP2P is just really niceDrakilorP2P is just really nice
I've been wondering; do you use these abstract scripts in real projects or is it just for curiosity?
Reply With Quote
  #3  
Old 11-23-2010, 09:52 PM
WhiteDragon WhiteDragon is offline
Banned
Join Date: Feb 2007
Posts: 1,002
WhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to behold
Quote:
Originally Posted by DrakilorP2P View Post
I've been wondering; do you use these abstract scripts in real projects or is it just for curiosity?
Depends. If it's a project that only I will be touching then I use this stuff, but otherwise I try to keep it simple for anyone else who might need to work on it. Can't expect everyone to be interested enough to go learn a whole set of functions just to understand a small script.
Reply With Quote
  #4  
Old 12-18-2010, 01:29 AM
adam adam is offline
http://wiki.graal.us/
adam's Avatar
Join Date: Nov 2001
Posts: 2,247
adam has a spectacular aura about
Send a message via AIM to adam
:d
__________________
Rogue Shadow (TCN)(NAT)(Global Development Team)

For development help, contact the patrons of the #graaldt irc channel below, I am usually there.
Click Here to Join IRC Chat Now! -- irc.freenode.net Channel: #graaldt
Quote:
<Dustyshouri> no, RogueShadow is always talking about scripts lol
<Dustyshouri> in fact, he pretty much brought Graal back as a topic single-handedly
Reply With Quote
  #5  
Old 12-18-2010, 02:04 AM
Codein Codein is offline
jwd
Codein's Avatar
Join Date: Oct 2005
Location: Greater Manchester
Posts: 2,423
Codein has a spectacular aura aboutCodein has a spectacular aura about
Send a message via AIM to Codein Send a message via MSN to Codein
It's funny how I come across this post straight after checking out Haskell's website on the front page of HN.

These functions look really fun to play with. Not really seen an equivalent of map, reduce and filter in GScript before.
Reply With Quote
  #6  
Old 12-18-2010, 03:10 AM
12171217 12171217 is offline
Banned
Join Date: Jan 2009
Posts: 453
12171217 has a spectacular aura about
Is it faster to use the modulus operator to check if it's even or odd? That's what I've always done.
Reply With Quote
  #7  
Old 12-18-2010, 07:34 AM
fowlplay4 fowlplay4 is offline
team canada
fowlplay4's Avatar
Join Date: Jul 2004
Location: Canada
Posts: 5,200
fowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond repute
Quote:
Originally Posted by 12171217 View Post
Is it faster to use the modulus operator to check if it's even or odd? That's what I've always done.
PHP Code:
function onCreated() {
  for (
temp.0temp.5temp.i++) {
    
temp.init timevar2;
    
testEven();
    
temp.sum += timevar2 temp.init;
  }
  echo(
temp.sum 5);
}

function 
testEven() {
  for (
temp.0temp.200000temp.i++) {
    
isEven(temp.i);
  }
}

function 
isEven(x) {
  return 
int(2) == (2);
}

function 
isEvenMod(x) {
  return (
2) == 0;

isEvenMod Averaged: 0.281881904
isEven Averaged: 0.300032424

Using modulus is slightly faster (0.01~ seconds in most cases) but I wouldn't consider it something that would become a bottleneck, well in GS2 anyway.
__________________
Quote:

Last edited by fowlplay4; 12-18-2010 at 08:18 PM..
Reply With Quote
  #8  
Old 12-18-2010, 07:04 PM
salesman salesman is offline
Finger lickin' good.
salesman's Avatar
Join Date: Nov 2008
Location: Colorado
Posts: 1,865
salesman has much to be proud ofsalesman has much to be proud ofsalesman has much to be proud ofsalesman has much to be proud ofsalesman has much to be proud ofsalesman has much to be proud ofsalesman has much to be proud of
Quote:
Originally Posted by fowlplay4 View Post
PHP Code:
function isEven(x) { // missing divide operation
  
return int(x) == (2);
}
function 
isEven(x) {
  return 
int(2) == (2);

You're missing an operation in the isEven() function!

The way I usually look at it, checking if its even by int(x / 2) == (x / 2) requires four basic operations (int, 2 divides, and a comparison), at least two references (x twice, maybe a third for the int() function call). Modulus requires two basic operations (mod, and a comparison) and only one variable reference.

But yeah I agree, the difference is so small it probably wouldn't matter in most cases.
__________________
Reply With Quote
  #9  
Old 12-18-2010, 08:19 PM
fowlplay4 fowlplay4 is offline
team canada
fowlplay4's Avatar
Join Date: Jul 2004
Location: Canada
Posts: 5,200
fowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond repute
So I ran it again with the right isEven script and it was pretty much the same result.
__________________
Quote:
Reply With Quote
  #10  
Old 12-18-2010, 10:34 PM
Cloven Cloven is offline
Delteria
Cloven's Avatar
Join Date: Dec 2006
Location: Florida, United States
Posts: 542
Cloven has a spectacular aura about
Send a message via AIM to Cloven
Quote:
Originally Posted by salesman View Post
You're missing an operation in the isEven() function!

The way I usually look at it, checking if its even by int(x / 2) == (x / 2) requires four basic operations (int, 2 divides, and a comparison), at least two references (x twice, maybe a third for the int() function call). Modulus requires two basic operations (mod, and a comparison) and only one variable reference.

But yeah I agree, the difference is so small it probably wouldn't matter in most cases.
As a wise man once told me: "This isn't NASA." It's kind of ironic how often such a stupid sounding saying like that applies.
Reply With Quote
  #11  
Old 01-04-2011, 01:53 AM
Codein Codein is offline
jwd
Codein's Avatar
Join Date: Oct 2005
Location: Greater Manchester
Posts: 2,423
Codein has a spectacular aura aboutCodein has a spectacular aura about
Send a message via AIM to Codein Send a message via MSN to Codein
But wait...

PHP Code:
function isEven(value)
{
  return !(
value 1);

Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 02:38 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Copyright (C) 1998-2019 Toonslab All Rights Reserved.