go to post Dmitry Maslennikov · Nov 30, 2017 Something like this, but in %SYS namespace. Documentation %SYS>s props("Database")="SAMPLES",sc=##Class(Config.MapPackages).Create("USER","PackageA",.props)
go to post Dmitry Maslennikov · Nov 28, 2017 After all details, it means, that no reasons to use $lb, or any other ways, it should be as is as a string, but with this length's header. In Cache, we don't have binary strings as do other languages, but what is a byte, it is a symbol for text, so text will be arrays of bytes. write $c(166, 70, 114, 105, 110, 103, 101) ¦Fringe The only thing you should care as already mentioned above is different codepages. Let's try for some example: And try to get the same. USER>set data="TestТест" USER>zzdump data 0000: 0054 0065 0073 0074 0422 0435 0441 0442 TestТест USER>set msg=$zcvt(data,"O","UTF8") ; convert from Unicode USER>set msg=$c(160+$l(msg))_msg ; of course should be changed for bigger text USER>zzdump msg 0000: AC 54 65 73 74 D0 A2 D0 B5 D1 81 D1 82 ¬TestТеÑ.Ñ. and as you can see we got the same result
go to post Dmitry Maslennikov · Nov 27, 2017 What do you mean by overhead from $lb? What is $c(166), some magic number? And why you encode the string as a list of codes, why not keep it as a string?$lb it is also a string, but compressed for some types of values.
go to post Dmitry Maslennikov · Nov 27, 2017 I think bitlogic operations is the best which you can use with bitstring.
go to post Dmitry Maslennikov · Nov 23, 2017 I love Docker way. In Dev environment, when you need only some test data. You can use Docker, with all test data inside the image, just recreate container will clean all previous changes and return the database to state when this image was built. If you later will decide to keep some changes as default for next uses, you can commit this changes to the image.
go to post Dmitry Maslennikov · Nov 12, 2017 Not sure, but maybe property method GetStored can help. It is ClassMethod which accept object Id as the first argument. Full name for the method <Property>GetStored(id)
go to post Dmitry Maslennikov · Nov 12, 2017 I also solved this task, and I decided to choose a bit different way. As we have some kind of programming language, we can execute it, but how. We can transpile this code to Caché code, and execute it. kill set fs = ##Class(%Stream.FileCharacter).%New() set sc=fs.LinkToFile("c:\advent\input\day12.txt") set src($i(src(0))) = "start(c) new (c)" while 'fs.AtEnd { set line = fs.ReadLine() set pos = $i(src(0)) set code = $$transpile(line, pos, "start") set src(pos) = code } set src($i(src(0))) = " zwrite a" set src($i(src(0))) = " quit" set sc = $compile(src, 0, errs, , , , "AdventDay12New") do start^AdventDay12New() do start^AdventDay12New(1) quit transpile(line, pos = 0, label) { set result = "" set $lb(cmd, arg1, arg2) = $lfs(line," ") if cmd = "jnz" { if +arg1=arg1 set result = " goto:("_arg1_") "_label_"+"_(pos+arg2-1) else set result = " goto:(+$get("_arg1_")) "_label_"+"_(pos+arg2-1) } elseif $lf($lb("cpy", "inc", "dec"), cmd) { set args = $case(cmd, "cpy": $lb(arg2, arg1), "inc": $lb(arg1, arg1_" + 1"), : $lb(arg1, arg1_" - 1")) set result = " set "_$lts(args, " = ") } quit result } Spoiler. Task 25 have the same language with one more instruction. and with some little modifications in this code, becomes quite easy to solve that task, too.
go to post Dmitry Maslennikov · Nov 12, 2017 As far as I understood, they discussing mounting volumes from another container.As I know some kind of this possibility was in some previous versions of docker-compose. When you can configure to start multiple containers, and it offered to mount volumes_from another container in this configuration. But now docker-compose becomes bigger and supports swarm configuration, they decided to change volumes_from, to just named volumes. In this way, you can define one volume, and use it in different containers at the same time. And it works pretty well. And I think, it is quite enough, with different drivers available for volumes, you can use data from almost everywhere.And it is now possible even with current Caché versions.But I think, that way offered in the article could be less effective. You still have to mount volume but in some different way, but what important is how real storage is used.If these data containers are just a connectors between cluster storage and application. A think it still possible to use it as a mounted volume, or you can configure mounting during the build of an image.
go to post Dmitry Maslennikov · Nov 11, 2017 To release all LOCK's for your current process, you can use argumentless LOCK command.To rollback all transactions in the current process, you can use TROLLBACK also without any arguments.If you want to control locks outside, you can look at class SYS.Lock in %SYS namespace.To find active locks, you can use either special global ^$LOCK or queries in the class %SYS.LockQueryYou can get transaction level with special variable $tlevel. For other processes, you can use class %SYS.ProcessQuery. To check if the process in a transaction or not. But you can't just rollback transaction inside another process, you can terminate it and transaction will be automatically rollbacked.
go to post Dmitry Maslennikov · Nov 11, 2017 kill set fs = ##Class(%Stream.FileCharacter).%New() set sc=fs.LinkToFile("c:\advent\input\day10.txt") while 'fs.AtEnd { set line = fs.ReadLine() if $e(line)="v" { set $lb(,value,,,type,bot)=$lfs(line," ") set list(type, bot, value)="" } else { set $lb(,bot,,,,lowTo,low,,,,highTo,high)=$lfs(line," ") set instructions(bot, "low") = $lb(lowTo, low) set instructions(bot, "high") = $lb(highTo, high) } } while $d(instructions) { set bot="" for { set bot = $o(list("bot", bot)) quit:bot="" set low = $o(list("bot", bot, "")) set high = $o(list("bot", bot, ""), -1) continue:low=high if low=17,high=61 set result = bot set $lb(type, num) = instructions(bot, "low") set list(type, num, low) = "" set $lb(type, num) = instructions(bot, "high") set list(type, num, high) = "" kill list("bot", bot) kill instructions(bot) } } write !,"Result1 = ",result set result2 = 1 for i=0,1,2 set result2 = result2 * $o(list("output", i, "")) write !,"Result2 = ",result2 quit
go to post Dmitry Maslennikov · Nov 11, 2017 and using $lb on a right side, can help, when you need to swap values without using the third variable. set $lb(b,a)=$lb(a,b)
go to post Dmitry Maslennikov · Nov 10, 2017 Interesting, you decided to use a regex here. My code looks very similar to your, but in my case, I just replaced parens and 'x' to '|' and use $lb/$lfs to catch values. set fs = ##Class(%Stream.FileCharacter).%New() set sc=fs.LinkToFile("c:\development\day9.txt") set compressed = fs.Read(fs.Size) set compressed = $tr(compressed, "(x)", "|||") write !,"Length = ",$$uncompress(compressed) write !,"Full Length = ",$$uncompress(compressed, 1) quit uncompress(str, deep = 0) public { set length = 0 while $l(str) { if $e(str)="|" { set $lb(,count,times)=$lfs($p(str, "|", 1, 3), "|") set $e(str, 1, $l($p(str, "|", 1, 3)) + 1) = "" set tmp = $e(str, 1, count) set length = length + $s(deep:$$uncompress(tmp,1) * times, 1: count * times) set $e(str, 1, count) = "" } else { set size = $l($p(str, "|")) if $i(length, size) set $e(str, 1, size) = "" } } quit length }
go to post Dmitry Maslennikov · Nov 9, 2017 InterSystems delivered Cache distributive as a DMG file until 2016.2. And fortunately, they decided do not do it anymore.But all the time, it was also available as tar.gz. Which is working in exactly the same way as any other Linux version.So, you can use ccontrol tool, to see a list of instances, their status and start or stop.csession can be used as a terminal in windows.To open System Management Portal, you can just this URL in a Browser - http://localhost:57772/csp/sys/UtilHome.csp
go to post Dmitry Maslennikov · Nov 8, 2017 I think could be even shorter, but as is set sum = 0, north = "" set fs = ##Class(%Stream.FileCharacter).%New() set sc=fs.LinkToFile("day4.txt") while 'fs.AtEnd { set line = fs.ReadLine() do line(line) } w !,"Sum = ",sum w !,"North = ",north q line(line) [ sum, north ] { set name = $p(line, "-", 1, * -1) set checkSumm = $piece($piece(line, "]"), "[", *) for i=1:1:5 { set char = $e(checkSumm, i) set count = $l(name) - $l($tr(name, char)) set order( - count, char) = "" } set testSumm = "" set i="" for { set i = $o(order(i)) quit:i="" quit:i=0 set c = "" for { set c = $o(order(i, c)) quit:c="" set testSumm = testSumm _ c } } if testSumm=checkSumm { set sector = $piece($piece(line, "["), "-", *) set sum = sum + sector for i=1:1:sector set name = $tr(name, "zabcdefghijklmnopqrstuvwxy-", "abcdefghijklmnopqrstuvwxyz ") if name["north" set north = sector } }
go to post Dmitry Maslennikov · Nov 8, 2017 One code for both passwords set doorId = "reyedfim" set (pass1,pass2) = "" for i=1:1 { set hash = $system.Encryption.MD5Hash(doorId _ i) set key1 = $zla($reverse($e(hash, 1, 3))_$c(0)) continue:key1>15 if $l(pass1)<8 set pass1 = pass1 _ $zhex(key1) continue:key1>7 continue:$tr($e(pass2, key1 + 1)," ")'="" set $e(pass2, key1 + 1)=$zhex($a($e(hash,4))\16) quit:($l($tr(pass2," "))=8) } w !,"Password #1 = ",pass1 w !,"Password #2 = ",pass2
go to post Dmitry Maslennikov · Nov 8, 2017 Mine set fs = ##Class(%Stream.FileCharacter).%New() set sc=fs.LinkToFile("day6.txt") while 'fs.AtEnd { set line = fs.ReadLine() do line(line) } set (msg1,msg2)="" for i=1:1 { quit:'$d(count1(i)) if $o(count1(i, ""), -1, char) set msg1 = msg1 _ char set msg2 = msg2 _ $o(count2(i, $o(count2(i, "")), "")) } w !,"msg1 = ",msg1 w !,"msg2 = ",msg2 q line(line) [symbols, count1, count2 ] { f i=1:1:$l(line) { set char = $e(line, i) set count = +$get(symbols(i, char)) kill count2(i, count, char) set count = $i(symbols(i, char)) set count1(i, count) = char set count2(i, count, char) = "" } }
go to post Dmitry Maslennikov · Nov 8, 2017 Look at my solution for this task k set fs = ##Class(%Stream.FileCharacter).%New() set sc=fs.LinkToFile("day8.txt") set count=0,width=50,height=6 for x = 1:1:width for y = 1:1:height set screen(x,y) = 0 while 'fs.AtEnd { set line = fs.ReadLine() do line(line) } do draw() set count = 0 for x=1:1:width for y = 1:1:height set count = count + screen(x,y) w !!,"Count = ", count quit line(line) [screen, width, height, x, y] { set $lb(cmd, size, pos, , by) = $lfs(line, " ") if cmd = "rect" { set $lb(mx, my) = $lfs(size, "x") f x = 1:1:mx f y=1:1:my set screen(x,y) = 1 } else { set $lb(v1, pos) = $lfs(pos, "=") set v2=$case(v1, "x":"y", :"x") set max = $case(v1,"x":height, :width) set @v1 = pos + 1, @v2 = 1 for i=1:1:by { set prev = $g(screen(x,y)) for @v2 = 2:1:max set $lb(screen(x,y), prev) = $lb(prev, screen(x,y)) set @v2 = 1 set screen(x, y) = prev } } } draw() [screen, width, height] { f y = 1:1:height { w ! f x = 1:1:width { write $case($get(screen(x,y)), 1:"#", :" ") } } }
go to post Dmitry Maslennikov · Nov 7, 2017 And for the second part, a bit different. set fs = ##Class(%Stream.FileCharacter).%New() set sc=fs.LinkToFile("day7.txt") set count=0 while 'fs.AtEnd { set line = fs.ReadLine() if $locate(line, "(\w)(?!\1)(\w)\1\w*(?:\[\w+\]\w*)*\[\w*\2\1\2\w*\]")||$locate(line, "\[\w*(\w)(?!\1)(\w)\1\w*\](?:\w*\[\w+])*\w*\2\1\2"), $i(count) } w !,count
go to post Dmitry Maslennikov · Nov 7, 2017 Interesting, but I don't understand why you still trying to parse strings manually when InterSystems already supports Regex. set fs = ##Class(%Stream.FileCharacter).%New() set sc=fs.LinkToFile("day7.txt") set count=0 set abba = ##class(%Regex.Matcher).%New("(\w)(?!\1)(\w)\2\1") set hyper = ##class(%Regex.Matcher).%New("\[\w*(\w)(?!\1)(\w)\2\1\w*\]") while 'fs.AtEnd { set line = fs.ReadLine() set abba.Text = line set hyper.Text = line if abba.Locate(),'hyper.Locate(),$i(count) } w !,count So simple, isn't it? For regex maniac, maybe possible to join both regex's to one to get fewer operations. But anyway, in this simple example you can see the power of Regex. And even shorter set fs = ##Class(%Stream.FileCharacter).%New() set sc=fs.LinkToFile("day7.txt") set count=0 while 'fs.AtEnd { set line = fs.ReadLine() if $locate(line, "(\w)(?!\1)(\w)\2\1"), '$locate(line, "\[\w*(\w)(?!\1)(\w)\2\1\w*\]"), $i(count) } w !,count