c2a4061997-02-06Fredrik Hübinette (Hubbe) #define error(X) throw( ({ (X), backtrace()[0..sizeof(backtrace())-2] }) )
088e2e1998-02-12Mirar (Pontus Hagland) constant diff = __builtin.diff; constant diff_longest_sequence = __builtin.diff_longest_sequence; constant diff_compare_table = __builtin.diff_compare_table;
5bb99c1998-02-12Henrik Grubbström (Grubba) constant longest_ordered_sequence = __builtin.longest_ordered_sequence;
088e2e1998-02-12Mirar (Pontus Hagland)  constant sort = __builtin.sort;
c2a4061997-02-06Fredrik Hübinette (Hubbe) mixed map(mixed arr, mixed fun, mixed ... args) { int e; mixed *ret;
58a0f61997-08-03Fredrik Hübinette (Hubbe)  if(mappingp(arr))
c2a4061997-02-06Fredrik Hübinette (Hubbe)  return mkmapping(indices(arr),map(values(arr),fun,@args));
58a0f61997-08-03Fredrik Hübinette (Hubbe)  switch(sprintf("%t",fun)) {
f4e2391997-08-03Fredrik Hübinette (Hubbe)  case "int":
c2a4061997-02-06Fredrik Hübinette (Hubbe)  return arr(@args);
f4e2391997-08-03Fredrik Hübinette (Hubbe)  case "string":
c2a4061997-02-06Fredrik Hübinette (Hubbe)  return column(arr, fun)(@args);
f4e2391997-08-03Fredrik Hübinette (Hubbe)  case "function": case "program": case "object":
c2a4061997-02-06Fredrik Hübinette (Hubbe)  ret=allocate(sizeof(arr)); for(e=0;e<sizeof(arr);e++) ret[e]=fun(arr[e],@args); return ret;
f4e2391997-08-03Fredrik Hübinette (Hubbe)  default: error("Bad argument 2 to map_array().\n"); }
c2a4061997-02-06Fredrik Hübinette (Hubbe) } mixed filter(mixed arr, mixed fun, mixed ... args) { int e; mixed *ret; if(mappingp(arr)) { mixed *i, *v, r; i=indices(arr); ret=map(v=values(arr),fun,@args); r=([]); for(e=0;e<sizeof(ret);e++) if(ret[e]) r[i[e]]=v[e];
8ed3541998-02-04Marcus Comstedt  return r;
c2a4061997-02-06Fredrik Hübinette (Hubbe)  }else{ int d; ret=map(arr,fun,@args); for(e=0;e<sizeof(arr);e++) if(ret[e]) ret[d++]=arr[e]; return ret[..d-1]; } } int search_array(mixed *arr, mixed fun, mixed ... args) { int e; if(stringp(fun)) { for(e=0;e<sizeof(arr);e++) if(arr[e][fun](@args)) return e; return -1; } else if(functionp(fun)) { for(e=0;e<sizeof(arr);e++) if(fun(arr[e],@args)) return e; return -1; } else if(intp(fun)) { for(e=0;e<sizeof(arr);e++) if(arr[e](@args)) return e; return -1; } else { error("Bad argument 2 to filter().\n"); } } mixed *sum_arrays(function foo, mixed * ... args) { mixed *ret; int e,d; ret=allocate(sizeof(args[0])); for(e=0;e<sizeof(args[0]);e++) ret[e]=foo(@ column(args, e)); return ret; }
8d49101998-01-21Fredrik Hübinette (Hubbe) mixed *sort_array(array foo,function|void cmp, mixed ... args)
c2a4061997-02-06Fredrik Hübinette (Hubbe) { array bar,tmp; int len,start; int length; int foop, fooend, barp, barend; if(!cmp || cmp==`>) { foo+=({}); sort(foo); return foo; } if(cmp == `<) { foo+=({}); sort(foo); return reverse(foo); } length=sizeof(foo); foo+=({}); bar=allocate(length); for(len=1;len<length;len*=2) { start=0; while(start+len < length) { foop=start; barp=start+len; fooend=barp; barend=barp+len; if(barend > length) barend=length; while(1) { if(cmp(foo[foop],foo[barp],@args) <= 0) { bar[start++]=foo[foop++]; if(foop == fooend) { while(barp < barend) bar[start++]=foo[barp++]; break; } }else{ bar[start++]=foo[barp++]; if(barp == barend) { while(foop < fooend) bar[start++]=foo[foop++]; break; } } } } while(start < length) bar[start]=foo[start++]; tmp=foo; foo=bar; bar=tmp; } return foo; } array uniq(array a) { return indices(mkmapping(a,a)); }
0dcb7f1998-01-31Fredrik Hübinette (Hubbe) array columns(array x, array ind) { array ret=allocate(sizeof(ind)); for(int e=0;e<sizeof(ind);e++) ret[e]=column(x,ind[e]); return ret; }
905bb11998-01-31Fredrik Hübinette (Hubbe)  array transpose(array x) { array ret=allocate(sizeof(x[0])); for(int e=0;e<sizeof(x[0]);e++) ret[e]=column(x,e); return ret;
088e2e1998-02-12Mirar (Pontus Hagland) }
b98e4a1998-02-15Mirar (Pontus Hagland)  // diff3, complement to diff (alpha stage) array(array(array(mixed))) diff3(array mid,array left,array right) { array lmid,ldst; array rmid,rdst; [lmid,ldst]=diff(mid,left); [rmid,rdst]=diff(mid,right); array res=({}); int pos; int lpos=0,rpos=0; int l=0,r=0; array eq=({}); for (l=0; l<sizeof(lmid); l++) { lpos=-1; // find next equal l--m while (l<sizeof(lmid) && lmid[l]!=ldst[l]) { res+=({({lmid[l],ldst[l],({})})}); // skip these for (lpos=0; r<sizeof(rmid) && lpos<sizeof(lmid[l]); lpos++) { mixed x=lmid[l][lpos]; for(;;) { if (rpos>=sizeof(rmid[r])) { if (rpos<sizeof(rdst[r])) res+=({({({}),({}),rdst[r][rpos..]})}); rpos=0; r++; if (r==sizeof(rmid)) break; } else if (rmid[r][rpos]==x) { if (rpos<sizeof(rdst[r])) res+=({({({}),({}),({rdst[r][rpos]})})}); rpos++; break; } else { if (rpos<sizeof(rdst[r])) res+=({({({}),({}),({rdst[r][rpos]})})}); rpos++; } } } l++; } if (l==sizeof(lmid)) break; // loop over this, find this in r for (lpos=0; r<sizeof(rmid) && lpos<sizeof(lmid[l]); lpos++) { mixed x=lmid[l][lpos]; for(;;) { if (rpos>=sizeof(rmid[r])) { if (rpos<sizeof(rdst[r])) res+=({({({}),({}),rdst[r][rpos..]})}); rpos=0; r++; if (r==sizeof(rmid)) break; } else if (rmid[r][rpos]==x) { if (rmid[r]!=rdst[r]) // unequal if (r<sizeof(rdst[r])) res+=({({({x}),({x}),({rdst[r][rpos]})})}); else res+=({({({x}),({x}),({})})}); else // equal! { array ax=({x}); res+=({({ax,ax,ax})}); } rpos++; break; } else { if (rpos<sizeof(rdst[r])) res+=({({({}),({}),({rdst[r][rpos]})})}); rpos++; } } } } // flush what's left if (r<sizeof(rmid)) { if (rmid[r]!=rdst[r]) { if (rpos<sizeof(rmid[r])) res+=({({rmid[r][rpos..],({}),({})})}); if (rpos<sizeof(rdst[r])) res+=({({({}),({}),rdst[r][rpos..]})}); } else res+=({({rmid[r][rpos..],({}),rdst[r][rpos..]})}); r++; } if (l<sizeof(lmid) && lpos!=-1) { if (lpos<sizeof(lmid[l])) res+=({({lmid[l][lpos..],({}),({})})}); if (lpos<sizeof(ldst[l])) res+=({({({}),({}),ldst[l][lpos..]})}); } res+=transpose( ({ldst[l..],lmid[l..], map(allocate(sizeof(lmid)-l), lambda(int x) { return ({}); })}) ); res+=transpose( ({rmid[r..], map(allocate(sizeof(rmid)-r), lambda(int x) { return ({}); }), rdst[r..]}) ); array res2=({}); for (l=0; l<sizeof(res); ) { int ol; for (ol=l; l<sizeof(res) && res[l][0]==res[l][1] && res[l][1]==res[l][2]; l++); if (ol!=l) // got some equal res2+=({sum_arrays(`+,@res[ol..l-1])}); for (ol=l; l<sizeof(res) && !(res[l][0]==res[l][1] && res[l][1]==res[l][2]); l++); if (ol!=l) // got some unequal res2+=({sum_arrays(`+,@res[ol..l-1])}); } return transpose(res2); }