a580e1 2000-09-27 Fredrik HÃ¼binette (Hubbe) #pike __REAL_VERSION__ a20af6 2000-09-26 Fredrik HÃ¼binette (Hubbe) c2a406 1997-02-06 Fredrik HÃ¼binette (Hubbe) #define error(X) throw( ({ (X), backtrace()[0..sizeof(backtrace())-2] }) ) 088e2e 1998-02-12 Mirar (Pontus Hagland) constant diff = __builtin.diff; constant diff_longest_sequence = __builtin.diff_longest_sequence; constant diff_compare_table = __builtin.diff_compare_table; 5bb99c 1998-02-12 Henrik GrubbstrÃ¶m (Grubba) constant longest_ordered_sequence = __builtin.longest_ordered_sequence; a7759e 1998-11-17 Henrik GrubbstrÃ¶m (Grubba) constant interleave_array = __builtin.interleave_array; 088e2e 1998-02-12 Mirar (Pontus Hagland) constant sort = __builtin.sort; f7aff6 1998-04-14 Henrik Wallin constant everynth = __builtin.everynth; constant splice = __builtin.splice; constant transpose = __builtin.transpose; 652d92 2000-04-19 David Hedbor constant uniq = __builtin.uniq_array; 55683e 2000-08-28 Per Hedbor 5a3697 1999-07-27 Mirar (Pontus Hagland) constant filter=predef::filter; constant map=predef::map; 55683e 2000-08-28 Per Hedbor constant permute = __builtin.permute; c2a406 1997-02-06 Fredrik HÃ¼binette (Hubbe) 5d6608 2000-12-13 Henrik GrubbstrÃ¶m (Grubba) //! @[reduce()] sends the first two elements in @[arr] to @[fun], //! then the result and the next element in @[arr] to @[fun] and //! so on. Then it returns the result. The function will return //! @[zero] if @[arr] is the empty array. If @[arr] has //! only one element, that element will be returned. //! //! @seealso //! @[Array.rreduce()] //! be192f 1999-07-26 Marcus Comstedt mixed reduce(function fun, array arr, mixed|void zero) 662511 1999-07-25 Marcus Comstedt { if(sizeof(arr)) zero = arr[0]; for(int i=1; i=0; --i) 0662a9 2000-07-12 Henrik GrubbstrÃ¶m (Grubba) zero = ([function(mixed,mixed:mixed)]fun)(arr[i], zero); 662511 1999-07-25 Marcus Comstedt return zero; } 5d6608 2000-12-13 Henrik GrubbstrÃ¶m (Grubba) //! @[shuffle()] gives back the same elements, but in random order. //! //! @seealso //! @[Array.permute()] //! b77d8d 1998-02-28 Henrik GrubbstrÃ¶m (Grubba) array shuffle(array arr) { int i = sizeof(arr); while(i) { int j = random(i--); if (j != i) { mixed tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } } return(arr); } 5d6608 2000-12-13 Henrik GrubbstrÃ¶m (Grubba) //! @[search_array()] works like @[map()], only it returns the index //! of the first call that returnes true instead. //! //! If no call returns true, -1 is returned. //! //! @seealso //! @[Array.sum_arrays()], @[map()] //! 4755b7 2000-02-18 Henrik GrubbstrÃ¶m (Grubba) int search_array(array arr, mixed fun, mixed ... args) c2a406 1997-02-06 Fredrik HÃ¼binette (Hubbe) { int e; if(stringp(fun)) { for(e=0;e()] is used instead. //! //! @seealso //! @[map()], @[sort()], @[`>()] //! array sort_array(array foo, function|void cmp, mixed ... args) c2a406 1997-02-06 Fredrik 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) barend=length; while(1) { 0662a9 2000-07-12 Henrik GrubbstrÃ¶m (Grubba) if(([function(mixed,mixed,mixed...:int)]cmp)(foo[foop],foo[barp],@args) <= 0) c2a406 1997-02-06 Fredrik HÃ¼binette (Hubbe) { 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; } 0dcb7f 1998-01-31 Fredrik HÃ¼binette (Hubbe) array columns(array x, array ind) { array ret=allocate(sizeof(ind)); for(int e=0;e)[side]) { // Got cyclically interlocking equivalences. Have to break one // of them. Prefer the shortest. int which, merge, inv_side = side ^ 3, i, oi; array(int) eq, oeq; array arr, oarr; int atest = side == 1 ? ceq[ci] != 3 : beq[bi] != 3; int btest = side == 1 ? aeq[ai] != 3 : ceq[ci] != 3; int ctest = side == 1 ? beq[bi] != 3 : aeq[ai] != 3; for (i = 0;; i++) { int abreak = atest && aeq[ai] != aeq[ai + i]; int bbreak = btest && beq[bi] != beq[bi + i]; int cbreak = ctest && ceq[ci] != ceq[ci + i]; if (abreak + bbreak + cbreak > 1) { // More than one shortest sequence. Avoid breaking one that // could give an all-three match later. if (side == 1) { if (!atest) cbreak = 0; if (!btest) abreak = 0; if (!ctest) bbreak = 0; } else { if (!atest) bbreak = 0; if (!btest) cbreak = 0; if (!ctest) abreak = 0; } // Prefer breaking one that can be joined with the previous // diff part. switch (prevodd) { case 0: if (abreak) bbreak = cbreak = 0; break; case 1: if (bbreak) cbreak = abreak = 0; break; case 2: if (cbreak) abreak = bbreak = 0; break; } } if (abreak) { which = 0, merge = (<0, -1>)[prevodd]; i = ai, eq = aeq, arr = a; if (inv_side == 1) oi = bi, oeq = beq, oarr = b; else oi = ci, oeq = ceq, oarr = c; break; } if (bbreak) { which = 1, merge = (<1, -1>)[prevodd]; i = bi, eq = beq, arr = b; if (inv_side == 1) oi = ci, oeq = ceq, oarr = c; else oi = ai, oeq = aeq, oarr = a; break; } if (cbreak) { which = 2, merge = (<2, -1>)[prevodd]; i = ci, eq = ceq, arr = c; if (inv_side == 1) oi = ai, oeq = aeq, oarr = a; else oi = bi, oeq = beq, oarr = b; break; } } //werror (" which=%d merge=%d inv_side=%d i=%d oi=%d\n", // which, merge, inv_side, i, oi); int s = i, mask = eq[i]; do { eq[i++] &= inv_side; while (!(oeq[oi] & inv_side)) oi++; oeq[oi] &= side; } while (eq[i] == mask); if (merge && !eq[s]) { array part = ({}); do part += ({arr[s++]}); while (!eq[s]); switch (which) { case 0: ai = s; ares[-1] += part; break; case 1: bi = s; bres[-1] += part; break; case 2: ci = s; cres[-1] += part; break; } } } //werror ("aeq[%d]=%d beq[%d]=%d ceq[%d]=%d prevodd=%d\n", // ai, aeq[ai], bi, beq[bi], ci, ceq[ci], prevodd); 04a1a8 1998-11-30 Martin Stjernholm f5c8ba 1998-12-02 Martin Stjernholm if (aeq[ai] == 2 && beq[bi] == 1) { // a and b are equal. do apart += ({a[ai++]}), bi++; while (aeq[ai] == 2 && beq[bi] == 1); bpart = apart; while (!ceq[ci]) cpart += ({c[ci++]}); prevodd = 2; } else if (beq[bi] == 2 && ceq[ci] == 1) { // b and c are equal. do bpart += ({b[bi++]}), ci++; while (beq[bi] == 2 && ceq[ci] == 1); cpart = bpart; while (!aeq[ai]) apart += ({a[ai++]}); prevodd = 0; } else if (ceq[ci] == 2 && aeq[ai] == 1) { // c and a are equal. do cpart += ({c[ci++]}), ai++; while (ceq[ci] == 2 && aeq[ai] == 1); apart = cpart; while (!beq[bi]) bpart += ({b[bi++]}); prevodd = 1; 04a1a8 1998-11-30 Martin Stjernholm } 54e28f 1999-05-31 Martin Stjernholm else if ((<1*2*3, 3*3*3>)[aeq[ai] * beq[bi] * ceq[ci]]) { // All are equal. // Got to match both when all three are 3 and when they are 1, 2 // and 3 in that order modulo rotation (might get such sequences // after breaking the cyclic equivalences above). do apart += ({a[ai++]}), bi++, ci++; while ((<0333, 0123, 0312, 0231>)[aeq[ai] << 6 | beq[bi] << 3 | ceq[ci]]); f5c8ba 1998-12-02 Martin Stjernholm cpart = bpart = apart; prevodd = -1; } 54e28f 1999-05-31 Martin Stjernholm f5c8ba 1998-12-02 Martin Stjernholm else { // Haven't got any equivalences in this block. Avoid adjacent // complementary blocks (e.g. ({({"foo"}),({}),({})}) next to // ({({}),({"bar"}),({"bar"})})). Besides that, leave the // odd-one-out sequence empty in a block where two are equal. 54e28f 1999-05-31 Martin Stjernholm switch (prevodd) { case 0: apart = ares[-1], ares[-1] = ({}); break; case 1: bpart = bres[-1], bres[-1] = ({}); break; case 2: cpart = cres[-1], cres[-1] = ({}); break; f5c8ba 1998-12-02 Martin Stjernholm } 54e28f 1999-05-31 Martin Stjernholm prevodd = -1; while (!aeq[ai]) apart += ({a[ai++]}); while (!beq[bi]) bpart += ({b[bi++]}); while (!ceq[ci]) cpart += ({c[ci++]}); f5c8ba 1998-12-02 Martin Stjernholm } 34e2b3 1998-12-01 Martin Stjernholm 54e28f 1999-05-31 Martin Stjernholm //werror ("%O\n", ({apart, bpart, cpart})); f5c8ba 1998-12-02 Martin Stjernholm ares += ({apart}), bres += ({bpart}), cres += ({cpart}); 04a1a8 1998-11-30 Martin Stjernholm } return ({ares, bres, cres}); } b98e4a 1998-02-15 Mirar (Pontus Hagland) // diff3, complement to diff (alpha stage) 4755b7 2000-02-18 Henrik GrubbstrÃ¶m (Grubba) array(array(array)) diff3_old(array mid,array left,array right) b98e4a 1998-02-15 Mirar (Pontus Hagland) { 4755b7 2000-02-18 Henrik GrubbstrÃ¶m (Grubba) array(array) lmid,ldst; array(array) rmid,rdst; b98e4a 1998-02-15 Mirar (Pontus Hagland) d77442 1998-02-16 Mirar (Pontus Hagland) [lmid,ldst]=diff(mid,left); [rmid,rdst]=diff(mid,right); b98e4a 1998-02-15 Mirar (Pontus Hagland) 04a1a8 1998-11-30 Martin Stjernholm int l=0,r=0,n; 4755b7 2000-02-18 Henrik GrubbstrÃ¶m (Grubba) array(array(array)) res=({}); b98e4a 1998-02-15 Mirar (Pontus Hagland) int lpos=0,rpos=0; array eq=({}); 189dab 1998-02-16 Mirar (Pontus Hagland) int x; b98e4a 1998-02-15 Mirar (Pontus Hagland) 723b28 1998-02-19 Mirar (Pontus Hagland) for (n=0; ;) b98e4a 1998-02-15 Mirar (Pontus Hagland) { 723b28 1998-02-19 Mirar (Pontus Hagland) while (l=sizeof(lmid[l])) b98e4a 1998-02-15 Mirar (Pontus Hagland) { 189dab 1998-02-16 Mirar (Pontus Hagland) if (sizeof(ldst[l])>lpos) res+=({({({}),ldst[l][lpos..],({})})}); b98e4a 1998-02-15 Mirar (Pontus Hagland) l++; 189dab 1998-02-16 Mirar (Pontus Hagland) lpos=0; b98e4a 1998-02-15 Mirar (Pontus Hagland) } 723b28 1998-02-19 Mirar (Pontus Hagland) while (r=sizeof(rmid[r])) b98e4a 1998-02-15 Mirar (Pontus Hagland) { 189dab 1998-02-16 Mirar (Pontus Hagland) if (sizeof(rdst[r])>rpos) res+=({({({}),({}),rdst[r][rpos..]})}); r++; rpos=0; b98e4a 1998-02-15 Mirar (Pontus Hagland) } 723b28 1998-02-19 Mirar (Pontus Hagland) if (n==sizeof(mid)) break; 189dab 1998-02-16 Mirar (Pontus Hagland) x=min(sizeof(lmid[l])-lpos,sizeof(rmid[r])-rpos); b98e4a 1998-02-15 Mirar (Pontus Hagland) 189dab 1998-02-16 Mirar (Pontus Hagland) if (lmid[l]==ldst[l] && rmid[r]==rdst[r]) b98e4a 1998-02-15 Mirar (Pontus Hagland) { 189dab 1998-02-16 Mirar (Pontus Hagland) eq=lmid[l][lpos..lpos+x-1]; res+=({({eq,eq,eq})}); } else if (lmid[l]==ldst[l]) { eq=lmid[l][lpos..lpos+x-1]; res+=({({eq,eq,rdst[r][rpos..rpos+x-1]})}); } else if (rmid[r]==rdst[r]) { eq=rmid[r][rpos..rpos+x-1]; res+=({({eq,ldst[l][lpos..lpos+x-1],eq})}); } else { res+=({({lmid[l][lpos..lpos+x-1], ldst[l][lpos..lpos+x-1], rdst[r][rpos..rpos+x-1]})}); b98e4a 1998-02-15 Mirar (Pontus Hagland) } 723b28 1998-02-19 Mirar (Pontus Hagland) // werror(sprintf("-> %-5{%O%} %-5{%O%} %-5{%O%}" // " x=%d l=%d:%d r=%d:%d \n",@res[-1],x,l,lpos,r,rpos)); 189dab 1998-02-16 Mirar (Pontus Hagland) rpos+=x; lpos+=x; n+=x; b98e4a 1998-02-15 Mirar (Pontus Hagland) } d77442 1998-02-16 Mirar (Pontus Hagland) return transpose(res); b98e4a 1998-02-15 Mirar (Pontus Hagland) } 78762b 1999-06-01 Mirar (Pontus Hagland) // sort with care of numerical sort: // "abc4def" before "abc30def" 6a18c8 1999-06-01 Mirar (Pontus Hagland) int dwim_sort_func(string a0,string b0) 78762b 1999-06-01 Mirar (Pontus Hagland) { string a2="",b2=""; int a1,b1; sscanf(a0,"%s%d%s",a0,a1,a2); sscanf(b0,"%s%d%s",b0,b1,b2); if (a0>b0) return 1; if (a0b1) return 1; if (a1b) return 1; if (a