﻿ Replies by Stuart Strickland for InterSystems Developer Community

174 probably from an inaccurate count of the difference between some versions. You still have the r#2:3 problem

W ##Class(CodeGolf.LengthOrder).Type("abc,de","de,abc") should be Unsorted

Size=177, problem fixed and another reduction found at the start of the \$Select

ClassMethod Type(a...) As %String
{
i=\$i(r):1:\$g(a){j=1:1:\$L(a(i),","){L=\$L(\$tr(\$p(a(i),",",j)," ")),r=\$s(L=\$g(c,L):r,r<3*L>c:2,r#2*c>L:3,1:4),c=Lc\$p("Constant1Increasing1Decreasing1Unsorted",1,r)
}

Any of these that use r#2:3 give the wrong answer for

W ##Class(CodeGolf.LengthOrder).Type("abc,de","de,abc")

Shaved down to 174. A dubious \$Find-2 to get first string length. Changed a condition in the \$Select from p<c&(r<3) to r<3*c>p

ClassMethod Type(a...) As %String
{
j=\$i(r):1:a{w=\$tr(a(j)," "),p=\$f(w,",")-2 i=2:1:\$l(w,",") c=\$l(\$p(w,",",i)),r=\$s(p=c:r,r<3*c>p:2,r#2:3,1:4),p=c\$p("Constant7Increasing7Decreasing7Unsorted",7,r)
}
also fits in @Robert Barbiaux attempt

ClassMethod Type(a...) As %String
{
i=\$i(r):1:\$g(a){j=1:1:\$l(a(i),","){l=\$l(\$tr(\$p(a(i),",",j)," ")),c=\$g(c,l),r=\$s(l=c:r,r<3*l>c:2,r#2:3,1:4),c=lc\$p("Constant1Increasing1Decreasing1Unsorted",1,r)
}

The for loop initialising r to 1 is top class thinking. You can still take 2 more characters off:

ClassMethod Type(a...) As %String
{
j=\$i(r):1:a{w=\$tr(a(j)," "),p=\$f(w,",")-2 i=2:1:\$l(w,",") c=\$l(\$p(w,",",i)),r=\$s(p=c:r,p<c&(r<3):2,r#2:3,1:4),p=c\$p("Constant7Increasing7Decreasing7Unsorted",7,r)
}

Yes this time, but unfortunately running tests agains ClassMethod Test1() and then posting ClassMethod Test() on here can make me look silly.

size=193

ClassMethod Type(a...) As %String
{
r=3 i=1:1:a{w=\$tr(a(i)," "),b=\$l(\$p(w,",")) p=2:1:\$l(w,",") c=b,b=\$l(\$p(w,",",p)),d=\$s(c<b:1,c>b:2,1:3),r=\$s(r=3:d,3_r[d:r,1:4)\$p("Increasing1Decreasing1Constant1Unsorted",1,r)
}

I'm afraid not. I didn't read the question properly but thankfully we have you who does a better job than test cases!

Corrected it now.

ClassMethod Type(args...) As %String
{
// no attempt made at miniturizing the code, 362 chars not including comments
res="Constant"
i=1:1 {
q:'\$d(args(i)) w=\$tr(args(i)," ")
p=2:1:\$l(w,",") {
a=\$l(\$p(w,",",p)),b=\$l(\$p(w,",",p-1))
s d=\$s(a>b:1,a<b:-1,1:0)
d>0 res=\$case(res,"Constant":"Increasing","Increasing":"Increasing",:"Unsorted")
d<0 res=\$case(res,"Constant":"Decreasing","Decreasing":"Decreasing",:"Unsorted")
}
}
res
}

You need an interactive user's system to run this without any user interaction?

If it doesn't matter who runs it and it doesn't take any serious resources and could run unnoticed then could you set a global that is checked by some code that is regularly run by a group of users? The first interactive process that finds the global could do your \$ZF for you? Say SET ^GLOBAL("RUN NOTEPAD")=\$H

Otherwise I think you need to fix the destination program so it will run in the background.

Thanks Vitaliy! That is just what I was looking for!

I suppose that underneath the code, deep down in Quote^%qcr, it may be doing the same as I'm doing, but it is unlikely to have any errors in it and it's not a wild assumption that it will do it in the most efficient way.

Alas, the few version 5 sites will have to live with my slower code

%SYS>w \$zv
Cache for UNIX (IBM PowerPC/32-bit) 5.0.18 (Build 6103 + Adhoc 3626) Tue Mar 7 2006 11:55:33 EST
%SYS>W \$zcvt(##CLASS(%Library.Utility).FormatString(\$lb("abc","DEF","",,"tesT",\$lb(0))),"u")

W \$ZCVT(##CLASS(%Library.Utility).FormatString(\$LB("abc","DEF","",,"tesT",\$LB(0)
^
)),"u")
<CLASS DOES NOT EXIST>
%SYS>W \$zcvt(##CLASS(%Utility).FormatString(\$lb("abc","DEF","",,"tesT",\$lb(0))),"u")

W \$ZCVT(##CLASS(%Utility).FormatString(\$LB("abc","DEF","",,"tesT",\$LB(0))),"u")
^
<CLASS DOES NOT EXIST>

Thank you Erin. That's a nice try but \$c(1) isn't guaranteed in a \$LIST

s x=\$lb(0) zzdump x

That's a really good idea. Doesn't quite get there because of nested lists.

Here is a bit more visual info on the problem:

>s x=\$LB("test","for","searching unknown strings here is a very long piece with enough characters to get a lowercase alpha as a \$list marker","items","in","lists",\$lb("/subs","/values","nested list","did you see that ""w"" before the third piece?"))

>f i=1:1:\$l(x) s c=\$e(x,i) w:c?1c "\$c("_\$a(c)_")" w:c'?1c c

\$c(6)\$c(1)test\$c(5)\$c(1)forw\$c(1)searching unknown strings here is a very long piece with enough characters to get a lowercase alpha as a \$list marker\$c(7)\$c(1)items\$c(4)\$c(1)in\$c(7)\$c(1)listsM\$c(1)\$c(7)\$c(1)/subs\$c(9)\$c(1)/values\$c(13)\$c(1)nested list.\$c(1)did you see that "w" before the third piece?

It's those potential lowercase list separators that are forcing me to go the long way round with stepping through each piece. \$ListToString may help speed the code up especially as I'm not really expecting deep nesting of lists.

Thanks Dmitry

I want to find any string in another string that could be a plain string, a \$LIST, or a series of nested \$LIST to any depth - basically an unkown structure. The string I'm searching in can be any size and the pieces can be any size. And I wan't to do a case insensitive search through a large amount of data and I want instant results. And I want to know the character positions of what was found. And I want the results in a human readable format. And just to make it hard, it has to run on everything from Caché version 5 upwards which means \$LISTNEXT, \$LISTVALID are not always available.

That would be fine if I was looking for the full element value as my search string. I'm looking for any occurance, full or part, in a lot of data.

From the documentation:
\$LISTFIND searches the specified list for the first instance of the requested value. A match must be exact and consist of the full element value. Letter comparisons are case-sensitive. Numbers are compared in canonical form. If an exact match is found, \$LISTFIND returns the position of the matching element. If value is not found, \$LISTFIND returns a 0.

// Suppose the string I'm  looking in is in
S X=\$LB("Stuart Strickland","Yaron Munz") // X could be anything
// and I'm looking for "MUNZ"
I \$zcvt(X,"u")["MUNZ" Q 1  // I think this is quick but could cause a problem by converting lower case \$LIST spacers to upper
S sc=0 F i=1:1:\$LL(X) S Y=\$LG(X,i) I \$zcvt(Y,"u")["MUNZ" s sc=1  // I think this is slow
S sc=\$LISTFIND(X,"MUNZ")         // I know this will not work
S sc=\$LISTFIND(\$zcvt(X),"MUNZ")  // I know this will not work and might even cause an error
Q sc

132

ClassMethod Calendar(As %Integer) As %String
{
\$p("Metal7Water7Wood7Fire7Earth",7,y#10\2+1)_" "_\$p("Monkey7Rooster7Dog7Pig7Rat7Ox7Tiger7Rabbit7Dragon7Snake7Horse7Goat",7,y#12+1)
}

That article is an interesting read for anyone who has written code that goes directly to the generated INT code. I will need to re-think some of my older code that finds lines of code from \$ZE and then displays and diagnoses the source of errors based on the variable names it finds there. I might also have to start using a mainstream debugger.

Ah yes, \$Change can save a character on \$Replace. And nested \$TR saves on \$zstrip.

f{z=x,x=\$change(\$tr(x,\$tr(x,"()")),"()",9) ret:x=x=""}