/ general utilities \d .u / n number of tries, d delay in milliseconds, f function, a arguments retry:{[n;d;f;a] i:1;while[1;if[~*r:.[f;a;:];:r];:[n/+\'y=\:" ",x} eq:{uq[y]&(&/y lr/:("{}";"[]"))&x=y} cut:{1_'(&eq[x;d])_ d:x,y} uq:{~b|~=\~b:esc["\"";x]} uc:(_ci@[!256;97+!26;-;32])@_ic$: lc:(_ci@[!256;65+!26;+;32])@_ic$: / word wrap wrap:{(b -1_(-1+b _binl x+b:0,1+&" "=y)\0)_ y,:" "} / signum sign:{(-x<0)+0 string ftime:{[t] if[~t;:""] if[0N=t;:""] x::[T:2=4:t;86400;1]*t;x:_ltime[_ x],rnd[3;x-_ x] r:-1_,/(2 2 2$'1!100 100 100_vs*x),'"/" r:@[r;&r=" ";:;"0"] r," ",(-1_,/(-2#'"0",/:($(3#100)_vs x 1)),\:":"),:[T;".",3#2_($x 2),"000";""]} / rounding rnd:{b:10^x;(%b)*_.5+b*y} / floating point vs (vs[scalar;vector]) vs:{(i;_ y-x*i:_ y%x)} / hour minute second hms:{@[t;&" "=t:1_,/":",'2${:[*x;x;1_ x]}0 24 60 60_vs x;:;"0"]} / time formatting time:{[p;f;i;t]:[-1=4:t;tfmt[p;f;i;t];mat t]} mat:{(- 1||/#:'x)$x$:} tfmt:{[p;f;i;t]if[_n~i;i:0];:[1=p;4$f+t-1;(4$*a),'("HTQMP"2 3 4 12?p),'(- 1+p>9)$*-1#a:(f,1)+(0,p)_vs -1+i+t,()]} tval:{[p;f;i;g;h;s;a]t:times[g;h;s];t tfmt[p;f;i;t]?/:a} times:{[g;h;s]{(x?g)_ x}(!1+h+s)-h} / format local/gmt ltime:{t_ _ltime x} gtime:{t_ _gtime x} t_:{1_,/" .. ::",'4 2 2 2 2 2{(-x)#"0000",y}'$,/0 100 100 _vs/:x} / execute function trapped exec:{[f;a]f . a} / failure signalling fail:{fatal""} fatal:{.m.E["Fatal Error!";x]} / dyadic operator extended to dictionaries dop:{ l:5=4:y;r:5=4:z if[~l|r;:x[y;z]];if[l&~r;:@[y;_n;_f[x;;z]]];if[r&~l;:@[z;_n;_f[x;y]]] a:!y;b:!z;i:a@&a _lin b;j:a _dvl i;k:b _dvl i;n:0 0 1 1(+;-;*;%)?x @[@[@[y;i;:;_f[x]'[y i;z i]];j;_f[x;;n]];k;:;_f[x;n]'z k]} / apply function recursively in structure t into:{[t;s]t:@[t;c;:;s c:(b:!s)_dvl!t];:[#d:b _dvl c;@[t;d;_f;s d;t];t]} / dyadic transpose transpose:{[p;m]s[p]#(,//m)i: _ ud:{_ssr[$x;".";"_"]} du:{_ssr[$x;"_";"."]} / cross:(,/,/:\:)/(),/: / cross:{:[~c:#x:(),/:(),x;x;1=c;+x;+x@'n _vs!*/n:#:'x]} cross:{((::;+:;(,/,/:\:)/)0 1?#x)x:(),/:(),x} / cut/compose on tabs detab:{1_,//{"\n",y,'(x-#:'y)#\:" "}[x]'cut["\t"]'cut["\n";y]} entab:{-1_,/{(-1_,/({(x-*:'&:'~" "='|:'a)#'a:((_1%x%#y),x)#y}[x;y]),'"\t"),"\n"}[x]'cut["\n";y]} / null paths npath:{[d;p]:[_n~e:d . p;();p,/:paths[e;()]]} / crosstabulate paths xpath:{[d;p] if[(#p)=i:(p?`)&(@:'p)?0;:npath[d;p]] if[@p i;p[i]:!d . i#p;if[~#p i;:()]] q:cross(i+1)#p :[~#p:(i+1)_ p;,/npath[d]'q;,/d _f/:q,\:p]}